From a7d38735a8572303fa2ea7e154e9a9dc3bf7eecb Mon Sep 17 00:00:00 2001 From: John Jenkins Date: Tue, 21 Jan 2025 18:30:09 +0000 Subject: [PATCH] fix(test): stop re-running prototype augment in spec tests. (#6105) Co-authored-by: John Jenkins --- src/runtime/proxy-component.ts | 12 +++++++-- src/runtime/test/prop-warnings.spec.tsx | 36 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/runtime/proxy-component.ts b/src/runtime/proxy-component.ts index 9f7d2115fca..2b4c6e06169 100644 --- a/src/runtime/proxy-component.ts +++ b/src/runtime/proxy-component.ts @@ -29,6 +29,14 @@ export const proxyComponent = ( ): d.ComponentConstructor => { const prototype = (Cstr as any).prototype; + if (BUILD.isTesting) { + if (prototype.done) { + // @ts-expect-error - we don't want to re-augment the prototype. This happens during spec tests. + return; + } + prototype.done = true; + } + /** * proxy form associated custom element lifecycle callbacks * @ref https://web.dev/articles/more-capable-form-controls#lifecycle_callbacks @@ -113,9 +121,9 @@ export const proxyComponent = ( // the element is not constructing (ref && ref.$flags$ & HOST_FLAGS.isConstructingInstance) === 0 && // the member is a prop - (cmpMeta.$members$[memberName][0] & MEMBER_FLAGS.Prop) !== 0 && + (memberFlags & MEMBER_FLAGS.Prop) !== 0 && // the member is not mutable - (cmpMeta.$members$[memberName][0] & MEMBER_FLAGS.Mutable) === 0 + (memberFlags & MEMBER_FLAGS.Mutable) === 0 ) { consoleDevWarn( `@Prop() "${memberName}" on <${cmpMeta.$tagName$}> is immutable but was modified from within the component.\nMore information: https://stenciljs.com/docs/properties#prop-mutability`, diff --git a/src/runtime/test/prop-warnings.spec.tsx b/src/runtime/test/prop-warnings.spec.tsx index cb60fe9e213..2f3c5bab2ca 100644 --- a/src/runtime/test/prop-warnings.spec.tsx +++ b/src/runtime/test/prop-warnings.spec.tsx @@ -1,6 +1,18 @@ import { Component, h, Method, Prop } from '@stencil/core'; import { newSpecPage } from '@stencil/core/testing'; +@Component({ + tag: 'shared-cmp', + shadow: true, +}) +class SharedCmp { + @Prop() a = 'Boom!'; + + render() { + return `${this.a}`; + } +} + describe('prop', () => { const spy = jest.spyOn(console, 'warn').mockImplementation(); @@ -89,4 +101,28 @@ describe('prop', () => { expect(root).toEqualHtml('2'); expect(spy).not.toHaveBeenCalled(); }); + + it('should not show warning when component is used across multiple tests - first time', async () => { + const { root, waitForChanges } = await newSpecPage({ + components: [SharedCmp], + html: ``, + }); + + root.a = 'Bam!'; + await waitForChanges(); + + expect(spy).not.toHaveBeenCalled(); + }); + + it('should not show warning when component is used across multiple tests - second time', async () => { + const { root, waitForChanges } = await newSpecPage({ + components: [SharedCmp], + html: ``, + }); + + root.a = 'Boom!'; + await waitForChanges(); + + expect(spy).not.toHaveBeenCalled(); + }); });