@microsoft/fast-html 1.0.0-alpha.31 → 1.0.0-alpha.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/dts/components/observer-map.d.ts +1 -1
  2. package/dist/dts/components/schema.d.ts +1 -1
  3. package/dist/dts/components/utilities.d.ts +20 -18
  4. package/dist/esm/components/element.js +0 -5
  5. package/dist/esm/components/utilities.js +116 -71
  6. package/package.json +17 -32
  7. package/dist/dts/fixtures/attribute/attribute.spec.d.ts +0 -1
  8. package/dist/dts/fixtures/attribute/main.d.ts +0 -1
  9. package/dist/dts/fixtures/binding/binding.spec.d.ts +0 -1
  10. package/dist/dts/fixtures/binding/main.d.ts +0 -1
  11. package/dist/dts/fixtures/children/children.spec.d.ts +0 -1
  12. package/dist/dts/fixtures/children/main.d.ts +0 -1
  13. package/dist/dts/fixtures/dot-syntax/dot-syntax.spec.d.ts +0 -1
  14. package/dist/dts/fixtures/dot-syntax/main.d.ts +0 -1
  15. package/dist/dts/fixtures/event/event.spec.d.ts +0 -1
  16. package/dist/dts/fixtures/event/main.d.ts +0 -1
  17. package/dist/dts/fixtures/lifecycle-callbacks/lifecycle-callbacks.spec.d.ts +0 -1
  18. package/dist/dts/fixtures/lifecycle-callbacks/main.d.ts +0 -5
  19. package/dist/dts/fixtures/observer-map/main.d.ts +0 -1
  20. package/dist/dts/fixtures/observer-map/observer-map.spec.d.ts +0 -1
  21. package/dist/dts/fixtures/ref/main.d.ts +0 -1
  22. package/dist/dts/fixtures/ref/ref.spec.d.ts +0 -1
  23. package/dist/dts/fixtures/repeat/main.d.ts +0 -1
  24. package/dist/dts/fixtures/repeat/repeat.spec.d.ts +0 -1
  25. package/dist/dts/fixtures/slotted/main.d.ts +0 -1
  26. package/dist/dts/fixtures/slotted/slotted.spec.d.ts +0 -1
  27. package/dist/dts/fixtures/when/main.d.ts +0 -1
  28. package/dist/dts/fixtures/when/when.spec.d.ts +0 -1
  29. package/dist/esm/fixtures/attribute/attribute.spec.js +0 -23
  30. package/dist/esm/fixtures/attribute/main.js +0 -20
  31. package/dist/esm/fixtures/binding/binding.spec.js +0 -23
  32. package/dist/esm/fixtures/binding/main.js +0 -30
  33. package/dist/esm/fixtures/children/children.spec.js +0 -37
  34. package/dist/esm/fixtures/children/main.js +0 -25
  35. package/dist/esm/fixtures/dot-syntax/dot-syntax.spec.js +0 -116
  36. package/dist/esm/fixtures/dot-syntax/main.js +0 -42
  37. package/dist/esm/fixtures/event/event.spec.js +0 -35
  38. package/dist/esm/fixtures/event/main.js +0 -32
  39. package/dist/esm/fixtures/lifecycle-callbacks/lifecycle-callbacks.spec.js +0 -166
  40. package/dist/esm/fixtures/lifecycle-callbacks/main.js +0 -126
  41. package/dist/esm/fixtures/observer-map/main.js +0 -375
  42. package/dist/esm/fixtures/observer-map/observer-map.spec.js +0 -251
  43. package/dist/esm/fixtures/ref/main.js +0 -15
  44. package/dist/esm/fixtures/ref/ref.spec.js +0 -9
  45. package/dist/esm/fixtures/repeat/main.js +0 -44
  46. package/dist/esm/fixtures/repeat/repeat.spec.js +0 -36
  47. package/dist/esm/fixtures/slotted/main.js +0 -33
  48. package/dist/esm/fixtures/slotted/slotted.spec.js +0 -24
  49. package/dist/esm/fixtures/when/main.js +0 -156
  50. package/dist/esm/fixtures/when/when.spec.js +0 -82
  51. package/dist/esm/tsconfig.tsbuildinfo +0 -1
