From d95269a016b35635e624b3ed9bab80c92e69b880 Mon Sep 17 00:00:00 2001 From: Lucas Gomes Date: Tue, 1 Aug 2023 15:55:46 -0400 Subject: [PATCH 1/5] fix: dispatch form submit using a handleClick --- .../core/src/components/button/button.tsx | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/core/src/components/button/button.tsx b/packages/core/src/components/button/button.tsx index 39a510dd9..43697b3ea 100644 --- a/packages/core/src/components/button/button.tsx +++ b/packages/core/src/components/button/button.tsx @@ -1,5 +1,13 @@ import { Mode } from '@ionic/core' -import { Component, Host, Prop, h } from '@stencil/core' +import { + Component, + Element, + Event, + EventEmitter, + Host, + Prop, + h, +} from '@stencil/core' @Component({ tag: 'atom-button', @@ -21,6 +29,29 @@ export class AtomButton { @Prop() target?: string @Prop() type: 'submit' | 'reset' | 'button' = 'button' + @Event() click: EventEmitter + + @Element() element: HTMLElement + + formFunctions = { + reset: 'reset', + submit: 'requestSubmit', + } + + private handleClick = (event) => { + event.preventDefault() + + if (this.loading || this.disabled) return + if (this.type === 'button') { + return this.click.emit(event) + } else { + const form = this.element.closest('form') + if (form) { + return form[this.formFunctions[this.type]]() + } + } + } + render() { return ( {this.loading && ( From a5b60f572ce1419e1c419a18e9c5d8b1c85eb5be Mon Sep 17 00:00:00 2001 From: Alan Schio Date: Thu, 3 Aug 2023 08:02:29 -0400 Subject: [PATCH 2/5] feat(button): add bind to handle and prepare tests --- .../core/src/components/button/button.spec.ts | 45 +++++++++++++++++++ .../core/src/components/button/button.tsx | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/core/src/components/button/button.spec.ts b/packages/core/src/components/button/button.spec.ts index c1f3d7019..13f073d0f 100644 --- a/packages/core/src/components/button/button.spec.ts +++ b/packages/core/src/components/button/button.spec.ts @@ -131,4 +131,49 @@ describe('AtomButton', () => { expect(spy).toHaveBeenCalled() }) + + it('should submit button call parent form requestSubmit', async () => { + // TODO - form from test are being show as MockHTMLElement instead of HTMLFormElement + const page = await newSpecPage({ + components: [AtomButton], + html: '
Click
', + }) + + await page.waitForChanges() + const formEl = (page.body.querySelector('form') as HTMLFormElement) || { + requestSubmit: jest.fn, + addEventListener: jest.fn, + } + const eventListenerSpy = jest.fn() + jest.spyOn(formEl, 'requestSubmit') + + formEl.addEventListener('submit', eventListenerSpy) + + const buttonEl = page.root?.shadowRoot?.querySelector('ion-button') + + buttonEl?.click() + + expect(eventListenerSpy).toHaveBeenCalled() + expect(formEl.requestSubmit).toHaveBeenCalled() + }) + + it('should submit button call parent form reset', async () => { + const page = await newSpecPage({ + components: [AtomButton], + html: '
Click
', + }) + + await page.waitForChanges() + const formEl = (page.body.querySelector('form') as HTMLFormElement) || { + reset: jest.fn, + addEventListener: jest.fn, + } + jest.spyOn(formEl, 'reset') + + const buttonEl = page.root?.shadowRoot?.querySelector('ion-button') + + buttonEl?.click() + + expect(formEl.reset).toHaveBeenCalled() + }) }) diff --git a/packages/core/src/components/button/button.tsx b/packages/core/src/components/button/button.tsx index 43697b3ea..425d31ac1 100644 --- a/packages/core/src/components/button/button.tsx +++ b/packages/core/src/components/button/button.tsx @@ -78,7 +78,7 @@ export class AtomButton { rel={this.rel} target={this.target} download={this.download} - onClick={this.handleClick} + onClick={this.handleClick.bind(this)} > {this.loading && ( From 33b0c1b12cffdcc20885bd091c170be3128d9f34 Mon Sep 17 00:00:00 2001 From: Alan Schio Date: Thu, 3 Aug 2023 08:15:38 -0400 Subject: [PATCH 3/5] test(button): add funcions to mock elements --- .../core/src/components/button/button.spec.ts | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/packages/core/src/components/button/button.spec.ts b/packages/core/src/components/button/button.spec.ts index 13f073d0f..fc9edbfb2 100644 --- a/packages/core/src/components/button/button.spec.ts +++ b/packages/core/src/components/button/button.spec.ts @@ -140,20 +140,13 @@ describe('AtomButton', () => { }) await page.waitForChanges() - const formEl = (page.body.querySelector('form') as HTMLFormElement) || { - requestSubmit: jest.fn, - addEventListener: jest.fn, - } - const eventListenerSpy = jest.fn() - jest.spyOn(formEl, 'requestSubmit') - - formEl.addEventListener('submit', eventListenerSpy) - + const formEl = page.body.querySelector('form') as HTMLFormElement + formEl.requestSubmit = jest.fn const buttonEl = page.root?.shadowRoot?.querySelector('ion-button') + jest.spyOn(formEl, 'requestSubmit') buttonEl?.click() - expect(eventListenerSpy).toHaveBeenCalled() expect(formEl.requestSubmit).toHaveBeenCalled() }) @@ -164,14 +157,10 @@ describe('AtomButton', () => { }) await page.waitForChanges() - const formEl = (page.body.querySelector('form') as HTMLFormElement) || { - reset: jest.fn, - addEventListener: jest.fn, - } - jest.spyOn(formEl, 'reset') - + const formEl = page.body.querySelector('form') as HTMLFormElement + formEl.reset = jest.fn() const buttonEl = page.root?.shadowRoot?.querySelector('ion-button') - + jest.spyOn(formEl, 'reset') buttonEl?.click() expect(formEl.reset).toHaveBeenCalled() From c0a965c07c7ed3517d7762b3f50fb0ba6f309d14 Mon Sep 17 00:00:00 2001 From: Lucas Gomes Date: Fri, 4 Aug 2023 11:44:51 -0400 Subject: [PATCH 4/5] test(button): test if button dont call form functions if is disabled --- .../core/src/components/button/button.spec.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/core/src/components/button/button.spec.ts b/packages/core/src/components/button/button.spec.ts index fc9edbfb2..8a2137865 100644 --- a/packages/core/src/components/button/button.spec.ts +++ b/packages/core/src/components/button/button.spec.ts @@ -165,4 +165,20 @@ describe('AtomButton', () => { expect(formEl.reset).toHaveBeenCalled() }) + + it('should not call form reset if button is disabled', async () => { + const page = await newSpecPage({ + components: [AtomButton], + html: '
Click
', + }) + + await page.waitForChanges() + const formEl = page.body.querySelector('form') as HTMLFormElement + formEl.reset = jest.fn() + const buttonEl = page.root?.shadowRoot?.querySelector('ion-button') + jest.spyOn(formEl, 'reset') + buttonEl?.click() + + expect(formEl.reset).not.toHaveBeenCalled() + }) }) From 182cf2d61eefc7d52a12c1c35d3d402e8b0399eb Mon Sep 17 00:00:00 2001 From: Lucas Gomes Date: Fri, 4 Aug 2023 11:58:57 -0400 Subject: [PATCH 5/5] refactor(button): remove unnecessary TODO on button tests --- packages/core/src/components/button/button.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/components/button/button.spec.ts b/packages/core/src/components/button/button.spec.ts index 8a2137865..a21fe43dc 100644 --- a/packages/core/src/components/button/button.spec.ts +++ b/packages/core/src/components/button/button.spec.ts @@ -133,7 +133,6 @@ describe('AtomButton', () => { }) it('should submit button call parent form requestSubmit', async () => { - // TODO - form from test are being show as MockHTMLElement instead of HTMLFormElement const page = await newSpecPage({ components: [AtomButton], html: '
Click
',