@skyux/forms 15.0.0-alpha.8 → 15.0.0-beta.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.
|
@@ -8,6 +8,9 @@ import { SkyIconHarness } from '@skyux/icon/testing';
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Harness for interacting with a character counter indicator component in tests.
|
|
11
|
+
*
|
|
12
|
+
* @deprecated Use `SkyInputBoxHarness` with an input box that sets the
|
|
13
|
+
* `characterLimit` input instead.
|
|
11
14
|
*/
|
|
12
15
|
class SkyCharacterCounterIndicatorHarness extends SkyComponentHarness {
|
|
13
16
|
/**
|
|
@@ -122,6 +125,75 @@ class SkyFormErrorsHarness extends SkyComponentHarness {
|
|
|
122
125
|
}
|
|
123
126
|
}
|
|
124
127
|
|
|
128
|
+
/**
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
async function getCharacterLimitRatio(labelEl) {
|
|
132
|
+
const text = (await labelEl.text()).trim();
|
|
133
|
+
const parts = text.split('/');
|
|
134
|
+
const countText = parts[0]?.trim();
|
|
135
|
+
const limitText = parts[1]?.trim();
|
|
136
|
+
const count = Number(countText);
|
|
137
|
+
const limit = Number(limitText);
|
|
138
|
+
// The label mirrors whatever `characterLimit` coerced to, which allows
|
|
139
|
+
// decimals and negatives, so don't restrict this to digits.
|
|
140
|
+
if (parts.length !== 2 ||
|
|
141
|
+
!countText ||
|
|
142
|
+
!limitText ||
|
|
143
|
+
isNaN(count) ||
|
|
144
|
+
isNaN(limit)) {
|
|
145
|
+
throw new Error(`Expected the character limit label to read "count/limit" but found "${text}".`);
|
|
146
|
+
}
|
|
147
|
+
return { count, limit };
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
async function isOverCharacterLimit(labelEl) {
|
|
153
|
+
return await labelEl.hasClass('sky-error-label');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Setting `characterLimit` on `sky-input-box` used to render a
|
|
158
|
+
* `sky-character-counter-indicator`, but now renders a
|
|
159
|
+
* `sky-input-box-character-limit`. Since `SkyInputBoxHarness.getCharacterCounter()`
|
|
160
|
+
* is public API, it must still return a `SkyCharacterCounterIndicatorHarness`,
|
|
161
|
+
* so this subclass preserves that type while reading the new markup. Delete it
|
|
162
|
+
* when the deprecated character counter component is removed.
|
|
163
|
+
*
|
|
164
|
+
* @internal
|
|
165
|
+
*/
|
|
166
|
+
class SkyInputBoxCharacterCounterIndicatorCompatHarness extends SkyCharacterCounterIndicatorHarness {
|
|
167
|
+
static { this.hostSelector = 'sky-input-box-character-limit'; }
|
|
168
|
+
#getLabel = this.locatorFor('.sky-input-box-character-limit-label');
|
|
169
|
+
async getCharacterCount() {
|
|
170
|
+
return (await getCharacterLimitRatio(await this.#getLabel())).count;
|
|
171
|
+
}
|
|
172
|
+
async getCharacterCountLimit() {
|
|
173
|
+
return (await getCharacterLimitRatio(await this.#getLabel())).limit;
|
|
174
|
+
}
|
|
175
|
+
async isOverLimit() {
|
|
176
|
+
return await isOverCharacterLimit(await this.#getLabel());
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @internal
|
|
182
|
+
*/
|
|
183
|
+
class SkyInputBoxCharacterLimitHarness extends SkyComponentHarness {
|
|
184
|
+
static { this.hostSelector = 'sky-input-box-character-limit'; }
|
|
185
|
+
#getLabel = this.locatorFor('.sky-input-box-character-limit-label');
|
|
186
|
+
async getCharacterCount() {
|
|
187
|
+
return (await getCharacterLimitRatio(await this.#getLabel())).count;
|
|
188
|
+
}
|
|
189
|
+
async getCharacterLimit() {
|
|
190
|
+
return (await getCharacterLimitRatio(await this.#getLabel())).limit;
|
|
191
|
+
}
|
|
192
|
+
async isOverCharacterLimit() {
|
|
193
|
+
return await isOverCharacterLimit(await this.#getLabel());
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
125
197
|
/**
|
|
126
198
|
* Harness for interacting with an input box component in tests.
|
|
127
199
|
*/
|
|
@@ -130,6 +202,7 @@ class SkyInputBoxHarness extends SkyQueryableComponentHarness {
|
|
|
130
202
|
* @internal
|
|
131
203
|
*/
|
|
132
204
|
static { this.hostSelector = 'sky-input-box'; }
|
|
205
|
+
#getCharacterLimit = this.locatorForOptional(SkyInputBoxCharacterLimitHarness);
|
|
133
206
|
#getHintText = this.locatorForOptional('.sky-input-box-hint-text');
|
|
134
207
|
#getLabel = this.locatorForOptional('.sky-control-label');
|
|
135
208
|
#getWrapper = this.locatorFor('.sky-input-box');
|
|
@@ -152,16 +225,46 @@ class SkyInputBoxHarness extends SkyQueryableComponentHarness {
|
|
|
152
225
|
/**
|
|
153
226
|
* Gets the character counter indicator for the input box or throws an error if
|
|
154
227
|
* a character limit is not specified.
|
|
228
|
+
*
|
|
229
|
+
* @deprecated Use `getCharacterCount()`, `getCharacterLimit()`, and
|
|
230
|
+
* `isOverCharacterLimit()` instead. Those methods require the `characterLimit`
|
|
231
|
+
* input, so an input box that projects a `sky-character-counter-indicator` component
|
|
232
|
+
* must migrate to that input first.
|
|
155
233
|
*/
|
|
156
234
|
async getCharacterCounter() {
|
|
157
|
-
const characterCounter = await this.locatorForOptional(new HarnessPredicate(SkyCharacterCounterIndicatorHarness, {
|
|
235
|
+
const characterCounter = (await this.locatorForOptional(new HarnessPredicate(SkyCharacterCounterIndicatorHarness, {
|
|
158
236
|
ancestor: '.sky-input-box-label-wrapper',
|
|
159
|
-
}))()
|
|
237
|
+
}))()) ??
|
|
238
|
+
(await this.locatorForOptional(SkyInputBoxCharacterCounterIndicatorCompatHarness)());
|
|
160
239
|
if (!characterCounter) {
|
|
161
240
|
throw new Error('The input box does not have a character limit specified.');
|
|
162
241
|
}
|
|
163
242
|
return characterCounter;
|
|
164
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Gets the current character count, or throws an error if the input box does
|
|
246
|
+
* not set the `characterLimit` input.
|
|
247
|
+
*/
|
|
248
|
+
async getCharacterCount() {
|
|
249
|
+
const harness = await this.#getCharacterLimitOrThrow();
|
|
250
|
+
return await harness.getCharacterCount();
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Gets the character limit, or throws an error if the input box does not set
|
|
254
|
+
* the `characterLimit` input.
|
|
255
|
+
*/
|
|
256
|
+
async getCharacterLimit() {
|
|
257
|
+
const harness = await this.#getCharacterLimitOrThrow();
|
|
258
|
+
return await harness.getCharacterLimit();
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Whether the character count has exceeded the character limit. Throws an
|
|
262
|
+
* error if the input box does not set the `characterLimit` input.
|
|
263
|
+
*/
|
|
264
|
+
async isOverCharacterLimit() {
|
|
265
|
+
const harness = await this.#getCharacterLimitOrThrow();
|
|
266
|
+
return await harness.isOverCharacterLimit();
|
|
267
|
+
}
|
|
165
268
|
/**
|
|
166
269
|
* Gets a list of status indicator harnesses for errors not automatically
|
|
167
270
|
* handled by input box.
|
|
@@ -297,6 +400,13 @@ class SkyInputBoxHarness extends SkyQueryableComponentHarness {
|
|
|
297
400
|
const host = await this.host();
|
|
298
401
|
return await host.hasClass('sky-form-field-stacked');
|
|
299
402
|
}
|
|
403
|
+
async #getCharacterLimitOrThrow() {
|
|
404
|
+
const characterLimit = await this.#getCharacterLimit();
|
|
405
|
+
if (!characterLimit) {
|
|
406
|
+
throw new Error('The input box does not have a character limit specified.');
|
|
407
|
+
}
|
|
408
|
+
return characterLimit;
|
|
409
|
+
}
|
|
300
410
|
async #getElementTextOrDefault(el) {
|
|
301
411
|
return (await el?.text())?.trim() ?? '';
|
|
302
412
|
}
|
|
@@ -2014,9 +2124,142 @@ class SkyToggleSwitchHarness extends SkyComponentHarness {
|
|
|
2014
2124
|
}
|
|
2015
2125
|
}
|
|
2016
2126
|
|
|
2127
|
+
/**
|
|
2128
|
+
* Harness for interacting with a button component in tests.
|
|
2129
|
+
*/
|
|
2130
|
+
class SkyButtonHarness extends SkyComponentHarness {
|
|
2131
|
+
/**
|
|
2132
|
+
* @internal
|
|
2133
|
+
*/
|
|
2134
|
+
static { this.hostSelector = 'sky-button'; }
|
|
2135
|
+
#getButton = this.locatorForOptional('button');
|
|
2136
|
+
#getAnchor = this.locatorForOptional('a');
|
|
2137
|
+
#getIcon = this.locatorForOptional(SkyIconHarness);
|
|
2138
|
+
#getAnchorOrButton = this.locatorFor('button, a');
|
|
2139
|
+
#getLabelTextLabel = this.locatorForOptional('span');
|
|
2140
|
+
/**
|
|
2141
|
+
* Gets a `HarnessPredicate` that can be used to search for a
|
|
2142
|
+
* `SkyButtonHarness` that meets certain criteria.
|
|
2143
|
+
*/
|
|
2144
|
+
static with(filters) {
|
|
2145
|
+
return SkyButtonHarness.getDataSkyIdPredicate(filters);
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Blurs the button.
|
|
2149
|
+
*/
|
|
2150
|
+
async blur() {
|
|
2151
|
+
await (await this.#getAnchorOrButton())?.blur();
|
|
2152
|
+
}
|
|
2153
|
+
/**
|
|
2154
|
+
* Clicks the button.
|
|
2155
|
+
*/
|
|
2156
|
+
async click() {
|
|
2157
|
+
await (await this.#getAnchorOrButton())?.click();
|
|
2158
|
+
}
|
|
2159
|
+
/**
|
|
2160
|
+
* Focuses the button.
|
|
2161
|
+
*/
|
|
2162
|
+
async focus() {
|
|
2163
|
+
await (await this.#getAnchorOrButton())?.focus();
|
|
2164
|
+
}
|
|
2165
|
+
/**
|
|
2166
|
+
* Gets the button's style.
|
|
2167
|
+
*/
|
|
2168
|
+
async getButtonStyle() {
|
|
2169
|
+
const anchorOrButton = await this.#getAnchorOrButton();
|
|
2170
|
+
const buttonStyles = [
|
|
2171
|
+
'danger',
|
|
2172
|
+
'default',
|
|
2173
|
+
'icon-borderless',
|
|
2174
|
+
'link',
|
|
2175
|
+
'link-inline',
|
|
2176
|
+
'primary',
|
|
2177
|
+
];
|
|
2178
|
+
for (const buttonStyle of buttonStyles) {
|
|
2179
|
+
if (await anchorOrButton?.hasClass(`sky-btn-${buttonStyle}`)) {
|
|
2180
|
+
return buttonStyle;
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
/* istanbul ignore next */
|
|
2184
|
+
throw new Error('Unable to determine button style.');
|
|
2185
|
+
}
|
|
2186
|
+
/**
|
|
2187
|
+
* Gets the button's type.
|
|
2188
|
+
*/
|
|
2189
|
+
async getButtonType() {
|
|
2190
|
+
const button = await this.#getButton();
|
|
2191
|
+
return (await button?.getAttribute('type'));
|
|
2192
|
+
}
|
|
2193
|
+
/**
|
|
2194
|
+
* Gets the button's label text. If the label is set via `labelText` and `labelHidden` is true,
|
|
2195
|
+
* the text will still be returned.
|
|
2196
|
+
*/
|
|
2197
|
+
async getLabelText() {
|
|
2198
|
+
const labelTextLabel = await this.#getLabelTextLabel();
|
|
2199
|
+
if (labelTextLabel) {
|
|
2200
|
+
return await labelTextLabel.text();
|
|
2201
|
+
}
|
|
2202
|
+
return (await this.#getAriaLabel());
|
|
2203
|
+
}
|
|
2204
|
+
/**
|
|
2205
|
+
* Whether the label is hidden. Only supported when using the `labelText` input to set the label.
|
|
2206
|
+
*/
|
|
2207
|
+
async getLabelHidden() {
|
|
2208
|
+
const labelTextLabel = await this.#getLabelTextLabel();
|
|
2209
|
+
return !(await labelTextLabel?.text());
|
|
2210
|
+
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Whether the button is disabled.
|
|
2213
|
+
*/
|
|
2214
|
+
async isDisabled() {
|
|
2215
|
+
const button = await this.#getButton();
|
|
2216
|
+
if (button) {
|
|
2217
|
+
return (await button.getAttribute('disabled')) !== null;
|
|
2218
|
+
}
|
|
2219
|
+
return false;
|
|
2220
|
+
}
|
|
2221
|
+
/**
|
|
2222
|
+
* Whether the button is focused.
|
|
2223
|
+
*/
|
|
2224
|
+
async isFocused() {
|
|
2225
|
+
return await (await this.#getAnchorOrButton()).isFocused();
|
|
2226
|
+
}
|
|
2227
|
+
/**
|
|
2228
|
+
* Gets the name of the displayed icon, or undefined if no icon is displayed.
|
|
2229
|
+
*/
|
|
2230
|
+
async getIconName() {
|
|
2231
|
+
return await (await this.#getIcon())?.getIconName();
|
|
2232
|
+
}
|
|
2233
|
+
/**
|
|
2234
|
+
* Whether the button is a block button.
|
|
2235
|
+
*/
|
|
2236
|
+
async isBlock() {
|
|
2237
|
+
return await (await this.#getAnchorOrButton()).hasClass('sky-btn-block');
|
|
2238
|
+
}
|
|
2239
|
+
/**
|
|
2240
|
+
* Whether the button is displaying a logo. This will return false when no icon
|
|
2241
|
+
* is displayed, even when the logo input is set to true.
|
|
2242
|
+
*/
|
|
2243
|
+
async isLogo() {
|
|
2244
|
+
const iconHost = await (await this.#getIcon())?.host();
|
|
2245
|
+
return !!(await iconHost?.hasClass('sky-btn-block-logo'));
|
|
2246
|
+
}
|
|
2247
|
+
/**
|
|
2248
|
+
* Gets the resolved URL for the current permalink, or undefined if no permalink
|
|
2249
|
+
* is specified.
|
|
2250
|
+
*/
|
|
2251
|
+
async getLink() {
|
|
2252
|
+
const anchor = await this.#getAnchor();
|
|
2253
|
+
return (await anchor?.getAttribute('href')) ?? undefined;
|
|
2254
|
+
}
|
|
2255
|
+
async #getAriaLabel() {
|
|
2256
|
+
return await (await this.#getAnchorOrButton()).getAttribute('aria-label');
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2017
2260
|
/**
|
|
2018
2261
|
* Generated bundle index. Do not edit.
|
|
2019
2262
|
*/
|
|
2020
2263
|
|
|
2021
|
-
export { SkyCharacterCounterIndicatorHarness, SkyCheckboxFixture, SkyCheckboxGroupHarness, SkyCheckboxHarness, SkyCheckboxLabelHarness, SkyFieldGroupHarness, SkyFileAttachmentHarness, SkyFileDropHarness, SkyFileItemHarness, SkyFormErrorHarness, SkyFormErrorsHarness, SkyInputBoxHarness, SkyRadioFixture, SkyRadioGroupHarness, SkyRadioHarness, SkyRadioLabelHarness, SkySelectionBoxGridHarness, SkySelectionBoxHarness, SkyToggleSwitchHarness, provideSkyFileAttachmentTesting };
|
|
2264
|
+
export { SkyButtonHarness, SkyCharacterCounterIndicatorHarness, SkyCheckboxFixture, SkyCheckboxGroupHarness, SkyCheckboxHarness, SkyCheckboxLabelHarness, SkyFieldGroupHarness, SkyFileAttachmentHarness, SkyFileDropHarness, SkyFileItemHarness, SkyFormErrorHarness, SkyFormErrorsHarness, SkyInputBoxHarness, SkyRadioFixture, SkyRadioGroupHarness, SkyRadioHarness, SkyRadioLabelHarness, SkySelectionBoxGridHarness, SkySelectionBoxHarness, SkyToggleSwitchHarness, provideSkyFileAttachmentTesting };
|
|
2022
2265
|
//# sourceMappingURL=skyux-forms-testing.mjs.map
|