@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.
- package/dist/dts/components/observer-map.d.ts +1 -1
- package/dist/dts/components/schema.d.ts +1 -1
- package/dist/dts/components/utilities.d.ts +20 -18
- package/dist/esm/components/element.js +0 -5
- package/dist/esm/components/utilities.js +116 -71
- package/package.json +17 -32
- package/dist/dts/fixtures/attribute/attribute.spec.d.ts +0 -1
- package/dist/dts/fixtures/attribute/main.d.ts +0 -1
- package/dist/dts/fixtures/binding/binding.spec.d.ts +0 -1
- package/dist/dts/fixtures/binding/main.d.ts +0 -1
- package/dist/dts/fixtures/children/children.spec.d.ts +0 -1
- package/dist/dts/fixtures/children/main.d.ts +0 -1
- package/dist/dts/fixtures/dot-syntax/dot-syntax.spec.d.ts +0 -1
- package/dist/dts/fixtures/dot-syntax/main.d.ts +0 -1
- package/dist/dts/fixtures/event/event.spec.d.ts +0 -1
- package/dist/dts/fixtures/event/main.d.ts +0 -1
- package/dist/dts/fixtures/lifecycle-callbacks/lifecycle-callbacks.spec.d.ts +0 -1
- package/dist/dts/fixtures/lifecycle-callbacks/main.d.ts +0 -5
- package/dist/dts/fixtures/observer-map/main.d.ts +0 -1
- package/dist/dts/fixtures/observer-map/observer-map.spec.d.ts +0 -1
- package/dist/dts/fixtures/ref/main.d.ts +0 -1
- package/dist/dts/fixtures/ref/ref.spec.d.ts +0 -1
- package/dist/dts/fixtures/repeat/main.d.ts +0 -1
- package/dist/dts/fixtures/repeat/repeat.spec.d.ts +0 -1
- package/dist/dts/fixtures/slotted/main.d.ts +0 -1
- package/dist/dts/fixtures/slotted/slotted.spec.d.ts +0 -1
- package/dist/dts/fixtures/when/main.d.ts +0 -1
- package/dist/dts/fixtures/when/when.spec.d.ts +0 -1
- package/dist/esm/fixtures/attribute/attribute.spec.js +0 -23
- package/dist/esm/fixtures/attribute/main.js +0 -20
- package/dist/esm/fixtures/binding/binding.spec.js +0 -23
- package/dist/esm/fixtures/binding/main.js +0 -30
- package/dist/esm/fixtures/children/children.spec.js +0 -37
- package/dist/esm/fixtures/children/main.js +0 -25
- package/dist/esm/fixtures/dot-syntax/dot-syntax.spec.js +0 -116
- package/dist/esm/fixtures/dot-syntax/main.js +0 -42
- package/dist/esm/fixtures/event/event.spec.js +0 -35
- package/dist/esm/fixtures/event/main.js +0 -32
- package/dist/esm/fixtures/lifecycle-callbacks/lifecycle-callbacks.spec.js +0 -166
- package/dist/esm/fixtures/lifecycle-callbacks/main.js +0 -126
- package/dist/esm/fixtures/observer-map/main.js +0 -375
- package/dist/esm/fixtures/observer-map/observer-map.spec.js +0 -251
- package/dist/esm/fixtures/ref/main.js +0 -15
- package/dist/esm/fixtures/ref/ref.spec.js +0 -9
- package/dist/esm/fixtures/repeat/main.js +0 -44
- package/dist/esm/fixtures/repeat/repeat.spec.js +0 -36
- package/dist/esm/fixtures/slotted/main.js +0 -33
- package/dist/esm/fixtures/slotted/slotted.spec.js +0 -24
- package/dist/esm/fixtures/when/main.js +0 -156
- package/dist/esm/fixtures/when/when.spec.js +0 -82
- 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;
|