@@ -1,30 +0,0 @@
1
- import { __decorate, __metadata } from "tslib";
2
- import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
3
- import { attr, FASTElement } from "@microsoft/fast-element";
4
- class TestElement extends FASTElement {
5
- constructor() {
6
- super(...arguments);
7
- this.text = "Hello";
8
- }
9
- }
10
- __decorate([
11
- attr,
12
- __metadata("design:type", String)
13
- ], TestElement.prototype, "text", void 0);
14
- RenderableFASTElement(TestElement).defineAsync({
15
- name: "test-element",
16
- templateOptions: "defer-and-hydrate",
17
- });
18
- class TestElementUnescaped extends FASTElement {
19
- constructor() {
20
- super(...arguments);
21
- this.html = `<p>Hello world</p>`;
22
- }
23
- }
24
- RenderableFASTElement(TestElementUnescaped).defineAsync({
25
- name: "test-element-unescaped",
26
- templateOptions: "defer-and-hydrate",
27
- });
28
- TemplateElement.define({
29
- name: "f-template",
30
- });
@@ -1,37 +0,0 @@
1
- import { __awaiter } from "tslib";
2
- import { expect, test } from "@playwright/test";
3
- test.describe("f-template", () => __awaiter(void 0, void 0, void 0, function* () {
4
- test("create a children directive", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
5
- yield page.goto("/children");
6
- const listItemCount1 = yield page.evaluate(() => {
7
- var _a;
8
- const customElement = document.getElementsByTagName("test-element");
9
- const listItems = (_a = customElement.item(0)) === null || _a === void 0 ? void 0 : _a.listItems.filter((listItem) => {
10
- return listItem instanceof HTMLLIElement;
11
- });
12
- return listItems === null || listItems === void 0 ? void 0 : listItems.length;
13
- });
14
- expect(listItemCount1).toEqual(2);
15
- yield page.evaluate(() => {
16
- const customElement = document.getElementsByTagName("test-element");
17
- customElement.item(0).list = [
18
- "A",
19
- "B",
20
- "C"
21
- ];
22
- });
23
- const timeout = new Promise(function (resolve) {
24
- setTimeout(resolve, 100);
25
- });
26
- yield timeout;
27
- const listItemCount2 = yield page.evaluate(() => {
28
- var _a;
29
- const customElement = document.getElementsByTagName("test-element");
30
- const listItems = (_a = customElement.item(0)) === null || _a === void 0 ? void 0 : _a.listItems.filter((listItem) => {
31
- return listItem instanceof HTMLLIElement;
32
- });
33
- return listItems === null || listItems === void 0 ? void 0 : listItems.length;
34
- });
35
- expect(listItemCount2).toEqual(3);
36
- }));
37
- }));
@@ -1,25 +0,0 @@
1
- import { __decorate, __metadata } from "tslib";
2
- import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
3
- import { FASTElement, observable } from "@microsoft/fast-element";
4
- class TestElement extends FASTElement {
5
- constructor() {
6
- super(...arguments);
7
- this.listItems = [];
8
- this.list = ["Foo", "Bar"];
9
- }
10
- }
11
- __decorate([
12
- observable,
13
- __metadata("design:type", Array)
14
- ], TestElement.prototype, "listItems", void 0);
15
- __decorate([
16
- observable,
17
- __metadata("design:type", Array)
18
- ], TestElement.prototype, "list", void 0);
19
- RenderableFASTElement(TestElement).defineAsync({
20
- name: "test-element",
21
- templateOptions: "defer-and-hydrate",
22
- });
23
- TemplateElement.define({
24
- name: "f-template",
25
- });
@@ -1,116 +0,0 @@
1
- import { __awaiter } from "tslib";
2
- import { expect, test } from "@playwright/test";
3
- test.describe("f-template dot-syntax bindings", () => __awaiter(void 0, void 0, void 0, function* () {
4
- test("create a object property reference using dot syntax in a binding", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
5
- yield page.goto("/dot-syntax");
6
- const customElement = yield page.locator("test-element");
7
- yield expect(customElement.locator("span").nth(0)).toHaveText("bar");
8
- }));
9
- test("should display initial property values correctly", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
10
- yield page.goto("/dot-syntax");
11
- const customElement = yield page.locator("test-element");
12
- // Check initial values
13
- yield expect(customElement.locator("span").nth(0)).toHaveText("bar");
14
- yield expect(customElement.locator("span").nth(1)).toHaveText("");
15
- yield expect(customElement.locator("span").nth(2)).toHaveText("FOO");
16
- }));
17
- test("should update object.b when 'Set b' button is clicked", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
18
- yield page.goto("/dot-syntax");
19
- const customElement = yield page.locator("test-element");
20
- const setBButton = customElement.locator("button").nth(0);
21
- const bSpan = customElement.locator("span").nth(0);
22
- // Verify initial state
23
- yield expect(bSpan).toHaveText("bar");
24
- // Click the "Set b" button
25
- yield setBButton.click();
26
- // Verify the value updated
27
- yield expect(bSpan).toHaveText("Hello");
28
- }));
29
- test("should update object.a.b1 when 'Set a.b1' button is clicked", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
30
- yield page.goto("/dot-syntax");
31
- const customElement = yield page.locator("test-element");
32
- const setAB1Button = customElement.locator("button").nth(1);
33
- const ab1Span = customElement.locator("span").nth(1);
34
- // Verify initial state (should be empty/undefined)
35
- yield expect(ab1Span).toHaveText("");
36
- // Click the "Set a.b1" button
37
- yield setAB1Button.click();
38
- // Verify the value updated
39
- yield expect(ab1Span).toHaveText("World");
40
- }));
41
- test("should update object.a.b2.c when 'Set a.b2.c' button is clicked", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
42
- yield page.goto("/dot-syntax");
43
- const customElement = yield page.locator("test-element");
44
- const setAB2CButton = customElement.locator("button").nth(2);
45
- const ab2cSpan = customElement.locator("span").nth(2);
46
- // Click the "Set a.b2.c" button
47
- yield setAB2CButton.click();
48
- // Verify the value updated
49
- yield expect(ab2cSpan).toHaveText("Pluto");
50
- }));
51
- test("should handle multiple property updates independently", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
52
- yield page.goto("/dot-syntax");
53
- const customElement = yield page.locator("test-element");
54
- const setBButton = customElement.locator("button").nth(0);
55
- const setAB1Button = customElement.locator("button").nth(1);
56
- const setAB2CButton = customElement.locator("button").nth(2);
57
- const bSpan = customElement.locator("span").nth(0);
58
- const ab1Span = customElement.locator("span").nth(1);
59
- const ab2cSpan = customElement.locator("span").nth(2);
60
- // Update multiple properties
61
- yield setBButton.click();
62
- yield setAB1Button.click();
63
- yield setAB2CButton.click();
64
- // Verify all values are updated correctly
65
- yield expect(bSpan).toHaveText("Hello");
66
- yield expect(ab1Span).toHaveText("World");
67
- yield expect(ab2cSpan).toHaveText("Pluto");
68
- }));
69
- test("should maintain property values after multiple clicks", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
70
- yield page.goto("/dot-syntax");
71
- const customElement = yield page.locator("test-element");
72
- const setBButton = customElement.locator("button").nth(0);
73
- const bSpan = customElement.locator("span").nth(0);
74
- // Click multiple times to ensure consistency
75
- yield setBButton.click();
76
- yield expect(bSpan).toHaveText("Hello");
77
- yield setBButton.click();
78
- yield expect(bSpan).toHaveText("Hello"); // Should remain the same
79
- yield setBButton.click();
80
- yield expect(bSpan).toHaveText("Hello"); // Should still be the same
81
- }));
82
- test("should update nested properties correctly", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
83
- yield page.goto("/dot-syntax");
84
- const customElement = yield page.locator("test-element");
85
- const setAB1Button = customElement.locator("button").nth(1);
86
- const setAB2CButton = customElement.locator("button").nth(2);
87
- const ab1Span = customElement.locator("span").nth(1);
88
- const ab2cSpan = customElement.locator("span").nth(2);
89
- // Test nested property updates
90
- yield setAB1Button.click();
91
- yield expect(ab1Span).toHaveText("World");
92
- yield setAB2CButton.click();
93
- yield expect(ab2cSpan).toHaveText("Pluto");
94
- // Verify both nested properties coexist
95
- yield expect(ab1Span).toHaveText("World");
96
- yield expect(ab2cSpan).toHaveText("Pluto");
97
- }));
98
- test("should have correct button labels", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
99
- yield page.goto("/dot-syntax");
100
- const customElement = yield page.locator("test-element");
101
- // Verify button labels
102
- yield expect(customElement.locator("button").nth(0)).toHaveText("Set b");
103
- yield expect(customElement.locator("button").nth(1)).toHaveText("Set a.b1");
104
- yield expect(customElement.locator("button").nth(2)).toHaveText("Set a.b2.c");
105
- }));
106
- test("should reflect property changes in DOM immediately", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
107
- yield page.goto("/dot-syntax");
108
- const customElement = yield page.locator("test-element");
109
- const setBButton = customElement.locator("button").nth(0);
110
- const bSpan = customElement.locator("span").nth(0);
111
- // Verify immediate DOM update without additional waiting
112
- yield setBButton.click();
113
- // Should update immediately due to reactive system
114
- yield expect(bSpan).toHaveText("Hello", { timeout: 1000 });
115
- }));
116
- }));
@@ -1,42 +0,0 @@
1
- import { FASTElement } from "@microsoft/fast-element";
2
- import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
3
- class TestElement extends FASTElement {
4
- constructor() {
5
- super(...arguments);
6
- this.object = {
7
- b: "bar",
8
- a: {
9
- b2: {
10
- c: "FOO",
11
- },
12
- },
13
- };
14
- this.handleBClick = () => {
15
- this.object.b = "Hello";
16
- };
17
- this.handleAB1Click = () => {
18
- if (this.object.a) {
19
- this.object.a.b1 = "World";
20
- }
21
- else {
22
- this.object.a = {
23
- b1: "World",
24
- };
25
- }
26
- };
27
- this.handleAB2CClick = () => {
28
- this.object.a.b2.c = "Pluto";
29
- };
30
- }
31
- }
32
- RenderableFASTElement(TestElement).defineAsync({
33
- name: "test-element",
34
- templateOptions: "defer-and-hydrate",
35
- });
36
- TemplateElement.options({
37
- "test-element": {
38
- observerMap: "all",
39
- },
40
- }).define({
41
- name: "f-template",
42
- });
@@ -1,35 +0,0 @@
1
- import { __awaiter } from "tslib";
2
- import { expect, test } from "@playwright/test";
3
- test.describe("f-template", () => __awaiter(void 0, void 0, void 0, function* () {
4
- test("create an event attribute without arguments", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
5
- yield page.goto("/event");
6
- const customElement = yield page.locator("test-element");
7
- let message;
8
- yield page.on("console", msg => message = msg.text());
9
- yield customElement.locator("button").nth(0).click();
10
- expect(message).toEqual("no args");
11
- }));
12
- test("create an event attribute with an event argument", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
13
- yield page.goto("/event");
14
- const customElement = yield page.locator("test-element");
15
- let message;
16
- yield page.on("console", msg => message = msg.text());
17
- yield customElement.locator("button").nth(1).click();
18
- expect(message).toEqual("click");
19
- }));
20
- test("create an event attribute with an attribute argument", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
21
- yield page.goto("/event");
22
- const customElement = yield page.locator("test-element");
23
- let message;
24
- yield page.on("console", msg => message = msg.text());
25
- yield customElement.locator("button").nth(2).click();
26
- expect(message).toEqual("bar");
27
- }));
28
- test("should properly bind events with `this`", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
29
- yield page.goto("/event");
30
- const customElement = yield page.locator("test-element");
31
- yield expect(customElement).toHaveJSProperty("foo", "bar");
32
- yield customElement.locator("button").nth(3).click();
33
- yield expect(customElement).toHaveJSProperty("foo", "modified-by-click");
34
- }));
35
- }));
@@ -1,32 +0,0 @@
1
- import { __decorate, __metadata } from "tslib";
2
- import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
3
- import { attr, FASTElement } from "@microsoft/fast-element";
4
- class TestElement extends FASTElement {
5
- constructor() {
6
- super(...arguments);
7
- this.foo = "";
8
- this.handleNoArgsClick = () => {
9
- console.log("no args");
10
- };
11
- this.handleEventArgClick = (e) => {
12
- console.log(e.type);
13
- };
14
- this.handleAttributeArgClick = (foo) => {
15
- console.log(foo);
16
- };
17
- this.handleModifyAttributeClick = () => {
18
- this.foo = "modified-by-click";
19
- };
20
- }
21
- }
22
- __decorate([
23
- attr,
24
- __metadata("design:type", String)
25
- ], TestElement.prototype, "foo", void 0);
26
- RenderableFASTElement(TestElement).defineAsync({
27
- name: "test-element",
28
- templateOptions: "defer-and-hydrate",
29
- });
30
- TemplateElement.define({
31
- name: "f-template",
32
- });
@@ -1,166 +0,0 @@
1
- import { __awaiter } from "tslib";
2
- import { expect, test } from "@playwright/test";
3
- test.describe("Lifecycle Callbacks", () => __awaiter(void 0, void 0, void 0, function* () {
4
- test("should invoke all lifecycle callbacks in correct order for simple element", ({ page, }) => __awaiter(void 0, void 0, void 0, function* () {
5
- yield page.goto("/lifecycle-callbacks");
6
- // Wait for hydration to complete
7
- yield page.waitForFunction(() => window.getHydrationCompleteStatus());
8
- const events = yield page.evaluate(() => window.lifecycleEvents);
9
- // Verify callbacks for simple-element were called
10
- const simpleElementEvents = events.filter((e) => e.name === "simple-element");
11
- expect(simpleElementEvents.length).toBeGreaterThan(0);
12
- // Check that callbacks were called in the correct order
13
- const callbackOrder = simpleElementEvents.map((e) => e.callback);
14
- expect(callbackOrder).toContain("elementDidRegister");
15
- expect(callbackOrder).toContain("templateWillUpdate");
16
- expect(callbackOrder).toContain("templateDidUpdate");
17
- expect(callbackOrder).toContain("elementDidDefine");
18
- expect(callbackOrder).toContain("elementWillHydrate");
19
- expect(callbackOrder).toContain("elementDidHydrate");
20
- // Verify the order is correct
21
- const registerIndex = callbackOrder.indexOf("elementDidRegister");
22
- const willUpdateIndex = callbackOrder.indexOf("templateWillUpdate");
23
- const didUpdateIndex = callbackOrder.indexOf("templateDidUpdate");
24
- const defineIndex = callbackOrder.indexOf("elementDidDefine");
25
- const willHydrateIndex = callbackOrder.indexOf("elementWillHydrate");
26
- const didHydrateIndex = callbackOrder.indexOf("elementDidHydrate");
27
- expect(registerIndex).toBeLessThan(willUpdateIndex);
28
- expect(willUpdateIndex).toBeLessThan(didUpdateIndex);
29
- expect(didUpdateIndex).toBeLessThan(defineIndex);
30
- expect(willHydrateIndex).toBeGreaterThan(-1);
31
- expect(didHydrateIndex).toBeGreaterThan(willHydrateIndex);
32
- }));
33
- test("should invoke callbacks for multiple elements", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
34
- yield page.goto("/lifecycle-callbacks");
35
- yield page.waitForFunction(() => window.getHydrationCompleteStatus());
36
- const events = yield page.evaluate(() => window.lifecycleEvents);
37
- // Check that callbacks were invoked for all elements
38
- const elementNames = new Set(events.map((e) => e.name));
39
- expect(elementNames.has("simple-element")).toBe(true);
40
- expect(elementNames.has("complex-element")).toBe(true);
41
- expect(elementNames.has("nested-element")).toBe(true);
42
- }));
43
- test("should invoke elementWillHydrate before hydration", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
44
- yield page.goto("/lifecycle-callbacks");
45
- yield page.waitForFunction(() => window.getHydrationCompleteStatus());
46
- const events = yield page.evaluate(() => window.lifecycleEvents);
47
- const willHydrateEvents = events.filter((e) => e.callback === "elementWillHydrate");
48
- const didHydrateEvents = events.filter((e) => e.callback === "elementDidHydrate");
49
- // Every elementWillHydrate should be followed by elementDidHydrate for the same element
50
- willHydrateEvents.forEach((willEvent) => {
51
- const correspondingDidEvent = didHydrateEvents.find((e) => e.name === willEvent.name);
52
- expect(correspondingDidEvent).toBeDefined();
53
- });
54
- }));
55
- test("should invoke hydrationComplete callback after all elements hydrate", ({ page, }) => __awaiter(void 0, void 0, void 0, function* () {
56
- yield page.goto("/lifecycle-callbacks");
57
- const hydrationComplete = yield page.waitForFunction(() => window.getHydrationCompleteStatus(), { timeout: 5000 });
58
- expect(hydrationComplete).toBeTruthy();
59
- const events = yield page.evaluate(() => window.lifecycleEvents);
60
- // Verify hydrationComplete callback was invoked
61
- const hydrationCompleteEvents = events.filter((e) => e.callback === "hydrationComplete");
62
- expect(hydrationCompleteEvents.length).toBe(1);
63
- // Verify all elements are hydrated
64
- const simpleElement = yield page.locator("simple-element");
65
- const complexElement = yield page.locator("complex-element");
66
- const nestedElement = yield page.locator("nested-element");
67
- yield expect(simpleElement).not.toHaveAttribute("needs-hydration");
68
- yield expect(complexElement).not.toHaveAttribute("needs-hydration");
69
- yield expect(nestedElement).not.toHaveAttribute("needs-hydration");
70
- // Verify hydrationComplete was called AFTER all individual element hydrations
71
- const lastElementDidHydrateIndex = events.reduce((maxIndex, e, index) => {
72
- return e.callback === "elementDidHydrate" ? index : maxIndex;
73
- }, -1);
74
- const hydrationCompleteIndex = events.findIndex((e) => e.callback === "hydrationComplete");
75
- expect(hydrationCompleteIndex).toBeGreaterThan(lastElementDidHydrateIndex);
76
- }));
77
- test("should handle complex element with observer map", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
78
- yield page.goto("/lifecycle-callbacks");
79
- yield page.waitForFunction(() => window.getHydrationCompleteStatus());
80
- const complexElement = yield page.locator("complex-element");
81
- // Verify the element has hydrated correctly
82
- yield expect(complexElement).toHaveText(/Complex/);
83
- yield expect(complexElement).not.toHaveAttribute("needs-hydration");
84
- const events = yield page.evaluate(() => window.lifecycleEvents);
85
- const complexEvents = events.filter((e) => e.name === "complex-element");
86
- // Complex element should have all lifecycle callbacks
87
- expect(complexEvents.length).toBeGreaterThan(0);
88
- expect(complexEvents.some((e) => e.callback === "elementDidHydrate")).toBe(true);
89
- }));
90
- test("should handle nested elements correctly", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
91
- yield page.goto("/lifecycle-callbacks");
92
- yield page.waitForFunction(() => window.getHydrationCompleteStatus());
93
- const events = yield page.evaluate(() => window.lifecycleEvents);
94
- // Both parent complex-element and nested nested-element should have callbacks
95
- const complexEvents = events.filter((e) => e.name === "complex-element");
96
- const nestedEvents = events.filter((e) => e.name === "nested-element");
97
- expect(complexEvents.length).toBeGreaterThan(0);
98
- expect(nestedEvents.length).toBeGreaterThan(0);
99
- // Both should have hydrated
100
- expect(complexEvents.some((e) => e.callback === "elementDidHydrate")).toBe(true);
101
- expect(nestedEvents.some((e) => e.callback === "elementDidHydrate")).toBe(true);
102
- }));
103
- test("should handle deferred hydration element", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
104
- yield page.goto("/lifecycle-callbacks");
105
- // The deferred element has a prepare() method that delays hydration
106
- yield page.waitForFunction(() => window.getHydrationCompleteStatus(), {
107
- timeout: 5000,
108
- });
109
- const events = yield page.evaluate(() => window.lifecycleEvents);
110
- const deferredEvents = events.filter((e) => e.name === "deferred-element");
111
- // Should have hydration callbacks
112
- expect(deferredEvents.some((e) => e.callback === "elementWillHydrate")).toBe(true);
113
- expect(deferredEvents.some((e) => e.callback === "elementDidHydrate")).toBe(true);
114
- const deferredElement = yield page.locator("deferred-element");
115
- yield expect(deferredElement).not.toHaveAttribute("needs-hydration");
116
- yield expect(deferredElement).not.toHaveAttribute("defer-hydration");
117
- }));
118
- test("should verify template and hydration callbacks are invoked", ({ page, }) => __awaiter(void 0, void 0, void 0, function* () {
119
- yield page.goto("/lifecycle-callbacks");
120
- yield page.waitForFunction(() => window.getHydrationCompleteStatus());
121
- const events = yield page.evaluate(() => window.lifecycleEvents);
122
- // For each element, verify both template and hydration callbacks are invoked
123
- // Note: These callbacks can be interleaved as template processing is async
124
- const elementNames = ["simple-element", "complex-element", "nested-element"];
125
- elementNames.forEach(name => {
126
- const elementEvents = events.filter((e) => e.name === name);
127
- const callbacks = elementEvents.map((e) => e.callback);
128
- // Verify all expected callbacks were invoked
129
- expect(callbacks).toContain("elementDidRegister");
130
- expect(callbacks).toContain("templateWillUpdate");
131
- expect(callbacks).toContain("templateDidUpdate");
132
- expect(callbacks).toContain("elementDidDefine");
133
- expect(callbacks).toContain("elementWillHydrate");
134
- expect(callbacks).toContain("elementDidHydrate");
135
- // Verify hydration callbacks are in order
136
- const willHydrateIndex = callbacks.indexOf("elementWillHydrate");
137
- const didHydrateIndex = callbacks.indexOf("elementDidHydrate");
138
- expect(willHydrateIndex).toBeLessThan(didHydrateIndex);
139
- // Verify template callbacks are in order
140
- const registerIndex = callbacks.indexOf("elementDidRegister");
141
- const willUpdateIndex = callbacks.indexOf("templateWillUpdate");
142
- const didUpdateIndex = callbacks.indexOf("templateDidUpdate");
143
- const defineIndex = callbacks.indexOf("elementDidDefine");
144
- expect(registerIndex).toBeLessThan(willUpdateIndex);
145
- expect(willUpdateIndex).toBeLessThan(didUpdateIndex);
146
- expect(didUpdateIndex).toBeLessThan(defineIndex);
147
- });
148
- }));
149
- test("should properly hydrate elements and maintain functionality", ({ page, }) => __awaiter(void 0, void 0, void 0, function* () {
150
- yield page.goto("/lifecycle-callbacks");
151
- yield page.waitForFunction(() => window.getHydrationCompleteStatus());
152
- const simpleElement = yield page.locator("simple-element");
153
- const complexElement = yield page.locator("complex-element");
154
- // Verify simple element displays correctly
155
- yield expect(simpleElement).toHaveText("Hello World");
156
- // Verify complex element displays correctly
157
- yield expect(complexElement).toHaveText(/Complex/);
158
- // Verify elements are interactive after hydration
159
- const currentCount = yield complexElement.evaluate((el) => el.count);
160
- expect(currentCount).toBe(0);
161
- // Interact with the element
162
- yield complexElement.evaluate((el) => el.increment());
163
- const newCount = yield complexElement.evaluate((el) => el.count);
164
- expect(newCount).toBe(1);
165
- }));
166
- }));
@@ -1,126 +0,0 @@
1
- import { __awaiter, __decorate, __metadata } from "tslib";
2
- import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
3
- import { attr, FASTElement, observable } from "@microsoft/fast-element";
4
- // Track lifecycle callbacks for testing
5
- export const lifecycleEvents = [];
6
- // Track hydration complete
7
- export let hydrationCompleteEmitted = false;
8
- // Configure lifecycle callbacks
9
- TemplateElement.config({
10
- elementDidRegister(name) {
11
- lifecycleEvents.push({ callback: "elementDidRegister", name });
12
- },
13
- templateWillUpdate(name) {
14
- lifecycleEvents.push({ callback: "templateWillUpdate", name });
15
- },
16
- templateDidUpdate(name) {
17
- lifecycleEvents.push({ callback: "templateDidUpdate", name });
18
- },
19
- elementDidDefine(name) {
20
- lifecycleEvents.push({ callback: "elementDidDefine", name });
21
- },
22
- elementWillHydrate(name) {
23
- lifecycleEvents.push({ callback: "elementWillHydrate", name });
24
- },
25
- elementDidHydrate(name) {
26
- lifecycleEvents.push({ callback: "elementDidHydrate", name });
27
- },
28
- hydrationComplete() {
29
- lifecycleEvents.push({ callback: "hydrationComplete" });
30
- hydrationCompleteEmitted = true;
31
- },
32
- });
33
- // Simple element with basic property
34
- class SimpleElement extends FASTElement {
35
- constructor() {
36
- super(...arguments);
37
- this.message = "Hello";
38
- }
39
- }
40
- __decorate([
41
- attr,
42
- __metadata("design:type", String)
43
- ], SimpleElement.prototype, "message", void 0);
44
- RenderableFASTElement(SimpleElement).defineAsync({
45
- name: "simple-element",
46
- templateOptions: "defer-and-hydrate",
47
- });
48
- // Complex element with multiple properties and methods
49
- class ComplexElement extends FASTElement {
50
- constructor() {
51
- super(...arguments);
52
- this.title = "Complex";
53
- this.count = 0;
54
- this.items = [];
55
- }
56
- increment() {
57
- this.count++;
58
- }
59
- addItem(item) {
60
- this.items = [...this.items, item];
61
- }
62
- }
63
- __decorate([
64
- attr,
65
- __metadata("design:type", String)
66
- ], ComplexElement.prototype, "title", void 0);
67
- __decorate([
68
- observable,
69
- __metadata("design:type", Number)
70
- ], ComplexElement.prototype, "count", void 0);
71
- __decorate([
72
- observable,
73
- __metadata("design:type", Array)
74
- ], ComplexElement.prototype, "items", void 0);
75
- RenderableFASTElement(ComplexElement).defineAsync({
76
- name: "complex-element",
77
- templateOptions: "defer-and-hydrate",
78
- });
79
- // Nested element
80
- class NestedElement extends FASTElement {
81
- constructor() {
82
- super(...arguments);
83
- this.label = "Nested";
84
- }
85
- }
86
- __decorate([
87
- attr,
88
- __metadata("design:type", String)
89
- ], NestedElement.prototype, "label", void 0);
90
- RenderableFASTElement(NestedElement).defineAsync({
91
- name: "nested-element",
92
- templateOptions: "defer-and-hydrate",
93
- });
94
- // Element with deferred hydration
95
- class DeferredElement extends FASTElement {
96
- constructor() {
97
- super(...arguments);
98
- this.status = "pending";
99
- }
100
- prepare() {
101
- return __awaiter(this, void 0, void 0, function* () {
102
- // Simulate async work
103
- yield new Promise(resolve => setTimeout(resolve, 100));
104
- this.status = "ready";
105
- });
106
- }
107
- }
108
- __decorate([
109
- attr,
110
- __metadata("design:type", String)
111
- ], DeferredElement.prototype, "status", void 0);
112
- RenderableFASTElement(DeferredElement).defineAsync({
113
- name: "deferred-element",
114
- templateOptions: "defer-and-hydrate",
115
- });
116
- // Define templates
117
- TemplateElement.options({
118
- "complex-element": {
119
- observerMap: "all",
120
- },
121
- }).define({
122
- name: "f-template",
123
- });
124
- // Make lifecycleEvents available globally for testing
125
- window.lifecycleEvents = lifecycleEvents;
126
- window.getHydrationCompleteStatus = () => hydrationCompleteEmitted;