@stackoverflow/stacks 1.7.1 → 1.9.0
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 +1 -1
- package/dist/components/activity-indicator/activity-indicator.a11y.test.d.ts +1 -0
- package/dist/components/activity-indicator/activity-indicator.visual.test.d.ts +1 -0
- package/dist/components/avatar/avatar.a11y.test.d.ts +1 -0
- package/dist/components/avatar/avatar.visual.test.d.ts +1 -0
- package/dist/{controllers/s-banner.d.ts → components/banner/banner.d.ts} +1 -1
- package/dist/components/banner/banner.test.d.ts +1 -0
- package/dist/components/banner/banner.visual.test.d.ts +1 -0
- package/dist/components/button/button.a11y.test.d.ts +1 -0
- package/dist/components/button/button.visual.test.d.ts +1 -0
- package/dist/{controllers/s-expandable-control.d.ts → components/expandable/expandable.d.ts} +1 -1
- package/dist/components/expandable/expandable.test.d.ts +1 -0
- package/dist/{controllers/s-modal.d.ts → components/modal/modal.d.ts} +1 -1
- package/dist/{controllers/s-navigation-tablist.d.ts → components/navigation/navigation.d.ts} +1 -1
- package/dist/{controllers/s-popover.d.ts → components/popover/popover.d.ts} +1 -1
- package/dist/{controllers/s-tooltip.d.ts → components/popover/tooltip.d.ts} +1 -1
- package/dist/components/popover/tooltip.test.d.ts +1 -0
- package/dist/components/popover/tooltip.visual.test.d.ts +1 -0
- package/dist/{controllers/s-table.d.ts → components/table/table.d.ts} +1 -1
- package/dist/{controllers/s-toast.d.ts → components/toast/toast.d.ts} +1 -1
- package/dist/components/toast/toast.test.d.ts +1 -0
- package/dist/components/toast/toast.visual.test.d.ts +1 -0
- package/dist/{controllers/s-uploader.d.ts → components/uploader/uploader.d.ts} +1 -1
- package/dist/controllers.d.ts +9 -0
- package/dist/css/stacks.css +1351 -1171
- package/dist/css/stacks.min.css +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/js/stacks.js +545 -545
- package/dist/js/stacks.min.js +1 -1
- package/dist/test/test-utils.d.ts +136 -0
- package/lib/{css/atomic/borders.less → atomic/border.less} +18 -0
- package/lib/base/fieldset.less +5 -0
- package/lib/{css/base/icons.less → base/icon.less} +0 -9
- package/lib/components/activity-indicator/activity-indicator.a11y.test.ts +21 -0
- package/lib/components/activity-indicator/activity-indicator.visual.test.ts +23 -0
- package/lib/components/avatar/avatar.a11y.test.ts +36 -0
- package/lib/components/avatar/avatar.visual.test.ts +54 -0
- package/lib/components/banner/banner.less +51 -0
- package/lib/{test/s-banner.test.ts → components/banner/banner.test.ts} +7 -3
- package/lib/{ts/controllers/s-banner.ts → components/banner/banner.ts} +1 -1
- package/lib/components/banner/banner.visual.test.ts +36 -0
- package/lib/components/button/button.a11y.test.ts +32 -0
- package/lib/{css/components/buttons.less → components/button/button.less} +7 -6
- package/lib/components/button/button.visual.test.ts +52 -0
- package/lib/{css/components/cards.less → components/card/card.less} +1 -1
- package/lib/components/check-control/check-control.less +17 -0
- package/lib/components/check-group/check-group.less +19 -0
- package/lib/components/checkbox_radio/checkbox_radio.less +158 -0
- package/lib/components/description/description.less +9 -0
- package/lib/{css/components → components/expandable}/expandable.less +3 -0
- package/lib/components/expandable/expandable.test.ts +53 -0
- package/lib/{ts/controllers/s-expandable-control.ts → components/expandable/expandable.ts} +1 -1
- package/lib/components/input-fill/input-fill.less +35 -0
- package/lib/components/input-icon/input-icon.less +45 -0
- package/lib/components/input-message/input-message.less +48 -0
- package/lib/components/input_textarea/input_textarea.less +166 -0
- package/lib/{css/components/labels.less → components/label/label.less} +4 -4
- package/lib/{css/components → components/link}/link.less +9 -2
- package/lib/{ts/controllers/s-modal.ts → components/modal/modal.ts} +1 -1
- package/lib/{ts/controllers/s-navigation-tablist.ts → components/navigation/navigation.ts} +1 -1
- package/lib/{css/components/notices.less → components/notice/notice.less} +0 -89
- package/lib/{css/components/popovers.less → components/popover/popover.less} +1 -0
- package/lib/{ts/controllers/s-popover.ts → components/popover/popover.ts} +1 -1
- package/lib/{test/s-tooltip.test.ts → components/popover/tooltip.test.ts} +6 -2
- package/lib/{ts/controllers/s-tooltip.ts → components/popover/tooltip.ts} +2 -2
- package/lib/{test/s-tooltip.visual.test.ts → components/popover/tooltip.visual.test.ts} +2 -2
- package/lib/{css/components → components/post-summary}/post-summary.less +6 -2
- package/lib/components/select/select.less +148 -0
- package/lib/{css/components/sidebar-widgets.less → components/sidebar-widget/sidebar-widget.less} +0 -1
- package/lib/{css/components → components/table}/table.less +0 -5
- package/lib/{ts/controllers/s-table.ts → components/table/table.ts} +1 -1
- package/lib/components/table-container/table-container.less +4 -0
- package/lib/{css/components/tags.less → components/tag/tag.less} +3 -3
- package/lib/components/toast/toast.less +35 -0
- package/lib/{test/s-toast.test.ts → components/toast/toast.test.ts} +7 -3
- package/lib/{ts/controllers/s-toast.ts → components/toast/toast.ts} +1 -1
- package/lib/components/toast/toast.visual.test.ts +27 -0
- package/lib/{css/components/toggle-switches.less → components/toggle-switch/toggle-switch.less} +8 -0
- package/lib/{ts/controllers/s-uploader.ts → components/uploader/uploader.ts} +1 -1
- package/lib/controllers.ts +33 -0
- package/lib/{css/exports → exports}/mixins.less +73 -11
- package/lib/{ts/index.ts → index.ts} +1 -1
- package/lib/input-utils.less +44 -0
- package/lib/{css/stacks-dynamic.less → stacks-dynamic.less} +1 -2
- package/lib/stacks-static.less +93 -0
- package/lib/test/test-utils.ts +444 -0
- package/lib/tsconfig.json +1 -1
- package/package.json +26 -25
- package/dist/controllers/index.d.ts +0 -9
- package/lib/css/components/inputs.less +0 -666
- package/lib/css/stacks-static.less +0 -97
- package/lib/test/s-avatar.test.ts +0 -74
- package/lib/test/s-banner.visual.test.ts +0 -61
- package/lib/test/s-button.visual.test.ts +0 -12
- package/lib/test/s-toast.visual.test.ts +0 -48
- package/lib/ts/controllers/index.ts +0 -17
- /package/lib/{css/atomic/colors.less → atomic/color.less} +0 -0
- /package/lib/{css/atomic → atomic}/flex.less +0 -0
- /package/lib/{css/atomic → atomic}/gap.less +0 -0
- /package/lib/{css/atomic → atomic}/grid.less +0 -0
- /package/lib/{css/atomic → atomic}/misc.less +0 -0
- /package/lib/{css/atomic → atomic}/spacing.less +0 -0
- /package/lib/{css/atomic → atomic}/typography.less +0 -0
- /package/lib/{css/atomic → atomic}/width-height.less +0 -0
- /package/lib/{css/base → base}/body.less +0 -0
- /package/lib/{css/base → base}/configuration-static.less +0 -0
- /package/lib/{css/base/internals.less → base/internal.less} +0 -0
- /package/lib/{css/base → base}/reset-meyer.less +0 -0
- /package/lib/{css/base → base}/reset-normalize.less +0 -0
- /package/lib/{css/base → base}/reset.less +0 -0
- /package/lib/{css/components → components/activity-indicator}/activity-indicator.less +0 -0
- /package/lib/{css/components/anchors.less → components/anchor/anchor.less} +0 -0
- /package/lib/{css/components/avatars.less → components/avatar/avatar.less} +0 -0
- /package/lib/{css/components → components/award-bling}/award-bling.less +0 -0
- /package/lib/{css/components/badges.less → components/badge/badge.less} +0 -0
- /package/lib/{css/components → components/block-link}/block-link.less +0 -0
- /package/lib/{css/components → components/breadcrumbs}/breadcrumbs.less +0 -0
- /package/lib/{css/components/button-groups.less → components/button-group/button-group.less} +0 -0
- /package/lib/{css/components/code-blocks.less → components/code-block/code-block.less} +0 -0
- /package/lib/{css/components/empty-states.less → components/empty-state/empty-state.less} +0 -0
- /package/lib/{css/components/link-previews.less → components/link-preview/link-preview.less} +0 -0
- /package/lib/{css/components → components/menu}/menu.less +0 -0
- /package/lib/{css/components/modals.less → components/modal/modal.less} +0 -0
- /package/lib/{css/components → components/navigation}/navigation.less +0 -0
- /package/lib/{css/components/page-titles.less → components/page-title/page-title.less} +0 -0
- /package/lib/{css/components → components/pagination}/pagination.less +0 -0
- /package/lib/{css/components/progress-bars.less → components/progress-bar/progress-bar.less} +0 -0
- /package/lib/{css/components → components/prose}/prose.less +0 -0
- /package/lib/{css/components → components/spinner}/spinner.less +0 -0
- /package/lib/{css/components → components/topbar}/topbar.less +0 -0
- /package/lib/{css/components → components/uploader}/uploader.less +0 -0
- /package/lib/{css/components/user-cards.less → components/user-card/user-card.less} +0 -0
- /package/lib/{css/exports → exports}/constants-colors.less +0 -0
- /package/lib/{css/exports → exports}/constants-helpers.less +0 -0
- /package/lib/{css/exports → exports}/constants-type.less +0 -0
- /package/lib/{css/exports → exports}/exports.less +0 -0
- /package/lib/{css/stacks.less → stacks.less} +0 -0
- /package/lib/{ts/stacks.ts → stacks.ts} +0 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { html, fixture, expect, unsafeStatic } from "@open-wc/testing";
|
|
2
|
+
import { screen } from "@testing-library/dom";
|
|
3
|
+
import { visualDiff } from "@web/test-runner-visual-regression";
|
|
4
|
+
import type { TemplateResult } from "lit-html";
|
|
5
|
+
|
|
6
|
+
const colorThemes = ["dark", "light"];
|
|
7
|
+
const baseThemes = ["", "highcontrast"];
|
|
8
|
+
type Themes = ["light" | "dark" | "highcontrast" | ""];
|
|
9
|
+
type TestTypes = "visual" | "a11y";
|
|
10
|
+
|
|
11
|
+
type TestOptions = {
|
|
12
|
+
/**
|
|
13
|
+
* Enable tests for all color themes
|
|
14
|
+
* default: true
|
|
15
|
+
*/
|
|
16
|
+
testColorThemes: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Enable tests for high contrast
|
|
19
|
+
* default: true
|
|
20
|
+
*/
|
|
21
|
+
testHighContrast: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Include tests for the component without any variants applied
|
|
24
|
+
* default: true
|
|
25
|
+
*/
|
|
26
|
+
includeNullVariant: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Include tests for the component without any modifiers applied
|
|
29
|
+
* default: true
|
|
30
|
+
*/
|
|
31
|
+
includeNullModifier: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
interface ComponentTestVariationArgs {
|
|
35
|
+
/**
|
|
36
|
+
* Base class of the component
|
|
37
|
+
* (e.g. "s-component")
|
|
38
|
+
*/
|
|
39
|
+
baseClass: string;
|
|
40
|
+
/**
|
|
41
|
+
* Variants of the component
|
|
42
|
+
* (e.g. ["primary", "secondary"])
|
|
43
|
+
*/
|
|
44
|
+
variants?: string[];
|
|
45
|
+
/**
|
|
46
|
+
* Modifiers of the component
|
|
47
|
+
* (e.g. { primary: ["filled", "outlined"], secondary: ["xs", "sm", "md"] })
|
|
48
|
+
*/
|
|
49
|
+
modifiers?: ComponentTestModifiers;
|
|
50
|
+
/**
|
|
51
|
+
* Options for the test
|
|
52
|
+
*/
|
|
53
|
+
options?: TestOptions;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
type ComponentTestArgs = {
|
|
57
|
+
/**
|
|
58
|
+
* The element to test
|
|
59
|
+
* use the `html` template tag to render the element
|
|
60
|
+
*/
|
|
61
|
+
element: TemplateResult;
|
|
62
|
+
/**
|
|
63
|
+
* testid of the test
|
|
64
|
+
* (e.g. "s-component-primary-important")
|
|
65
|
+
*/
|
|
66
|
+
testid: string;
|
|
67
|
+
/**
|
|
68
|
+
* Theme to apply to the test element
|
|
69
|
+
*/
|
|
70
|
+
theme?: Themes;
|
|
71
|
+
/**
|
|
72
|
+
* Type of test to run
|
|
73
|
+
*/
|
|
74
|
+
type: TestTypes;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
interface ComponentTestsArgs extends ComponentTestVariationArgs {
|
|
78
|
+
/**
|
|
79
|
+
* Additional html attributes applied to the test element
|
|
80
|
+
* (e.g. { role: "button", id: "id" } -> <element role="button" id="id"> )
|
|
81
|
+
*/
|
|
82
|
+
attributes?: Record<string, string>;
|
|
83
|
+
/**
|
|
84
|
+
* Child elements to render inside the test element
|
|
85
|
+
* (if key `default` is used, the testid will not include the child name)
|
|
86
|
+
*/
|
|
87
|
+
children?: {
|
|
88
|
+
[key: string]: string;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* testids of tests to exclude from testing
|
|
92
|
+
*/
|
|
93
|
+
excludedTestids?: (string | RegExp)[];
|
|
94
|
+
/**
|
|
95
|
+
* testids of tests to skip
|
|
96
|
+
*/
|
|
97
|
+
skippedTestids?: (string | RegExp)[];
|
|
98
|
+
/**
|
|
99
|
+
* HTML tag name of the test element
|
|
100
|
+
*/
|
|
101
|
+
tag?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Function that returns a template for the test element
|
|
104
|
+
* used to wrap the component test element in a container
|
|
105
|
+
*/
|
|
106
|
+
template?: (args: {
|
|
107
|
+
component: unknown;
|
|
108
|
+
tag?: string;
|
|
109
|
+
testid: string;
|
|
110
|
+
}) => ReturnType<typeof html>;
|
|
111
|
+
/**
|
|
112
|
+
* Type of test to run
|
|
113
|
+
*/
|
|
114
|
+
type: TestTypes;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
type ComponentTestModifiers = {
|
|
118
|
+
/**
|
|
119
|
+
* Primary grouping of modifiers to test
|
|
120
|
+
* The base class will be used as a prefix for these modifiers
|
|
121
|
+
*/
|
|
122
|
+
primary?: string[];
|
|
123
|
+
/**
|
|
124
|
+
* Secondary grouping of modifiers to test
|
|
125
|
+
* The base class will be used as a prefix for these modifiers
|
|
126
|
+
*/
|
|
127
|
+
secondary?: string[];
|
|
128
|
+
/**
|
|
129
|
+
* Grouping of modifers to test that will not be prefixed with the base class
|
|
130
|
+
*/
|
|
131
|
+
global?: string[];
|
|
132
|
+
/**
|
|
133
|
+
* Modifiers to test individually
|
|
134
|
+
* The base class will be used as a prefix for these modifiers
|
|
135
|
+
*/
|
|
136
|
+
standalone?: string[];
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
type ComponentTestProps = {
|
|
140
|
+
classes: string;
|
|
141
|
+
testid: string;
|
|
142
|
+
theme?: Themes;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const attrObjToString = (attrs: Record<string, string>): string => {
|
|
146
|
+
const attrString = Object.keys(attrs).map((key) => {
|
|
147
|
+
return `${key}="${attrs[key]}"` || "";
|
|
148
|
+
});
|
|
149
|
+
return attrString.join(" ") || "";
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const buildClasses = ({
|
|
153
|
+
baseClass,
|
|
154
|
+
prefixed = [],
|
|
155
|
+
unprefixed = [],
|
|
156
|
+
}: {
|
|
157
|
+
baseClass: string;
|
|
158
|
+
prefixed?: string[];
|
|
159
|
+
unprefixed?: string[];
|
|
160
|
+
}) =>
|
|
161
|
+
[
|
|
162
|
+
baseClass,
|
|
163
|
+
...prefixed.filter((x) => x).map((suffix) => `${baseClass}__${suffix}`),
|
|
164
|
+
...unprefixed.filter((x) => x),
|
|
165
|
+
].join(" ");
|
|
166
|
+
|
|
167
|
+
const buildTestElement = ({
|
|
168
|
+
attributes = {},
|
|
169
|
+
children = "",
|
|
170
|
+
tag = "div",
|
|
171
|
+
testid,
|
|
172
|
+
}: {
|
|
173
|
+
attributes?: Record<string, string>;
|
|
174
|
+
children?: string;
|
|
175
|
+
tag?: string;
|
|
176
|
+
testid: string;
|
|
177
|
+
}) => {
|
|
178
|
+
const unsafe = {
|
|
179
|
+
tag: unsafeStatic(tag),
|
|
180
|
+
attributes: unsafeStatic(attrObjToString(attributes).toString()),
|
|
181
|
+
children: unsafeStatic(children),
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return html`
|
|
185
|
+
<${unsafe.tag}
|
|
186
|
+
${unsafe.attributes}
|
|
187
|
+
data-testid="${testid}"
|
|
188
|
+
>
|
|
189
|
+
${unsafe.children}
|
|
190
|
+
</${unsafe.tag}>
|
|
191
|
+
`;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const buildTestid = (arr: string[]) => arr.filter(Boolean).join("-");
|
|
195
|
+
|
|
196
|
+
const getComponentTestVariations = ({
|
|
197
|
+
baseClass,
|
|
198
|
+
variants = [],
|
|
199
|
+
modifiers,
|
|
200
|
+
options = {
|
|
201
|
+
testColorThemes: true,
|
|
202
|
+
testHighContrast: true,
|
|
203
|
+
includeNullVariant: false,
|
|
204
|
+
includeNullModifier: true,
|
|
205
|
+
},
|
|
206
|
+
}: ComponentTestVariationArgs): ComponentTestProps[] => {
|
|
207
|
+
const testVariations: ComponentTestProps[] = [];
|
|
208
|
+
// Test default, high contrast themes
|
|
209
|
+
[...(options.testHighContrast ? baseThemes : [""])].forEach((baseTheme) => {
|
|
210
|
+
// Test light, dark theme
|
|
211
|
+
[...(options.testColorThemes ? colorThemes : [""])].forEach(
|
|
212
|
+
(colorTheme) => {
|
|
213
|
+
const theme = [baseTheme, colorTheme].filter(Boolean) as Themes;
|
|
214
|
+
const testidBase = buildTestid([baseClass, ...theme]);
|
|
215
|
+
const primaryModifiers = modifiers?.primary
|
|
216
|
+
? ["", ...(<[]>modifiers.primary)]
|
|
217
|
+
: [""];
|
|
218
|
+
const secondaryModifiers = modifiers?.secondary
|
|
219
|
+
? ["", ...(<[]>modifiers.secondary)]
|
|
220
|
+
: [""];
|
|
221
|
+
const globalModifiers = modifiers?.global
|
|
222
|
+
? ["", ...(<[]>modifiers.global)]
|
|
223
|
+
: [""];
|
|
224
|
+
|
|
225
|
+
primaryModifiers.forEach((primaryModifier) => {
|
|
226
|
+
secondaryModifiers.forEach((secondaryModifier) => {
|
|
227
|
+
globalModifiers.forEach((globalModifier) => {
|
|
228
|
+
["", ...variants].forEach((variant) => {
|
|
229
|
+
testVariations.push({
|
|
230
|
+
classes: buildClasses({
|
|
231
|
+
baseClass,
|
|
232
|
+
prefixed: [
|
|
233
|
+
variant,
|
|
234
|
+
primaryModifier,
|
|
235
|
+
secondaryModifier,
|
|
236
|
+
],
|
|
237
|
+
unprefixed: [globalModifier],
|
|
238
|
+
}),
|
|
239
|
+
testid: buildTestid([
|
|
240
|
+
testidBase,
|
|
241
|
+
variant,
|
|
242
|
+
[
|
|
243
|
+
primaryModifier,
|
|
244
|
+
secondaryModifier,
|
|
245
|
+
globalModifier,
|
|
246
|
+
]
|
|
247
|
+
.filter(Boolean)
|
|
248
|
+
.join("-"),
|
|
249
|
+
]),
|
|
250
|
+
theme,
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// create standalone modifiers test props
|
|
258
|
+
modifiers?.standalone?.forEach((standaloneModifier) => {
|
|
259
|
+
testVariations.push({
|
|
260
|
+
testid: buildTestid([testidBase, standaloneModifier]),
|
|
261
|
+
classes: buildClasses({
|
|
262
|
+
baseClass,
|
|
263
|
+
prefixed: [standaloneModifier],
|
|
264
|
+
}),
|
|
265
|
+
theme,
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Sorting for readability
|
|
273
|
+
return testVariations.sort((a, b) => a.testid.localeCompare(b.testid));
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Constructs and runs an individual test for a component
|
|
278
|
+
*/
|
|
279
|
+
const runComponentTest = ({
|
|
280
|
+
element,
|
|
281
|
+
testid,
|
|
282
|
+
theme,
|
|
283
|
+
type,
|
|
284
|
+
}: ComponentTestArgs) => {
|
|
285
|
+
const getDescription = (type: TestTypes) => {
|
|
286
|
+
switch (type) {
|
|
287
|
+
case "a11y":
|
|
288
|
+
return "should be accessible";
|
|
289
|
+
case "visual":
|
|
290
|
+
return "should not introduce visual regressions";
|
|
291
|
+
default:
|
|
292
|
+
return "";
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
it(`${type}: ${testid} ${getDescription(type)}`, async () => {
|
|
297
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
298
|
+
await fixture(element);
|
|
299
|
+
const el = screen.getByTestId(testid);
|
|
300
|
+
|
|
301
|
+
document.body.className = "";
|
|
302
|
+
|
|
303
|
+
if (theme?.length) {
|
|
304
|
+
const prefixedThemes = theme.map((t) => `theme-${t}`);
|
|
305
|
+
document.body.classList.add(...prefixedThemes);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (type === "a11y") {
|
|
309
|
+
// TODO add conditional option for high contrast mode to test against AAA
|
|
310
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
311
|
+
await expect(el).to.be.accessible();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (type === "visual") {
|
|
315
|
+
await visualDiff(el, testid);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Constructs and runs tests for a component with a each provided combination
|
|
322
|
+
*/
|
|
323
|
+
const runComponentTests = ({
|
|
324
|
+
baseClass,
|
|
325
|
+
variants = [],
|
|
326
|
+
modifiers,
|
|
327
|
+
options = {
|
|
328
|
+
testColorThemes: true,
|
|
329
|
+
testHighContrast: true,
|
|
330
|
+
includeNullVariant: false,
|
|
331
|
+
includeNullModifier: true,
|
|
332
|
+
},
|
|
333
|
+
attributes,
|
|
334
|
+
children,
|
|
335
|
+
excludedTestids = [],
|
|
336
|
+
skippedTestids = [],
|
|
337
|
+
tag,
|
|
338
|
+
template,
|
|
339
|
+
type,
|
|
340
|
+
}: ComponentTestsArgs) => {
|
|
341
|
+
getComponentTestVariations({
|
|
342
|
+
baseClass,
|
|
343
|
+
variants,
|
|
344
|
+
modifiers,
|
|
345
|
+
options,
|
|
346
|
+
}).forEach(({ testid, classes, theme }) => {
|
|
347
|
+
const allChildren: {
|
|
348
|
+
[key: string]: string;
|
|
349
|
+
} = children ? { ...children } : { default: "" };
|
|
350
|
+
|
|
351
|
+
Object.keys(allChildren).forEach((key) => {
|
|
352
|
+
const testidModified =
|
|
353
|
+
key !== "default" ? `${testid}-${key}` : testid;
|
|
354
|
+
const children = allChildren[key];
|
|
355
|
+
|
|
356
|
+
const shouldSkipTest = excludeOrSkipTest({
|
|
357
|
+
patterns: skippedTestids,
|
|
358
|
+
skip: true,
|
|
359
|
+
testid: testidModified,
|
|
360
|
+
type,
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const shouldExcludeTest = excludeOrSkipTest({
|
|
364
|
+
patterns: excludedTestids,
|
|
365
|
+
testid: testidModified,
|
|
366
|
+
type,
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
if (shouldSkipTest || shouldExcludeTest) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const element = template
|
|
374
|
+
? html`${template({
|
|
375
|
+
testid: testidModified,
|
|
376
|
+
component: buildTestElement({
|
|
377
|
+
attributes: {
|
|
378
|
+
class: classes,
|
|
379
|
+
...attributes,
|
|
380
|
+
},
|
|
381
|
+
children,
|
|
382
|
+
testid: `${testidModified}-nested`,
|
|
383
|
+
tag,
|
|
384
|
+
}),
|
|
385
|
+
})}`
|
|
386
|
+
: buildTestElement({
|
|
387
|
+
attributes: {
|
|
388
|
+
class: classes,
|
|
389
|
+
...attributes,
|
|
390
|
+
},
|
|
391
|
+
children,
|
|
392
|
+
testid: testidModified,
|
|
393
|
+
tag,
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
runComponentTest({
|
|
397
|
+
element,
|
|
398
|
+
testid: testidModified,
|
|
399
|
+
theme,
|
|
400
|
+
type,
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
const matchTestidByPattern = ({
|
|
407
|
+
testid,
|
|
408
|
+
pattern,
|
|
409
|
+
}: {
|
|
410
|
+
testid: string;
|
|
411
|
+
pattern: string | RegExp;
|
|
412
|
+
}): boolean => {
|
|
413
|
+
if (pattern instanceof RegExp) {
|
|
414
|
+
return pattern.test(testid);
|
|
415
|
+
} else {
|
|
416
|
+
return pattern === testid;
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
const excludeOrSkipTest = ({
|
|
421
|
+
patterns,
|
|
422
|
+
skip = false,
|
|
423
|
+
testid,
|
|
424
|
+
type,
|
|
425
|
+
}: {
|
|
426
|
+
patterns: (string | RegExp)[];
|
|
427
|
+
skip?: boolean;
|
|
428
|
+
testid: string;
|
|
429
|
+
type: TestTypes;
|
|
430
|
+
}): boolean => {
|
|
431
|
+
const matchesTest = patterns.some((pattern) => {
|
|
432
|
+
return matchTestidByPattern({ testid, pattern });
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
if (matchesTest && skip) {
|
|
436
|
+
it.skip(`${type}: ${testid} (skipped)`, () => {
|
|
437
|
+
return;
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return matchesTest;
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
export { runComponentTest, runComponentTests };
|
package/lib/tsconfig.json
CHANGED
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/StackExchange/Stacks.git"
|
|
7
7
|
},
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.9.0",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
11
|
"lib"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"main": "./dist/js/stacks.js",
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"style": "./dist/css/stacks.css",
|
|
16
|
-
"less": "./lib/
|
|
16
|
+
"less": "./lib/stacks.less",
|
|
17
17
|
"unpkg": "dist/css/stacks.min.css",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"start": "concurrently -n w: npm:start:*",
|
|
@@ -23,14 +23,15 @@
|
|
|
23
23
|
"start:webpack": "webpack --watch --config ./docs/webpack.config.js",
|
|
24
24
|
"start:eleventy": "cd ./docs && eleventy --serve",
|
|
25
25
|
"test": "web-test-runner",
|
|
26
|
+
"test:a11y": "web-test-runner --group=a11y",
|
|
26
27
|
"test:unit": "web-test-runner --group=unit",
|
|
27
28
|
"test:unit:watch": "web-test-runner --group=unit --watch",
|
|
28
29
|
"test:visual": "web-test-runner --group=visual",
|
|
29
30
|
"test:visual:update": "web-test-runner --group=visual --update-visual-baseline",
|
|
30
31
|
"prepublishOnly": "npm run build",
|
|
31
32
|
"lint": "concurrently -n w: npm:lint:*",
|
|
32
|
-
"lint:ts": "eslint ./lib
|
|
33
|
-
"lint:css": "stylelint ./lib
|
|
33
|
+
"lint:ts": "eslint ./lib/**/*.ts",
|
|
34
|
+
"lint:css": "stylelint ./lib/*",
|
|
34
35
|
"lint:format": "prettier --check ./lib"
|
|
35
36
|
},
|
|
36
37
|
"license": "MIT",
|
|
@@ -39,48 +40,48 @@
|
|
|
39
40
|
"@popperjs/core": "^2.11.6"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
|
-
"@11ty/eleventy": "^
|
|
43
|
+
"@11ty/eleventy": "^2.0.0",
|
|
43
44
|
"@highlightjs/cdn-assets": "^11.7.0",
|
|
44
45
|
"@open-wc/testing": "^3.1.7",
|
|
45
46
|
"@rollup/plugin-commonjs": "^24.0.1",
|
|
46
47
|
"@rollup/plugin-replace": "^5.0.2",
|
|
47
|
-
"@stackoverflow/stacks-editor": "^0.8.
|
|
48
|
-
"@stackoverflow/stacks-icons": "^5.
|
|
49
|
-
"@testing-library/dom": "^
|
|
48
|
+
"@stackoverflow/stacks-editor": "^0.8.6",
|
|
49
|
+
"@stackoverflow/stacks-icons": "^5.3.1",
|
|
50
|
+
"@testing-library/dom": "^9.0.1",
|
|
50
51
|
"@testing-library/user-event": "^14.4.3",
|
|
51
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
52
|
-
"@typescript-eslint/parser": "^5.
|
|
53
|
-
"@web/dev-server-esbuild": "^0.3.
|
|
54
|
-
"@web/dev-server-rollup": "0.
|
|
55
|
-
"@web/test-runner": "^0.15.
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
|
53
|
+
"@typescript-eslint/parser": "^5.54.0",
|
|
54
|
+
"@web/dev-server-esbuild": "^0.3.4",
|
|
55
|
+
"@web/dev-server-rollup": "^0.4.0",
|
|
56
|
+
"@web/test-runner": "^0.15.1",
|
|
56
57
|
"@web/test-runner-playwright": "^0.9.0",
|
|
57
58
|
"@web/test-runner-visual-regression": "^0.7.0",
|
|
58
59
|
"concurrently": "^7.6.0",
|
|
59
|
-
"css-loader": "^6.7.
|
|
60
|
-
"cssnano": "^5.1.
|
|
60
|
+
"css-loader": "^6.7.3",
|
|
61
|
+
"cssnano": "^5.1.15",
|
|
61
62
|
"docsearch.js": "^2.6.3",
|
|
62
63
|
"eleventy-plugin-highlightjs": "^1.1.0",
|
|
63
64
|
"eleventy-plugin-nesting-toc": "^1.3.0",
|
|
64
|
-
"eslint": "^8.
|
|
65
|
-
"eslint-config-prettier": "^8.
|
|
65
|
+
"eslint": "^8.36.0",
|
|
66
|
+
"eslint-config-prettier": "^8.7.0",
|
|
66
67
|
"eslint-plugin-no-unsanitized": "^4.0.2",
|
|
67
|
-
"jquery": "^3.6.
|
|
68
|
+
"jquery": "^3.6.4",
|
|
68
69
|
"less-loader": "^11.1.0",
|
|
69
70
|
"list.js": "^2.3.1",
|
|
70
71
|
"markdown-it": "^13.0.1",
|
|
71
72
|
"mini-css-extract-plugin": "^2.7.2",
|
|
72
73
|
"postcss-less": "^6.0.0",
|
|
73
74
|
"postcss-loader": "^7.0.2",
|
|
74
|
-
"prettier": "^2.8.
|
|
75
|
+
"prettier": "^2.8.4",
|
|
75
76
|
"rollup-plugin-postcss": "^4.0.2",
|
|
76
|
-
"stylelint": "^
|
|
77
|
-
"stylelint-config-recommended": "^
|
|
78
|
-
"stylelint-config-standard": "^
|
|
77
|
+
"stylelint": "^15.3.0",
|
|
78
|
+
"stylelint-config-recommended": "^10.0.1",
|
|
79
|
+
"stylelint-config-standard": "^30.0.1",
|
|
79
80
|
"terser-webpack-plugin": "^5.3.6",
|
|
80
81
|
"ts-loader": "^9.4.2",
|
|
81
|
-
"typescript": "^4.9.
|
|
82
|
-
"webpack": "^5.
|
|
83
|
-
"webpack-cli": "^5.0.
|
|
82
|
+
"typescript": "^4.9.5",
|
|
83
|
+
"webpack": "^5.76.1",
|
|
84
|
+
"webpack-cli": "^5.0.1",
|
|
84
85
|
"webpack-merge": "^5.8.0"
|
|
85
86
|
},
|
|
86
87
|
"browserslist": [
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { ExpandableController } from "./s-expandable-control";
|
|
2
|
-
export { hideModal, ModalController, showModal } from "./s-modal";
|
|
3
|
-
export { hideBanner, BannerController, showBanner } from "./s-banner";
|
|
4
|
-
export { hideToast, ToastController, showToast } from "./s-toast";
|
|
5
|
-
export { TabListController } from "./s-navigation-tablist";
|
|
6
|
-
export { attachPopover, detachPopover, hidePopover, BasePopoverController, PopoverController, showPopover, } from "./s-popover";
|
|
7
|
-
export { TableController } from "./s-table";
|
|
8
|
-
export { setTooltipHtml, setTooltipText, TooltipController } from "./s-tooltip";
|
|
9
|
-
export { UploaderController } from "./s-uploader";
|