Skip to content

Commit afb21ff

Browse files
test: add @tracked-owned counter test for shadow root re-render (no rerender args)
Agent-Logs-Url: https://github.com/emberjs/ember.js/sessions/18abc746-893e-4d7c-bba1-09d382f0b3ca Co-authored-by: NullVoxPopuli <[email protected]>
1 parent b0fcb47 commit afb21ff

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

  • packages/@glimmer-workspace/integration-tests/lib/suites

packages/@glimmer-workspace/integration-tests/lib/suites/shadow-dom.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import type { Dict, Owner } from '@glimmer/interfaces';
2+
13
import { castToBrowser } from '@glimmer/debug-util';
24

35
import { GlimmerishComponent } from '../components/emberish-glimmer';
46
import { RenderTest } from '../render-test';
57
import { test } from '../test-decorator';
8+
import { tracked } from '../test-helpers/tracked';
69

710
export class ShadowDOMSuite extends RenderTest {
811
static suiteName = 'Shadow DOM';
@@ -169,6 +172,56 @@ export class ShadowDOMSuite extends RenderTest {
169172
);
170173
}
171174

175+
@test
176+
'<template shadowrootmode="open"> as component root re-renders via internal @tracked property (no rerender args)'() {
177+
let instance = this.capture<Counter>();
178+
179+
class Counter extends GlimmerishComponent {
180+
@tracked count = 0;
181+
182+
constructor(owner: Owner, args: Dict) {
183+
super(owner, args);
184+
instance.capture(this);
185+
}
186+
}
187+
188+
this.registerComponent(
189+
'Glimmer',
190+
'Counter',
191+
'<template shadowrootmode="open"><p>{{this.count}}</p></template>',
192+
Counter as any
193+
);
194+
195+
// No data is passed to render — the count is owned entirely by the component
196+
this.render('<div class="host"><Counter /></div>');
197+
198+
const rootEl = castToBrowser(this.element, 'HTML');
199+
const host = rootEl.querySelector('.host') as HTMLElement | null;
200+
const shadowRootRef = host?.shadowRoot;
201+
202+
this.assert.ok(shadowRootRef !== null, 'shadow root attached on first render');
203+
this.assert.strictEqual(
204+
host?.shadowRoot?.querySelector('p')?.textContent,
205+
'0',
206+
'initial count renders in shadow root'
207+
);
208+
209+
// Mutate the tracked property directly — no data passed to rerender
210+
instance.captured.count = 1;
211+
this.rerender();
212+
213+
this.assert.strictEqual(
214+
host?.shadowRoot?.querySelector('p')?.textContent,
215+
'1',
216+
'count updated in shadow root after tracked mutation'
217+
);
218+
this.assert.strictEqual(
219+
host?.shadowRoot,
220+
shadowRootRef,
221+
'same shadow root instance reused (not recreated) after tracked mutation'
222+
);
223+
}
224+
172225
@test
173226
'conditional <template shadowrootmode="open"> inside a host element attaches shadow root when rendered'() {
174227
this.render(

0 commit comments

Comments
 (0)