@microsoft/fast-html 1.0.0-alpha.3 → 1.0.0-alpha.31
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/README.md +255 -18
- package/dist/dts/components/element.d.ts +10 -0
- package/dist/dts/components/index.d.ts +3 -1
- package/dist/dts/components/observer-map.d.ts +26 -0
- package/dist/dts/components/schema.d.ts +144 -0
- package/dist/dts/components/template.d.ts +83 -7
- package/dist/dts/components/utilities.d.ts +109 -18
- package/dist/dts/fixtures/lifecycle-callbacks/lifecycle-callbacks.spec.d.ts +1 -0
- package/dist/dts/fixtures/lifecycle-callbacks/main.d.ts +5 -0
- package/dist/dts/fixtures/observer-map/main.d.ts +1 -0
- package/dist/dts/fixtures/observer-map/observer-map.spec.d.ts +1 -0
- package/dist/dts/index.d.ts +1 -1
- package/dist/esm/components/element.js +28 -0
- package/dist/esm/components/index.js +3 -1
- package/dist/esm/components/observer-map.js +53 -0
- package/dist/esm/components/observer-map.spec.js +19 -0
- package/dist/esm/components/schema.js +250 -0
- package/dist/esm/components/schema.spec.js +485 -0
- package/dist/esm/components/template.js +199 -111
- package/dist/esm/components/utilities.js +741 -43
- package/dist/esm/components/utilities.spec.js +317 -44
- package/dist/esm/fixtures/attribute/main.js +3 -2
- package/dist/esm/fixtures/binding/binding.spec.js +6 -0
- package/dist/esm/fixtures/binding/main.js +13 -2
- package/dist/esm/fixtures/children/children.spec.js +4 -0
- package/dist/esm/fixtures/children/main.js +3 -2
- package/dist/esm/fixtures/dot-syntax/dot-syntax.spec.js +109 -2
- package/dist/esm/fixtures/dot-syntax/main.js +30 -4
- package/dist/esm/fixtures/event/event.spec.js +28 -5
- package/dist/esm/fixtures/event/main.js +21 -5
- package/dist/esm/fixtures/lifecycle-callbacks/lifecycle-callbacks.spec.js +166 -0
- package/dist/esm/fixtures/lifecycle-callbacks/main.js +126 -0
- package/dist/esm/fixtures/observer-map/main.js +375 -0
- package/dist/esm/fixtures/observer-map/observer-map.spec.js +251 -0
- package/dist/esm/fixtures/ref/main.js +3 -2
- package/dist/esm/fixtures/ref/ref.spec.js +2 -6
- package/dist/esm/fixtures/repeat/main.js +27 -2
- package/dist/esm/fixtures/repeat/repeat.spec.js +16 -6
- package/dist/esm/fixtures/slotted/main.js +15 -4
- package/dist/esm/fixtures/slotted/slotted.spec.js +18 -19
- package/dist/esm/fixtures/when/main.js +139 -2
- package/dist/esm/fixtures/when/when.spec.js +64 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/fast-html.api.json +333 -0
- package/dist/fast-html.d.ts +282 -6
- package/dist/fast-html.untrimmed.d.ts +282 -6
- package/package.json +12 -7
- package/rules/attribute-directives.yml +38 -0
- package/rules/call-expression-with-event-argument.yml +41 -0
- package/rules/member-expression.yml +33 -0
- package/rules/tag-function-to-template-literal.yml +16 -0
- package/dist/esm/fixtures/partial/main.js +0 -31
- package/dist/esm/fixtures/partial/partial.spec.js +0 -14
- /package/dist/dts/{fixtures/partial/main.d.ts → components/observer-map.spec.d.ts} +0 -0
- /package/dist/dts/{fixtures/partial/partial.spec.d.ts → components/schema.spec.d.ts} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
import { expect, test } from "@playwright/test";
|
|
3
|
-
import {
|
|
3
|
+
import { refPropertyName } from "./schema.js";
|
|
4
|
+
import { getNextBehavior, getIndexOfNextMatchingTag, pathResolver, transformInnerHTML, getExpressionChain, extractPathsFromChainedExpression, getChildrenMap, findDef, } from "./utilities.js";
|
|
4
5
|
test.describe("utilities", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5
6
|
test.describe("content", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
6
7
|
test("get the next content binding", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -8,6 +9,7 @@ test.describe("utilities", () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
8
9
|
const templateResult = getNextBehavior(innerHTML);
|
|
9
10
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("dataBinding");
|
|
10
11
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.subtype).toEqual("content");
|
|
12
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.bindingType).toEqual("default");
|
|
11
13
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingStartIndex).toEqual(0);
|
|
12
14
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingEndIndex).toEqual(2);
|
|
13
15
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingStartIndex).toEqual(6);
|
|
@@ -21,21 +23,23 @@ test.describe("utilities", () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
21
23
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("dataBinding");
|
|
22
24
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.subtype).toEqual("attribute");
|
|
23
25
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.aspect).toEqual(null);
|
|
26
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.bindingType).toEqual("default");
|
|
24
27
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingStartIndex).toEqual(13);
|
|
25
28
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingEndIndex).toEqual(15);
|
|
26
29
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingStartIndex).toEqual(19);
|
|
27
30
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingEndIndex).toEqual(21);
|
|
28
31
|
}));
|
|
29
32
|
test("get the next attribute event binding", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
-
const innerHTML = "<input @click=\"{
|
|
33
|
+
const innerHTML = "<input @click=\"{handleClick()}\">";
|
|
31
34
|
const templateResult = getNextBehavior(innerHTML);
|
|
32
35
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.type).toEqual("dataBinding");
|
|
33
36
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.subtype).toEqual("attribute");
|
|
34
37
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.aspect).toEqual("@");
|
|
38
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.bindingType).toEqual("client");
|
|
35
39
|
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingStartIndex).toEqual(15);
|
|
36
|
-
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingEndIndex).toEqual(
|
|
37
|
-
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingStartIndex).toEqual(
|
|
38
|
-
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingEndIndex).toEqual(
|
|
40
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.openingEndIndex).toEqual(16);
|
|
41
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingStartIndex).toEqual(29);
|
|
42
|
+
expect(templateResult === null || templateResult === void 0 ? void 0 : templateResult.closingEndIndex).toEqual(30);
|
|
39
43
|
}));
|
|
40
44
|
}));
|
|
41
45
|
test.describe("templates", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -69,60 +73,40 @@ test.describe("utilities", () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
69
73
|
}));
|
|
70
74
|
test.describe("attributes", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
75
|
test("children directive", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
-
const innerHTML = "<ul f-children=\"{
|
|
76
|
+
const innerHTML = "<ul f-children=\"{list}\"></ul>";
|
|
73
77
|
const result = getNextBehavior(innerHTML);
|
|
74
78
|
expect(result === null || result === void 0 ? void 0 : result.type).toEqual("dataBinding");
|
|
75
79
|
expect(result === null || result === void 0 ? void 0 : result.subtype).toEqual("attributeDirective");
|
|
76
80
|
expect(result === null || result === void 0 ? void 0 : result.name).toEqual("children");
|
|
81
|
+
expect(result === null || result === void 0 ? void 0 : result.bindingType).toEqual("client");
|
|
77
82
|
expect(result === null || result === void 0 ? void 0 : result.openingStartIndex).toEqual(16);
|
|
78
|
-
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(
|
|
79
|
-
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(
|
|
80
|
-
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(
|
|
83
|
+
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(17);
|
|
84
|
+
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(21);
|
|
85
|
+
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(22);
|
|
81
86
|
}));
|
|
82
87
|
test("slotted directive", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
83
|
-
const innerHTML = "<slot f-slotted=\"{
|
|
88
|
+
const innerHTML = "<slot f-slotted=\"{slottedNodes}\"></slot>";
|
|
84
89
|
const result = getNextBehavior(innerHTML);
|
|
85
90
|
expect(result === null || result === void 0 ? void 0 : result.type).toEqual("dataBinding");
|
|
86
91
|
expect(result === null || result === void 0 ? void 0 : result.subtype).toEqual("attributeDirective");
|
|
87
92
|
expect(result === null || result === void 0 ? void 0 : result.name).toEqual("slotted");
|
|
93
|
+
expect(result === null || result === void 0 ? void 0 : result.bindingType).toEqual("client");
|
|
88
94
|
expect(result === null || result === void 0 ? void 0 : result.openingStartIndex).toEqual(17);
|
|
89
|
-
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(
|
|
90
|
-
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(
|
|
91
|
-
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(
|
|
95
|
+
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(18);
|
|
96
|
+
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(30);
|
|
97
|
+
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(31);
|
|
92
98
|
}));
|
|
93
99
|
test("ref directive", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
94
|
-
const innerHTML = "<video f-ref=\"{
|
|
100
|
+
const innerHTML = "<video f-ref=\"{video}\"></video>";
|
|
95
101
|
const result = getNextBehavior(innerHTML);
|
|
96
102
|
expect(result === null || result === void 0 ? void 0 : result.type).toEqual("dataBinding");
|
|
97
103
|
expect(result === null || result === void 0 ? void 0 : result.subtype).toEqual("attributeDirective");
|
|
98
104
|
expect(result === null || result === void 0 ? void 0 : result.name).toEqual("ref");
|
|
105
|
+
expect(result === null || result === void 0 ? void 0 : result.bindingType).toEqual("client");
|
|
99
106
|
expect(result === null || result === void 0 ? void 0 : result.openingStartIndex).toEqual(14);
|
|
100
|
-
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(
|
|
101
|
-
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(
|
|
102
|
-
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(
|
|
103
|
-
}));
|
|
104
|
-
}));
|
|
105
|
-
test.describe("partials", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
106
|
-
test("get a single partial", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
107
|
-
const partialContent = "{{text}}";
|
|
108
|
-
const partial = `<f-partial id="foo">${partialContent}</f-partial>`;
|
|
109
|
-
const allPartials = getAllPartials(partial);
|
|
110
|
-
expect(allPartials.foo.innerHTML).toEqual(partialContent);
|
|
111
|
-
expect(allPartials.foo.startIndex).toEqual(20);
|
|
112
|
-
expect(allPartials.foo.endIndex).toEqual(28);
|
|
113
|
-
}));
|
|
114
|
-
test("get multiple partials", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
115
|
-
const partial1Content = "{{text}}";
|
|
116
|
-
const partial2Content = "{{othertext}}";
|
|
117
|
-
const partial1 = `<f-partial id="foo">${partial1Content}</f-partial>`;
|
|
118
|
-
const partial2 = `<f-partial id="foobar">${partial2Content}</f-partial>`;
|
|
119
|
-
const allPartials = getAllPartials(`${partial1}${partial2}`);
|
|
120
|
-
expect(allPartials.foo.innerHTML).toEqual(partial1Content);
|
|
121
|
-
expect(allPartials.foo.startIndex).toEqual(20);
|
|
122
|
-
expect(allPartials.foo.endIndex).toEqual(28);
|
|
123
|
-
expect(allPartials.foobar.innerHTML).toEqual(partial2Content);
|
|
124
|
-
expect(allPartials.foobar.startIndex).toEqual(63);
|
|
125
|
-
expect(allPartials.foobar.endIndex).toEqual(76);
|
|
107
|
+
expect(result === null || result === void 0 ? void 0 : result.openingEndIndex).toEqual(15);
|
|
108
|
+
expect(result === null || result === void 0 ? void 0 : result.closingStartIndex).toEqual(20);
|
|
109
|
+
expect(result === null || result === void 0 ? void 0 : result.closingEndIndex).toEqual(21);
|
|
126
110
|
}));
|
|
127
111
|
}));
|
|
128
112
|
test.describe("getIndexOfNextMatchingTag", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -145,16 +129,305 @@ test.describe("utilities", () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
145
129
|
}));
|
|
146
130
|
test.describe("pathResolver", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
147
131
|
test("should resolve a path with no nesting", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
|
-
expect(pathResolver("foo")({ foo: "bar" })).toEqual("bar");
|
|
132
|
+
expect(pathResolver("foo", null, 0, {})({ foo: "bar" }, {})).toEqual("bar");
|
|
149
133
|
}));
|
|
150
134
|
test("should resolve a path with nesting", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
151
|
-
expect(pathResolver("foo.bar.bat")({ foo: { bar: { bat: "baz" } } })).toEqual("baz");
|
|
135
|
+
expect(pathResolver("foo.bar.bat", null, 0, {})({ foo: { bar: { bat: "baz" } } }, {})).toEqual("baz");
|
|
152
136
|
}));
|
|
153
137
|
test("should resolve a path with no nesting and self reference", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
154
|
-
expect(pathResolver("foo",
|
|
138
|
+
expect(pathResolver("foo", "foo", 0, {})("bar", {})).toEqual("bar");
|
|
155
139
|
}));
|
|
156
140
|
test("should resolve a path with nesting and self reference", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
157
|
-
expect(pathResolver("foo.bar.bat",
|
|
141
|
+
expect(pathResolver("foo.bar.bat", "foo", 0, {})({ bar: { bat: "baz" } }, {})).toEqual("baz");
|
|
142
|
+
}));
|
|
143
|
+
test("should resolve a path with context", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
|
+
expect(pathResolver("foo", "parent", 1, {})({}, { parent: { foo: "bar" } })).toEqual("bar");
|
|
145
|
+
}));
|
|
146
|
+
}));
|
|
147
|
+
test.describe("transformInnerHTML", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
|
+
test("should resolve a single unescaped data binding", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
149
|
+
expect(transformInnerHTML(`{{{html}}}`)).toEqual(`<div :innerHTML="{{html}}"></div>`);
|
|
150
|
+
}));
|
|
151
|
+
test("should resolve multiple unescaped data bindings", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
152
|
+
expect(transformInnerHTML(`{{{foo}}}{{{bar}}}`)).toEqual(`<div :innerHTML="{{foo}}"></div><div :innerHTML="{{bar}}"></div>`);
|
|
153
|
+
}));
|
|
154
|
+
test("should resolve an unescaped data bindings in a mix of other data content bindings", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
155
|
+
expect(transformInnerHTML(`{{text1}}{{{foo}}}{{text2}}{{{bar}}}{{text3}}`)).toEqual(`{{text1}}<div :innerHTML="{{foo}}"></div>{{text2}}<div :innerHTML="{{bar}}"></div>{{text3}}`);
|
|
156
|
+
}));
|
|
157
|
+
test("should resolve default data bindings in sequence", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
+
expect(transformInnerHTML(`{{text1}}{{text2}}`)).toEqual(`{{text1}}{{text2}}`);
|
|
159
|
+
}));
|
|
160
|
+
test("should resolve an unescaped data bindings in a mix of other data attribute bindings and nesting", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
161
|
+
expect(transformInnerHTML(`<div data-foo="{{text1}}">{{{foo}}}</div><div data-bar="{{text2}}"></div>{{{bar}}}<div data-bat="{{text3}}"></div>`)).toEqual(`<div data-foo="{{text1}}"><div :innerHTML="{{foo}}"></div></div><div data-bar="{{text2}}"></div><div :innerHTML="{{bar}}"></div><div data-bat="{{text3}}"></div>`);
|
|
162
|
+
}));
|
|
163
|
+
test("should resolve a non-data and non-attribute bindings", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
164
|
+
expect(transformInnerHTML(`<button @click="{handleNoArgsClick()}">No arguments</button>`)).toEqual(`<button @click="{handleNoArgsClick()}">No arguments</button>`);
|
|
165
|
+
}));
|
|
166
|
+
}));
|
|
167
|
+
test.describe("getExpressionChain", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
168
|
+
test("should resolve a truthy value", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
169
|
+
expect(getExpressionChain("foo")).toEqual({
|
|
170
|
+
expression: {
|
|
171
|
+
operator: "access",
|
|
172
|
+
left: "foo",
|
|
173
|
+
leftIsValue: false,
|
|
174
|
+
right: null,
|
|
175
|
+
rightIsValue: null,
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}));
|
|
179
|
+
test("should resolve a falsy value", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
180
|
+
expect(getExpressionChain("!foo")).toEqual({
|
|
181
|
+
expression: {
|
|
182
|
+
operator: "!",
|
|
183
|
+
left: "foo",
|
|
184
|
+
leftIsValue: false,
|
|
185
|
+
right: null,
|
|
186
|
+
rightIsValue: null,
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}));
|
|
190
|
+
test("should resolve a path not equal to string value", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
191
|
+
expect(getExpressionChain("foo != 'test'")).toEqual({
|
|
192
|
+
expression: {
|
|
193
|
+
operator: "!=",
|
|
194
|
+
left: "foo",
|
|
195
|
+
leftIsValue: false,
|
|
196
|
+
right: "test",
|
|
197
|
+
rightIsValue: true,
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}));
|
|
201
|
+
test("should resolve a path not equal to boolean value", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
202
|
+
expect(getExpressionChain("foo != false")).toEqual({
|
|
203
|
+
expression: {
|
|
204
|
+
operator: "!=",
|
|
205
|
+
left: "foo",
|
|
206
|
+
leftIsValue: false,
|
|
207
|
+
right: false,
|
|
208
|
+
rightIsValue: true,
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}));
|
|
212
|
+
test("should resolve a path not equal to numerical value", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
213
|
+
expect(getExpressionChain("foo != 5")).toEqual({
|
|
214
|
+
expression: {
|
|
215
|
+
operator: "!=",
|
|
216
|
+
left: "foo",
|
|
217
|
+
leftIsValue: false,
|
|
218
|
+
right: 5,
|
|
219
|
+
rightIsValue: true,
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}));
|
|
223
|
+
test("should resolve chained expressions", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
224
|
+
expect(getExpressionChain("foo != 'bat' && bar == 'baz'")).toEqual({
|
|
225
|
+
expression: {
|
|
226
|
+
operator: "!=",
|
|
227
|
+
left: "foo",
|
|
228
|
+
leftIsValue: false,
|
|
229
|
+
right: "bat",
|
|
230
|
+
rightIsValue: true,
|
|
231
|
+
},
|
|
232
|
+
next: {
|
|
233
|
+
operator: "&&",
|
|
234
|
+
expression: {
|
|
235
|
+
operator: "==",
|
|
236
|
+
left: "bar",
|
|
237
|
+
leftIsValue: false,
|
|
238
|
+
right: "baz",
|
|
239
|
+
rightIsValue: true,
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
expect(getExpressionChain("foo && bar")).toEqual({
|
|
244
|
+
expression: {
|
|
245
|
+
operator: "access",
|
|
246
|
+
left: "foo",
|
|
247
|
+
leftIsValue: false,
|
|
248
|
+
right: null,
|
|
249
|
+
rightIsValue: null,
|
|
250
|
+
},
|
|
251
|
+
next: {
|
|
252
|
+
operator: "&&",
|
|
253
|
+
expression: {
|
|
254
|
+
operator: "access",
|
|
255
|
+
left: "bar",
|
|
256
|
+
leftIsValue: false,
|
|
257
|
+
right: null,
|
|
258
|
+
rightIsValue: null,
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}));
|
|
263
|
+
}));
|
|
264
|
+
test.describe("extractPathsFromChainedExpression", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
265
|
+
test("should extract paths from simple access expression", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
266
|
+
const expressionChain = getExpressionChain("user");
|
|
267
|
+
expect(expressionChain).toBeDefined();
|
|
268
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
269
|
+
expect(paths.size).toEqual(1);
|
|
270
|
+
expect(paths.has("user")).toBe(true);
|
|
271
|
+
}));
|
|
272
|
+
test("should extract paths from dot notation expression", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
273
|
+
const expressionChain = getExpressionChain("user.name");
|
|
274
|
+
expect(expressionChain).toBeDefined();
|
|
275
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
276
|
+
expect(paths.size).toEqual(1);
|
|
277
|
+
expect(paths.has("user.name")).toBe(true);
|
|
278
|
+
}));
|
|
279
|
+
test("should extract paths from comparison with literal values", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
280
|
+
const expressionChain = getExpressionChain("user.age > 18");
|
|
281
|
+
expect(expressionChain).toBeDefined();
|
|
282
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
283
|
+
expect(paths.size).toEqual(1);
|
|
284
|
+
expect(paths.has("user.age")).toBe(true);
|
|
285
|
+
}));
|
|
286
|
+
test("should extract paths from comparison between two properties", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
287
|
+
const expressionChain = getExpressionChain("user.age >= admin.minAge");
|
|
288
|
+
expect(expressionChain).toBeDefined();
|
|
289
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
290
|
+
expect(paths.size).toEqual(2);
|
|
291
|
+
expect(paths.has("user.age")).toBe(true);
|
|
292
|
+
expect(paths.has("admin.minAge")).toBe(true);
|
|
293
|
+
}));
|
|
294
|
+
test("should extract paths from chained AND expressions", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
295
|
+
const expressionChain = getExpressionChain("isActive && user.name");
|
|
296
|
+
expect(expressionChain).toBeDefined();
|
|
297
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
298
|
+
expect(paths.size).toEqual(2);
|
|
299
|
+
expect(paths.has("isActive")).toBe(true);
|
|
300
|
+
expect(paths.has("user.name")).toBe(true);
|
|
301
|
+
}));
|
|
302
|
+
test("should extract paths from chained OR expressions", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
303
|
+
const expressionChain = getExpressionChain("user.isAdmin || permissions.canEdit");
|
|
304
|
+
expect(expressionChain).toBeDefined();
|
|
305
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
306
|
+
expect(paths.size).toEqual(2);
|
|
307
|
+
expect(paths.has("user.isAdmin")).toBe(true);
|
|
308
|
+
expect(paths.has("permissions.canEdit")).toBe(true);
|
|
309
|
+
}));
|
|
310
|
+
test("should extract paths from complex chained expressions", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
311
|
+
const expressionChain = getExpressionChain("user.age > 18 && user.status == 'active' || admin.override");
|
|
312
|
+
expect(expressionChain).toBeDefined();
|
|
313
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
314
|
+
expect(paths.size).toEqual(3);
|
|
315
|
+
expect(paths.has("user.age")).toBe(true);
|
|
316
|
+
expect(paths.has("user.status")).toBe(true);
|
|
317
|
+
expect(paths.has("admin.override")).toBe(true);
|
|
318
|
+
}));
|
|
319
|
+
test("should extract paths from NOT expressions", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
320
|
+
const expressionChain = getExpressionChain("!user.isDisabled");
|
|
321
|
+
expect(expressionChain).toBeDefined();
|
|
322
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
323
|
+
expect(paths.size).toEqual(1);
|
|
324
|
+
expect(paths.has("user.isDisabled")).toBe(true);
|
|
325
|
+
}));
|
|
326
|
+
test("should handle expressions with only literal values", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
327
|
+
const expressionChain = getExpressionChain("5 > 3");
|
|
328
|
+
expect(expressionChain).toBeDefined();
|
|
329
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
330
|
+
expect(paths.size).toEqual(0);
|
|
331
|
+
}));
|
|
332
|
+
test("should handle mixed literal and property expressions", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
333
|
+
const expressionChain = getExpressionChain("count > 0 && status == 'ready'");
|
|
334
|
+
expect(expressionChain).toBeDefined();
|
|
335
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
336
|
+
expect(paths.size).toEqual(2);
|
|
337
|
+
expect(paths.has("count")).toBe(true);
|
|
338
|
+
expect(paths.has("status")).toBe(true);
|
|
339
|
+
}));
|
|
340
|
+
test("should deduplicate identical paths", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
341
|
+
const expressionChain = getExpressionChain("user.name && user.name != 'anonymous'");
|
|
342
|
+
expect(expressionChain).toBeDefined();
|
|
343
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
344
|
+
expect(paths.size).toEqual(1);
|
|
345
|
+
expect(paths.has("user.name")).toBe(true);
|
|
346
|
+
}));
|
|
347
|
+
test("should handle HTML entity operators", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
348
|
+
const expressionChain = getExpressionChain("isValid && data.ready");
|
|
349
|
+
expect(expressionChain).toBeDefined();
|
|
350
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
351
|
+
expect(paths.size).toEqual(2);
|
|
352
|
+
expect(paths.has("isValid")).toBe(true);
|
|
353
|
+
expect(paths.has("data.ready")).toBe(true);
|
|
354
|
+
}));
|
|
355
|
+
test("should handle deeply nested property paths", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
356
|
+
const expressionChain = getExpressionChain("app.user.profile.settings.theme");
|
|
357
|
+
expect(expressionChain).toBeDefined();
|
|
358
|
+
const paths = extractPathsFromChainedExpression(expressionChain);
|
|
359
|
+
expect(paths.size).toEqual(1);
|
|
360
|
+
expect(paths.has("app.user.profile.settings.theme")).toBe(true);
|
|
361
|
+
}));
|
|
362
|
+
}));
|
|
363
|
+
test.describe("getChildrenMap", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
364
|
+
test("should get a ChildrenMap if an attribute is part of a custom element", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
365
|
+
const childrenMap = getChildrenMap(`<template><my-element foo="`);
|
|
366
|
+
expect(childrenMap).not.toBeNull();
|
|
367
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.attributeName).toEqual("foo");
|
|
368
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.customElementName).toEqual("my-element");
|
|
369
|
+
}));
|
|
370
|
+
test("should not get a ChildrenMap if an attribute is part of a non-custom element", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
371
|
+
const childrenMap = getChildrenMap(`<template><button foo="`);
|
|
372
|
+
expect(childrenMap).toBeNull();
|
|
373
|
+
}));
|
|
374
|
+
test("should remove any aspected attributes from an attribute name", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
375
|
+
const childrenMap = getChildrenMap(`<template><my-element :foo="`);
|
|
376
|
+
expect(childrenMap).not.toBeNull();
|
|
377
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.attributeName).toEqual("foo");
|
|
378
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.customElementName).toEqual("my-element");
|
|
379
|
+
}));
|
|
380
|
+
test("should not get a ChildreMap if the previous string indicates the binding was not an attribute", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
381
|
+
const childrenMap = getChildrenMap(`<template><my-element>`);
|
|
382
|
+
expect(childrenMap).toBeNull();
|
|
383
|
+
}));
|
|
384
|
+
test("should get a ChildrenMap if there are multiple attributes are listed before this attribute", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
385
|
+
const childrenMap = getChildrenMap(`<template><my-element foo="" bar="" bat="`);
|
|
386
|
+
expect(childrenMap).not.toBeNull();
|
|
387
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.attributeName).toEqual("bat");
|
|
388
|
+
expect(childrenMap === null || childrenMap === void 0 ? void 0 : childrenMap.customElementName).toEqual("my-element");
|
|
389
|
+
}));
|
|
390
|
+
}));
|
|
391
|
+
test.describe("schema functions", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
392
|
+
test.describe("findDef", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
393
|
+
test("should resolve from the root of a schema", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
394
|
+
expect(findDef({
|
|
395
|
+
[refPropertyName]: "#/$defs/MyType"
|
|
396
|
+
})).toEqual("MyType");
|
|
397
|
+
}));
|
|
398
|
+
test("should resolve as null from an anyOf array containing a reference to another component", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
399
|
+
expect(findDef({
|
|
400
|
+
anyOf: [
|
|
401
|
+
{
|
|
402
|
+
[refPropertyName]: "https://fast.design/schemas/test-element/c.json"
|
|
403
|
+
}
|
|
404
|
+
]
|
|
405
|
+
})).toEqual(null);
|
|
406
|
+
}));
|
|
407
|
+
test("should resolve from an anyOf array containing a reference to a $def", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
408
|
+
expect(findDef({
|
|
409
|
+
anyOf: [
|
|
410
|
+
{
|
|
411
|
+
[refPropertyName]: "#/$defs/MyType"
|
|
412
|
+
}
|
|
413
|
+
]
|
|
414
|
+
})).toEqual("MyType");
|
|
415
|
+
}));
|
|
416
|
+
test("should resolve from an anyOf array containing a reference to another component and a reference to a $def", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
417
|
+
expect(findDef({
|
|
418
|
+
anyOf: [
|
|
419
|
+
{
|
|
420
|
+
[refPropertyName]: "https://fast.design/schemas/test-element/c.json"
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
[refPropertyName]: "#/$defs/MyType"
|
|
424
|
+
}
|
|
425
|
+
]
|
|
426
|
+
})).toEqual("MyType");
|
|
427
|
+
}));
|
|
428
|
+
test("should resolve as null if not found", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
429
|
+
expect(findDef({})).toEqual(null);
|
|
430
|
+
}));
|
|
158
431
|
}));
|
|
159
432
|
}));
|
|
160
433
|
}));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
|
-
import { TemplateElement } from "@microsoft/fast-html";
|
|
2
|
+
import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
|
|
3
3
|
import { attr, FASTElement } from "@microsoft/fast-element";
|
|
4
4
|
class TestElement extends FASTElement {
|
|
5
5
|
constructor() {
|
|
@@ -11,8 +11,9 @@ __decorate([
|
|
|
11
11
|
attr,
|
|
12
12
|
__metadata("design:type", String)
|
|
13
13
|
], TestElement.prototype, "type", void 0);
|
|
14
|
-
TestElement.
|
|
14
|
+
RenderableFASTElement(TestElement).defineAsync({
|
|
15
15
|
name: "test-element",
|
|
16
|
+
templateOptions: "defer-and-hydrate",
|
|
16
17
|
});
|
|
17
18
|
TemplateElement.define({
|
|
18
19
|
name: "f-template",
|
|
@@ -14,4 +14,10 @@ test.describe("f-template", () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
14
14
|
yield expect(yield customElement.getAttribute("text")).toEqual("Hello pluto");
|
|
15
15
|
yield expect(customElement).toHaveText("Hello pluto");
|
|
16
16
|
}));
|
|
17
|
+
test("create an unescaped binding", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
yield page.goto("/binding");
|
|
19
|
+
const customElement = yield page.locator("test-element-unescaped");
|
|
20
|
+
yield expect(yield customElement.locator("p").count()).toEqual(1);
|
|
21
|
+
yield expect(customElement).toHaveText("Hello world");
|
|
22
|
+
}));
|
|
17
23
|
}));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
|
-
import { TemplateElement } from "@microsoft/fast-html";
|
|
2
|
+
import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
|
|
3
3
|
import { attr, FASTElement } from "@microsoft/fast-element";
|
|
4
4
|
class TestElement extends FASTElement {
|
|
5
5
|
constructor() {
|
|
@@ -11,8 +11,19 @@ __decorate([
|
|
|
11
11
|
attr,
|
|
12
12
|
__metadata("design:type", String)
|
|
13
13
|
], TestElement.prototype, "text", void 0);
|
|
14
|
-
TestElement.
|
|
14
|
+
RenderableFASTElement(TestElement).defineAsync({
|
|
15
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",
|
|
16
27
|
});
|
|
17
28
|
TemplateElement.define({
|
|
18
29
|
name: "f-template",
|
|
@@ -20,6 +20,10 @@ test.describe("f-template", () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
20
20
|
"C"
|
|
21
21
|
];
|
|
22
22
|
});
|
|
23
|
+
const timeout = new Promise(function (resolve) {
|
|
24
|
+
setTimeout(resolve, 100);
|
|
25
|
+
});
|
|
26
|
+
yield timeout;
|
|
23
27
|
const listItemCount2 = yield page.evaluate(() => {
|
|
24
28
|
var _a;
|
|
25
29
|
const customElement = document.getElementsByTagName("test-element");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
|
-
import { TemplateElement } from "@microsoft/fast-html";
|
|
2
|
+
import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
|
|
3
3
|
import { FASTElement, observable } from "@microsoft/fast-element";
|
|
4
4
|
class TestElement extends FASTElement {
|
|
5
5
|
constructor() {
|
|
@@ -16,8 +16,9 @@ __decorate([
|
|
|
16
16
|
observable,
|
|
17
17
|
__metadata("design:type", Array)
|
|
18
18
|
], TestElement.prototype, "list", void 0);
|
|
19
|
-
TestElement.
|
|
19
|
+
RenderableFASTElement(TestElement).defineAsync({
|
|
20
20
|
name: "test-element",
|
|
21
|
+
templateOptions: "defer-and-hydrate",
|
|
21
22
|
});
|
|
22
23
|
TemplateElement.define({
|
|
23
24
|
name: "f-template",
|
|
@@ -1,9 +1,116 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
import { expect, test } from "@playwright/test";
|
|
3
|
-
test.describe("f-template", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
3
|
+
test.describe("f-template dot-syntax bindings", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4
4
|
test("create a object property reference using dot syntax in a binding", ({ page }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5
5
|
yield page.goto("/dot-syntax");
|
|
6
6
|
const customElement = yield page.locator("test-element");
|
|
7
|
-
yield expect(customElement).toHaveText("bar");
|
|
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 });
|
|
8
115
|
}));
|
|
9
116
|
}));
|