Skip to content

Commit 61ac933

Browse files
carlosescriclaude
andcommitted
test: add case 6 — FACE with slot + delegatesFocus
Covers the pattern used by components like ui-select: shadow DOM with delegatesFocus, a focusable input inside the shadow root, and slotted light DOM children that must be patched while the host has focus. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 04a8e2a commit 61ac933

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

test/e2e/support/issues/issue_4323.ex

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ defmodule Phoenix.LiveViewTest.E2E.Issue4323Live do
4242
// Case 5: Non-FACE custom element
4343
class NonFaceEl extends HTMLElement {}
4444
customElements.define("non-face-el", NonFaceEl);
45+
46+
// Case 6: FACE with shadow DOM + slot + delegatesFocus
47+
class FaceSlottedDelegates extends HTMLElement {
48+
static formAssociated = true;
49+
constructor() {
50+
super();
51+
this.attachInternals();
52+
this.attachShadow({ mode: "open", delegatesFocus: true });
53+
this.shadowRoot.innerHTML = '<input type="text" /><div><slot></slot></div>';
54+
}
55+
}
56+
customElements.define("face-slotted-delegates", FaceSlottedDelegates);
4557
</script>
4658
"""
4759
end)
@@ -87,6 +99,12 @@ defmodule Phoenix.LiveViewTest.E2E.Issue4323Live do
8799
<span id="case5-child">count:{@counter}</span>
88100
</non-face-el>
89101
102+
<%!-- Case 6: FACE with slot + delegatesFocus --%>
103+
<face-slotted-delegates id="case6">
104+
<input id="case6-input" type="text" name="case6_input" />
105+
<span id="case6-child">count:{@counter}</span>
106+
</face-slotted-delegates>
107+
90108
<button id="inc-btn" type="button" phx-click="inc">Increment</button>
91109
</form>
92110
"""

test/e2e/tests/issues/4323.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,23 @@ test.describe("FACE children patching", () => {
8484
await expect(page.locator("#case4-child")).toHaveText("count:1");
8585
});
8686

87+
test("FACE with slot + delegatesFocus: slotted children are patched", async ({
88+
page,
89+
}) => {
90+
await expect(page.locator("#case6-child")).toHaveText("count:0");
91+
92+
// Click the FACE host; delegatesFocus sends focus to the shadow input,
93+
// but document.activeElement returns the shadow host
94+
await page.locator("#case6").click();
95+
const activeId = await page.evaluate(() => document.activeElement?.id);
96+
expect(activeId).toBe("case6");
97+
98+
await incrementCounter(page);
99+
100+
// Slotted light DOM children should be patched (FACE branch descends)
101+
await expect(page.locator("#case6-child")).toHaveText("count:1");
102+
});
103+
87104
test("non-FACE custom element: children are patched normally", async ({
88105
page,
89106
}) => {

0 commit comments

Comments
 (0)