+
${shortDescription @context='html'}
\ No newline at end of file
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/accordion/v1/accordion/clientlibs/site/js/accordionview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/accordion/v1/accordion/clientlibs/site/js/accordionview.js
index 0112d8cbca..4ec61913b9 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/accordion/v1/accordion/clientlibs/site/js/accordionview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/accordion/v1/accordion/clientlibs/site/js/accordionview.js
@@ -23,7 +23,7 @@
static DATA_ATTRIBUTE_VISIBLE = 'data-cmp-visible';
_templateHTML = {};
static selectors = {
- self: `.${Accordion.bemBlock}`,
+ self: "[data-" + this.NS + '-is="' + this.IS + '"]',
widget: `.${Accordion.bemBlock}__widget`,
description: `.${Accordion.bemBlock}__longdescription`,
qm: `.${Accordion.bemBlock}__questionmark`,
@@ -684,6 +684,9 @@
}
}
+ // Expose Accordion under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { Accordion: Accordion });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new Accordion({element, formContainer})
}, Accordion.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/button/v1/button/clientlibs/site/js/buttonview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/button/v1/button/clientlibs/site/js/buttonview.js
index 4d84bfcf45..3e333fe9c2 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/button/v1/button/clientlibs/site/js/buttonview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/button/v1/button/clientlibs/site/js/buttonview.js
@@ -71,6 +71,9 @@
}
}
+ // Expose button under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { Button: Button });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new Button({element, formContainer})
}, Button.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkbox/v1/checkbox/checkbox.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkbox/v1/checkbox/checkbox.html
index f5316ce0dc..4f86bf3fd1 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkbox/v1/checkbox/checkbox.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkbox/v1/checkbox/checkbox.html
@@ -41,6 +41,7 @@
id="${checkbox.id}_widget"
title="${checkbox.tooltipVisible ? '' : checkbox.tooltipText}"
name="${checkbox.name}"
+ aria-describedby="${checkbox.id}__errormessage ${checkbox.id}__longdescription ${checkbox.id}__shortdescription"
value="${checkbox.default[0]}"
disabled="${!checkbox.enabled}" />
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkbox/v1/checkbox/clientlibs/site/js/checkboxview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkbox/v1/checkbox/clientlibs/site/js/checkboxview.js
index fe25cf364e..e8353d848d 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkbox/v1/checkbox/clientlibs/site/js/checkboxview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkbox/v1/checkbox/clientlibs/site/js/checkboxview.js
@@ -69,6 +69,10 @@
return this.element.querySelector(CheckBox.selectors.tooltipDiv);
}
}
+
+ // Expose Accordion under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { CheckBox: CheckBox });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new CheckBox({element, formContainer})
}, CheckBox.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkboxgroup/v1/checkboxgroup/clientlibs/site/js/checkboxgroupview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkboxgroup/v1/checkboxgroup/clientlibs/site/js/checkboxgroupview.js
index 9113393f6b..6245a40846 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkboxgroup/v1/checkboxgroup/clientlibs/site/js/checkboxgroupview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/checkboxgroup/v1/checkboxgroup/clientlibs/site/js/checkboxgroupview.js
@@ -187,6 +187,9 @@
}
}
+ // Expose Accordion under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { CheckBoxGroup: CheckBoxGroup });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new CheckBoxGroup({element, formContainer})
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/site/js/formcontainerview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/site/js/formcontainerview.js
index 5e72583210..509e0ab8f0 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/site/js/formcontainerview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/container/v2/container/clientlibs/site/js/formcontainerview.js
@@ -98,4 +98,7 @@
document.addEventListener("DOMContentLoaded", onDocumentReady);
}
+ // Expose form container under v2 for custom extensions
+ FormView.v2 = Object.assign(FormView.v2 || {}, { FormContainer: FormContainerV2 });
+
})();
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerview.js
index 5e1ee4879e..93ad34bcf3 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerview.js
@@ -113,6 +113,9 @@
}
}
+ // Expose date picker under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { DatePicker: DatePicker });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new DatePicker({element, formContainer})
}, DatePicker.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerwidget.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerwidget.js
index 3ad0c18297..7a8a764ae6 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerwidget.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/clientlibs/site/js/datepickerwidget.js
@@ -57,7 +57,7 @@ if (typeof window.DatePickerWidget === 'undefined') {
*/
#defaultOptions = {
yearsPerView: 16,
- width: 433,
+ width: 340,
viewHeight: 248,
locale: {
days: ["S","M","T","W","T","F","S"],
@@ -625,9 +625,8 @@ if (typeof window.DatePickerWidget === 'undefined') {
var self = this,
curDate = new Date(this.currentYear, this.currentMonth),
maxDay = this.#maxDate(this.currentMonth),
- prevMaxDay = this.#maxDate((this.currentMonth + 12) % 12),
+ prevMaxDay = this.#maxDate((this.currentMonth + 11) % 12),
day1 = new Date(this.currentYear, this.currentMonth, 1).getDay(),
- rowsReq = Math.ceil((day1 + maxDay) / 7) + 1,
data, display;
var localizedYear = this.#getLocalizedYear(curDate);
@@ -636,19 +635,22 @@ if (typeof window.DatePickerWidget === 'undefined') {
caption: this.#options.locale.months[this.currentMonth] + ", "
+ this.#convertNumberToLocale(localizedYear),
header: this.#options.locale.days,
- numRows: rowsReq,
+ numRows: 7,
numColumns: 7,
elementAt: function (row, col) {
var day = (row - 1) * 7 + col - day1 + 1;
+ var monthVal = self.currentMonth + 1;
let gridId = "day-" + day;
display = self.#convertNumberToLocale(day);
data = day;
if (day < 1) {
display = self.#convertNumberToLocale(prevMaxDay + day);
- data = -1
+ data = -1;
+ monthVal = self.currentMonth;
} else if (day > maxDay) {
display = self.#convertNumberToLocale(day - maxDay);
data = -1;
+ monthVal = self.currentMonth + 2;
} else {
curDate.setDate(day);
// check if the currentdate is valid based on max and min valid date
@@ -663,7 +665,7 @@ if (typeof window.DatePickerWidget === 'undefined') {
gridId: gridId,
display: display,
ariaLabel: self.#options.editValue(
- self.currentYear + "-" + self.#pad2(self.currentMonth + 1)
+ self.currentYear + "-" + self.#pad2(monthVal)
+ "-" + self.#pad2(display))
};
}
@@ -856,20 +858,6 @@ if (typeof window.DatePickerWidget === 'undefined') {
}
this.insertRow(r++, row, false, options.elementAt);
}
-
- rows = this["$" + this.view.toLowerCase()].querySelectorAll("ul");
- rows = [...rows].filter((r) => {
- return !(r.offsetHeight === 0 && r.offsetWidth === 0)
- });
- let len = rows.length;
- while (len > options.numRows) {
- this["$" + this.view.toLowerCase()].querySelectorAll(
- "ul")[--len].style.display = "none";
- }
- while (options.numRows > len) {
- this["$" + this.view.toLowerCase()].querySelectorAll(
- "ul")[len++].style.display = "flex";
- }
}
#hotKeysCallBack = this.#hotKeys.bind(this);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/datepicker.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/datepicker.html
index 4326e7e89d..b8a799f274 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/datepicker.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/datepicker/v1/datepicker/datepicker.html
@@ -46,6 +46,7 @@
title="${datePicker.tooltipVisible ? '' : datePicker.tooltipText}"
id="${widgetId}"
placeholder="${datePicker.placeHolder}"
+ aria-describedby="${datePicker.id}__errormessage ${datePicker.id}__longdescription ${datePicker.id}__shortdescription"
min="${datePicker.minimumDate}"
max="${datePicker.maximumDate}"/>
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown/clientlibs/site/js/dropdownview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown/clientlibs/site/js/dropdownview.js
index 3c3e57e686..012baad432 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown/clientlibs/site/js/dropdownview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown/clientlibs/site/js/dropdownview.js
@@ -230,6 +230,9 @@
}
}
+ // Expose drop down under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { DropDown: DropDown });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new DropDown({element, formContainer})
}, DropDown.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown/dropdown.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown/dropdown.html
index 591f4509dc..0d9abef0c0 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown/dropdown.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/dropdown/v1/dropdown/dropdown.html
@@ -43,10 +43,11 @@
data-cmp-data-layer="${dropdown.data.json}"
disabled="${!dropdown.enabled || dropdown.readOnly}"
required="${dropdown.required}"
+ aria-describedby="${dropdown.id}__errormessage ${dropdown.id}__longdescription ${dropdown.id}__shortdescription"
data-sly-attribute.multiple="${dropdown.isMultiSelect ? 'multiple' : ''}"
aria-readonly="${dropdown.readOnly ? 'true' : ''}">
-
+
${dropdown.placeHolder}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/emailinput/v1/emailinput/clientlibs/site/js/emailinputview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/emailinput/v1/emailinput/clientlibs/site/js/emailinputview.js
index 81282127e8..3dbfe0831b 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/emailinput/v1/emailinput/clientlibs/site/js/emailinputview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/emailinput/v1/emailinput/clientlibs/site/js/emailinputview.js
@@ -82,6 +82,9 @@
}
}
+ // Expose email input under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { EmailInput: EmailInput });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new EmailInput({element, formContainer})
}, EmailInput.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/emailinput/v1/emailinput/emailinput.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/emailinput/v1/emailinput/emailinput.html
index b352146248..513e5df8bd 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/emailinput/v1/emailinput/emailinput.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/emailinput/v1/emailinput/emailinput.html
@@ -50,6 +50,7 @@
autocomplete="${email.autoComplete}"
minlength="${email.minLength}"
maxlength="${email.maxLength}"
+ aria-describedby="${email.id}__errormessage ${email.id}__longdescription ${email.id}__shortdescription"
dir="auto"/>
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v1/fileinput/clientlibs/site/js/fileinputview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v1/fileinput/clientlibs/site/js/fileinputview.js
index 3d3e7c3ac7..a9e52e92c6 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v1/fileinput/clientlibs/site/js/fileinputview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v1/fileinput/clientlibs/site/js/fileinputview.js
@@ -103,6 +103,9 @@
}
}
+ // Expose file input under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { FileInput: FileInput });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new FileInput({element, formContainer})
}, FileInput.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v1/fileinput/fileinput.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v1/fileinput/fileinput.html
index 60659eb879..c170dea080 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v1/fileinput/fileinput.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v1/fileinput/fileinput.html
@@ -35,7 +35,7 @@
-
${file.buttonText}
+
${file.buttonText}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v2/fileinput/clientlibs/site/js/fileinputview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v2/fileinput/clientlibs/site/js/fileinputview.js
index bb960bd88a..3519f77d60 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v2/fileinput/clientlibs/site/js/fileinputview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v2/fileinput/clientlibs/site/js/fileinputview.js
@@ -108,6 +108,9 @@
}
}
+ // Expose file input under v2 for custom extensions
+ FormView.v2 = Object.assign(FormView.v2 || {}, { FileInput: FileInputV2 });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new FileInputV2({element, formContainer})
}, FileInputV2.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v2/fileinput/fileinput.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v2/fileinput/fileinput.html
index 2e3ed88afe..650c08639e 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v2/fileinput/fileinput.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fileinput/v2/fileinput/fileinput.html
@@ -39,7 +39,7 @@
${file.dragDropText @context='html'}
-
${file.buttonText}
+
${file.buttonText}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/clientlibs/site/js/fragmentview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/clientlibs/site/js/fragmentview.js
index 4781333fbc..32e19973ba 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/clientlibs/site/js/fragmentview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/fragment/v1/fragment/clientlibs/site/js/fragmentview.js
@@ -66,6 +66,9 @@
}
}
+ // Expose Fragment under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { Fragment: Fragment });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new Fragment({element, formContainer})
}, Fragment.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/image/v1/image/clientlibs/site/js/imageview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/image/v1/image/clientlibs/site/js/imageview.js
index b18df4d4b3..a5364086cb 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/image/v1/image/clientlibs/site/js/imageview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/image/v1/image/clientlibs/site/js/imageview.js
@@ -61,7 +61,10 @@
setFocus() {
this.setActive();
}
- }
+ }
+
+ // Expose Image under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { Image: Image });
FormView.Utils.setupField(({element, formContainer}) => {
return new Image({element, formContainer})
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/numberinput/v1/numberinput/clientlibs/site/js/numberinputview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/numberinput/v1/numberinput/clientlibs/site/js/numberinputview.js
index 057ca8dbb8..79c19e6892 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/numberinput/v1/numberinput/clientlibs/site/js/numberinputview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/numberinput/v1/numberinput/clientlibs/site/js/numberinputview.js
@@ -111,6 +111,9 @@
}
}
+ // Expose NumberInput under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { NumberInput: NumberInput });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new NumberInput({element,formContainer})
}, NumberInput.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/numberinput/v1/numberinput/numberinput.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/numberinput/v1/numberinput/numberinput.html
index d1cf01778c..b466cc152a 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/numberinput/v1/numberinput/numberinput.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/numberinput/v1/numberinput/numberinput.html
@@ -49,6 +49,7 @@
disabled="${!numberinput.enabled}"
readonly="${numberinput.readOnly}"
required="${numberinput.required}"
+ aria-describedby="${numberinput.id}__errormessage ${numberinput.id}__longdescription ${numberinput.id}__shortdescription"
placeholder="${numberinput.placeHolder}"
dir="auto"/>
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/.content.xml
similarity index 100%
rename from ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/.content.xml
rename to ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/.content.xml
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/css.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/css.txt
similarity index 100%
rename from ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/css.txt
rename to ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/css.txt
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/css/panelcontainerview.css b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/css/panelcontainerview.css
similarity index 100%
rename from ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/css/panelcontainerview.css
rename to ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/css/panelcontainerview.css
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/js.txt b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/js.txt
similarity index 100%
rename from ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/js.txt
rename to ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/js.txt
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/js/panelcontainerview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/js/panelcontainerview.js
similarity index 98%
rename from ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/js/panelcontainerview.js
rename to ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/js/panelcontainerview.js
index e2922ef795..e837cc3b0b 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/runtime/js/panelcontainerview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/panelcontainer/v1/panelcontainer/clientlibs/site/js/panelcontainerview.js
@@ -181,6 +181,9 @@
}
}
+ // Expose panel under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { Panel: Panel });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new Panel({element, formContainer})
}, Panel.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/radiobutton/v1/radiobutton/clientlibs/site/js/radiobuttonview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/radiobutton/v1/radiobutton/clientlibs/site/js/radiobuttonview.js
index 74665a1267..677a989af9 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/radiobutton/v1/radiobutton/clientlibs/site/js/radiobuttonview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/radiobutton/v1/radiobutton/clientlibs/site/js/radiobuttonview.js
@@ -116,10 +116,8 @@
widgets.forEach(widget => {
if (readonly === true) {
widget.setAttribute(FormView.Constants.HTML_ATTRS.DISABLED, "disabled");
- widget.setAttribute("aria-readonly", true);
} else {
- widget.removeAttribute(FormView.Constants.HTML_ATTRS.DISABLED);
- widget.removeAttribute("aria-readonly");
+ widget.removeAttribute(FormView.Constants.HTML_ATTRS.DISABLED);
}
});
}
@@ -168,6 +166,9 @@
}
}
+ // Expose RadioButton under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { RadioButton: RadioButton });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new RadioButton({element, formContainer});
}, RadioButton.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/radiobutton/v1/radiobutton/radiobutton.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/radiobutton/v1/radiobutton/radiobutton.html
index 9a4ff8090e..e0541d7c30 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/radiobutton/v1/radiobutton/radiobutton.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/radiobutton/v1/radiobutton/radiobutton.html
@@ -48,8 +48,8 @@
value="${item.toString}"
disabled="${!radioButton.enabled || radioButton.readOnly}"
checked="${radioButton.enums[itemList.index] == radioButton.default[0]}"
- aria-readonly="${radioButton.readOnly ? 'true' : ''}"/>
- ${radioButton.enumNames[itemList.index] @ context = 'html'}
+ aria-describedby="${radioButton.id}__errormessage ${radioButton.id}__longdescription ${radioButton.id}__shortdescription"/>
+ ${radioButton.enumNames[itemList.index]}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/recaptcha/v1/recaptcha/clientlibs/site/js/recaptchaview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/recaptcha/v1/recaptcha/clientlibs/site/js/recaptchaview.js
index e22ab905f3..16c92383dc 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/recaptcha/v1/recaptcha/clientlibs/site/js/recaptchaview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/recaptcha/v1/recaptcha/clientlibs/site/js/recaptchaview.js
@@ -76,7 +76,10 @@
}
}
}
-}
+ }
+
+ // Expose Recaptcha under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { Recaptcha: Recaptcha });
FormView.Utils.setupField(({element, formContainer}) => {
return new Recaptcha({element, formContainer})
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/switch/v1/switch/clientlibs/site/js/switchview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/switch/v1/switch/clientlibs/site/js/switchview.js
index 3dda6a6674..3dff653164 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/switch/v1/switch/clientlibs/site/js/switchview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/switch/v1/switch/clientlibs/site/js/switchview.js
@@ -66,6 +66,9 @@
}
}
+ // Expose Switch under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { Switch: Switch });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new Switch({element,formContainer})
}, Switch.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/switch/v1/switch/switch.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/switch/v1/switch/switch.html
index 4565b72af5..3f8abdeffd 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/switch/v1/switch/switch.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/switch/v1/switch/switch.html
@@ -48,6 +48,7 @@
aria-label="${switch.label.value}"
disabled="${!switch.enabled || switch.readOnly}"
value="${switch.default}"
+ aria-describedby="${switch.id}__errormessage ${switch.id}__longdescription ${switch.id}__shortdescription"
aria-readonly="${switch.readOnly ? 'true' : ''}">
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/textinput/v1/textinput/clientlibs/site/js/textinputview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/textinput/v1/textinput/clientlibs/site/js/textinputview.js
index 183b2fe4db..e06e7fdc31 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/textinput/v1/textinput/clientlibs/site/js/textinputview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/textinput/v1/textinput/clientlibs/site/js/textinputview.js
@@ -82,6 +82,9 @@
}
}
+ // Expose TextInput under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { TextInput: TextInput });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new TextInput({element, formContainer})
}, TextInput.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/textinput/v1/textinput/textinput.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/textinput/v1/textinput/textinput.html
index 23e41392be..8a4b1f4611 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/textinput/v1/textinput/textinput.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/textinput/v1/textinput/textinput.html
@@ -48,6 +48,7 @@
placeholder="${text.placeHolder}"
autocomplete="${text.autoComplete}"
minlength="${text.minLength}"
+ aria-describedby="${text.id}__errormessage ${text.id}__longdescription ${text.id}__shortdescription"
maxlength="${text.maxLength}">
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/toggleablelink/v1/toggleablelink/widget.html b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/toggleablelink/v1/toggleablelink/widget.html
index 603b395347..cff074917f 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/toggleablelink/v1/toggleablelink/widget.html
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/toggleablelink/v1/toggleablelink/widget.html
@@ -25,6 +25,7 @@
value="${checkboxgroup.enums[itemList.index].toString}"
checked="${checkboxgroup.enums[itemList.index] in checkboxgroup.default }"
disabled="${!checkboxgroup.enabled || checkboxgroup.readOnly}"
+ aria-describedby="${checkboxgroup.id}__errormessage ${checkboxgroup.id}__longdescription ${checkboxgroup.id}__shortdescription"
aria-readonly="${checkboxgroup.readOnly ? 'true' : ''}"/>
${checkboxgroup.enumNames[itemList.index] @ context = 'html'}
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/verticaltabs/v1/verticaltabs/clientlibs/site/js/verticaltabs.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/verticaltabs/v1/verticaltabs/clientlibs/site/js/verticaltabs.js
index b48dc5c860..9a88810f43 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/verticaltabs/v1/verticaltabs/clientlibs/site/js/verticaltabs.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/verticaltabs/v1/verticaltabs/clientlibs/site/js/verticaltabs.js
@@ -91,6 +91,9 @@
}
}
+ // Expose VerticalTabs under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { VerticalTabs: VerticalTabs });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new VerticalTabs({element, formContainer})
}, VerticalTabs.selectors.self);
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/wizard/v1/wizard/clientlibs/site/js/wizardview.js b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/wizard/v1/wizard/clientlibs/site/js/wizardview.js
index c86095258a..6c59e307e4 100644
--- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/wizard/v1/wizard/clientlibs/site/js/wizardview.js
+++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/wizard/v1/wizard/clientlibs/site/js/wizardview.js
@@ -638,6 +638,9 @@
}
}
+ // Expose Wizard under v1 for custom extensions
+ FormView.v1 = Object.assign(FormView.v1 || {}, { Wizard: Wizard });
+
FormView.Utils.setupField(({element, formContainer}) => {
return new Wizard({element, formContainer})
}, Wizard.selectors.self);
diff --git a/ui.frontend/src/constants.js b/ui.frontend/src/constants.js
index 382cef69c7..c2b44d641d 100644
--- a/ui.frontend/src/constants.js
+++ b/ui.frontend/src/constants.js
@@ -345,6 +345,13 @@ export const Constants = {
*/
TABINDEX : "tabindex",
+ /**
+ * Aria Current attribute.
+ * @type {string}
+ */
+ ARIA_CURRENT : "aria-current",
+
+
/**
* Prefix path for all AF HTTP APIs.
* @type {string}
diff --git a/ui.frontend/src/utils.js b/ui.frontend/src/utils.js
index 096c2c6630..4e79628b25 100644
--- a/ui.frontend/src/utils.js
+++ b/ui.frontend/src/utils.js
@@ -36,11 +36,17 @@ class Utils {
*/
static #contextPath = "";
/**
- * The array of field creator sets.
+ * Object of field creator sets.
* @private
- * @type {Object[]}
*/
- static #fieldCreatorSets = [];
+ static #fieldCreatorSets = {};
+ /**
+ * The array of field creator order.
+ * This is to store the insertion order
+ * @private
+ * @type {String[]}
+ */
+ static #fieldCreatorOrder = [];
/**
* Returns the data attributes of the specific element.
@@ -136,7 +142,8 @@ class Utils {
* @param {module:FormView~FormContainer} formContainer - The form container.
*/
static createFieldsForAddedElement(addedElement, formContainer) {
- Utils.#fieldCreatorSets.forEach(function (fieldCreatorSet) {
+ Object.values(Utils.#fieldCreatorOrder).forEach(function (fieldSelector) {
+ let fieldCreatorSet = Utils.#fieldCreatorSets[fieldSelector];
const fieldElements = addedElement.querySelectorAll(fieldCreatorSet['fieldSelector']);
Utils.#createFormContainerFields(fieldElements, fieldCreatorSet['fieldCreator'], formContainer);
});
@@ -149,21 +156,28 @@ class Utils {
* @param {string} fieldClass - The data attribute to read the field data from.
*/
static setupField(fieldCreator, fieldSelector, fieldClass) {
- const onInit = (e) => {
- console.debug("FormContainerInitialised Received", e.detail);
- let formContainer = e.detail;
- let fieldElements = document.querySelectorAll(fieldSelector);
- Utils.#createFormContainerFields(fieldElements, fieldCreator, formContainer);
- Utils.registerMutationObserver(formContainer, fieldCreator, fieldSelector, fieldClass);
+ // there should be only one view for each fieldSelector in case of multiple view registrations in case of extension
+ // if customer needs to create two views for each field selector, they need to do it via themservles
+ if (!(fieldSelector in Utils.#fieldCreatorSets)) {
+ Utils.#fieldCreatorOrder.push(fieldSelector);
}
- Utils.#fieldCreatorSets.push({
+ Utils.#fieldCreatorSets[fieldSelector] = {
fieldCreator,
fieldSelector,
fieldClass
- });
- document.addEventListener(Constants.FORM_CONTAINER_INITIALISED, onInit);
+ };
}
+ static initializeAllFields(formContainer) {
+ console.debug("Initializing field views ", formContainer);
+ Object.values(Utils.#fieldCreatorOrder).forEach(function (fieldSelectorInCreator) {
+ const {fieldSelector, fieldCreator, fieldClass} = Utils.#fieldCreatorSets[fieldSelectorInCreator];
+ console.debug("Initializing all fields of field selector ", fieldSelector);
+ let fieldElements = document.querySelectorAll(fieldSelector);
+ Utils.#createFormContainerFields(fieldElements, fieldCreator, formContainer);
+ Utils.registerMutationObserver(formContainer, fieldCreator, fieldSelector, fieldClass);
+ });
+ }
/**
* Removes field reference from form container.
* @private
@@ -219,8 +233,24 @@ class Utils {
*/
static updateId(htmlElement, oldId, newId) {
let elementWithId = htmlElement.querySelectorAll("#" + oldId)[0];
+ let errorElementWithId = htmlElement.querySelector("#" + `${oldId}__errormessage`);
+ let elementWithDescId = htmlElement.querySelector("#" + `${oldId}-widget`);
+ let elementWithShortDescId = htmlElement.querySelector("#" + `${oldId}__shortdescription`);
+ let elementWithLongDescId = htmlElement.querySelector("#" + `${oldId}__longdescription`);
if (elementWithId) {
elementWithId.id = newId;
+ };
+ if (errorElementWithId) {
+ errorElementWithId.id = newId;
+ };
+ if (elementWithDescId) {
+ elementWithDescId.id = newId;
+ };
+ if (elementWithShortDescId) {
+ elementWithShortDescId.id = newId;
+ };
+ if (elementWithLongDescId) {
+ elementWithLongDescId.id = newId;
}
}
@@ -310,6 +340,7 @@ class Utils {
_path,
_element: elements[i]
});
+ Utils.initializeAllFields(formContainer);
const event = new CustomEvent(Constants.FORM_CONTAINER_INITIALISED, { "detail": formContainer });
document.dispatchEvent(event);
}
diff --git a/ui.frontend/src/view/FormFieldBase.js b/ui.frontend/src/view/FormFieldBase.js
index c6cbf8c578..1b34cdd427 100644
--- a/ui.frontend/src/view/FormFieldBase.js
+++ b/ui.frontend/src/view/FormFieldBase.js
@@ -389,7 +389,6 @@ class FormFieldBase extends FormField {
*/
updateReadOnly(readOnly, state) {
if (this.widget) {
- this.toggle(readOnly, "readonly");
this.element.setAttribute(Constants.DATA_ATTRIBUTE_READONLY, readOnly);
if (readOnly === true) {
this.widget.setAttribute("readonly", "readonly");
diff --git a/ui.frontend/src/view/FormTabs.js b/ui.frontend/src/view/FormTabs.js
index 5d25618784..650133ea9e 100644
--- a/ui.frontend/src/view/FormTabs.js
+++ b/ui.frontend/src/view/FormTabs.js
@@ -112,12 +112,14 @@ class FormTabs extends FormPanel {
tabs[i].classList.add(this.#_selectors.active.tab);
tabs[i].setAttribute(Constants.ARIA_SELECTED, true);
tabs[i].setAttribute(Constants.TABINDEX, "0");
+ tabs[i].setAttribute(Constants.ARIA_CURRENT, "true");
} else {
tabpanels[i].classList.remove(this.#_selectors.active.tabpanel);
tabpanels[i].setAttribute(Constants.ARIA_HIDDEN, true);
tabs[i].classList.remove(this.#_selectors.active.tab);
tabs[i].setAttribute(Constants.ARIA_SELECTED, false);
tabs[i].setAttribute(Constants.TABINDEX, "-1");
+ tabs[i].setAttribute(Constants.ARIA_CURRENT, "false");
}
}
}
diff --git a/ui.tests/test-module/specs/checkbox/checkbox.runtime.spec.js b/ui.tests/test-module/specs/checkbox/checkbox.runtime.spec.js
index e9810c5fd4..496ae9f74f 100644
--- a/ui.tests/test-module/specs/checkbox/checkbox.runtime.spec.js
+++ b/ui.tests/test-module/specs/checkbox/checkbox.runtime.spec.js
@@ -113,7 +113,7 @@ describe("Form Runtime with CheckBox Input", () => {
})
});
- it(" should show error messages in the HTML ", () => {
+ it(" should show error messages in the HTML", () => {
const [id, fieldView] = Object.entries(formContainer._fields)[2]
const model = formContainer._model.getElement(id)
@@ -123,6 +123,8 @@ describe("Form Runtime with CheckBox Input", () => {
cy.get(`#${id}`).find("input").click().then(x => {
cy.get(`#${id}`).find(".cmp-adaptiveform-checkbox__errormessage").should('have.text',"This is a custom required checkbox")
+ cy.get(`#${id} > div.${bemBlock}__errormessage`).should('have.attr', 'id', `${id}__errormessage`)
+ cy.get(`#${id} > .${bemBlock}__widget-container > .${bemBlock}__widget`).should('have.attr', 'aria-describedby', `${id}__errormessage ${id}__longdescription ${id}__shortdescription`)
})
cy.get(`#${id}`).find("input").click().then(x => {
diff --git a/ui.tests/test-module/specs/customization/customtextinput.runtime.spec.js b/ui.tests/test-module/specs/customization/customtextinput.runtime.spec.js
new file mode 100644
index 0000000000..e03204c290
--- /dev/null
+++ b/ui.tests/test-module/specs/customization/customtextinput.runtime.spec.js
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright 2022 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+describe("Form Runtime with Custom Text Input", () => {
+
+ before(() => {
+ cy.attachConsoleErrorSpy();
+ });
+
+ const pagePath = "content/forms/af/core-components-it/samples/textinput/custom.html"
+ const bemBlock = 'cmp-adaptiveform-textinput'
+ const IS = "adaptiveFormTextInput"
+ const selectors = {
+ textinput : `[data-cmp-is="${IS}"]`
+ }
+
+ let formContainer = null
+ let toggle_array = [];
+
+ beforeEach(() => {
+ cy.previewForm(pagePath).then(p => {
+ formContainer = p;
+ })
+ cy.fetchFeatureToggles().then((response) => {
+ if (response.status === 200) {
+ toggle_array = response.body.enabled;
+ }
+ });
+ });
+
+ const checkHTML = (id, state) => {
+ const visible = state.visible;
+ const passVisibleCheck = `${visible === true ? "" : "not."}be.visible`;
+ const passDisabledAttributeCheck = `${state.enabled === false ? "" : "not."}have.attr`;
+ const value = state.value == null ? '' : state.value;
+ cy.get(`#${id}`)
+ .should(passVisibleCheck)
+ .invoke('attr', 'data-cmp-visible')
+ .should('eq', visible.toString());
+ cy.get(`#${id}`)
+ .invoke('attr', 'data-cmp-enabled')
+ .should('eq', state.enabled.toString());
+ return cy.get(`#${id}`).within((root) => {
+ cy.get('*').should(passVisibleCheck)
+ cy.get('input')
+ .should(passDisabledAttributeCheck, 'disabled');
+ cy.get('input').should('have.value', value)
+ })
+ }
+
+ it(" should get model and view initialized properly ", () => {
+ expect(formContainer, "formcontainer is initialized").to.not.be.null;
+ expect(formContainer._model.items.length, "model and view elements match").to.equal(Object.keys(formContainer._fields).length);
+ Object.entries(formContainer._fields).forEach(([id, field]) => {
+ if(field.options.visible === "true") {
+ expect(field.getId()).to.equal(id)
+ expect(formContainer._model.getElement(id), `model and view are in sync`).to.equal(field.getModel())
+ checkHTML(id, field.getModel().getState())
+ }
+ });
+ cy.expectNoConsoleErrors();
+ })
+
+ it(" model's changes are reflected in the html ", () => {
+ const [id, fieldView] = Object.entries(formContainer._fields)[0]
+ const model = formContainer._model.getElement(id)
+ model.value = "some other value"
+ checkHTML(model.id, model.getState()).then(() => {
+ model.visible = false
+ return checkHTML(model.id, model.getState())
+ }).then(() => {
+ model.enabled = false
+ return checkHTML(model.id, model.getState())
+ })
+ cy.expectNoConsoleErrors();
+ });
+
+ it(" html changes are reflected in model ", () => {
+ const [id, fieldView] = Object.entries(formContainer._fields)[0]
+ const model = formContainer._model.getElement(id)
+ const input = "value"
+ cy.get(`#${id}`).find("input").clear().type(input).blur().then(x => {
+ expect(model.getState().value).to.equal(input)
+ })
+ cy.expectNoConsoleErrors();
+ });
+
+ it("should toggle description and tooltip", () => {
+ cy.toggleDescriptionTooltip(bemBlock, 'tooltip_scenario_test');
+ })
+
+
+ it("should show different default error messages on different constraints only on click of submit button", () => {
+ const [textbox1, textBox1FieldView] = Object.entries(formContainer._fields)[0];
+ const [textbox6, textBox6FieldView] = Object.entries(formContainer._fields)[5];
+ const [textbox7, textBox7FieldView] = Object.entries(formContainer._fields)[6];
+ const [textbox8, textBox8FieldView] = Object.entries(formContainer._fields)[7];
+
+ const [submitbutton1, fieldView] = Object.entries(formContainer._fields)[11];
+
+ // Required field should not show error on blur due to custom text field
+ cy.get(`#${textbox6}`).find("input").focus().clear().type("abc").blur().then(x => {
+ cy.get(`#${textbox6}`).find(".cmp-adaptiveform-textinput__errormessage").should('have.text',"")
+ })
+
+ // Click the submit button
+ cy.get(`#${submitbutton1}`).find("button").click();
+
+ cy.get(`#${textbox7}`).find("input").then(x => {
+ cy.get(`#${textbox7}`).find(".cmp-adaptiveform-textinput__errormessage").should('have.text',"Please shorten this text to 20 characters or less.")
+ })
+
+ cy.get(`#${textbox8}`).find("input").then(x => {
+ cy.get(`#${textbox8}`).find(".cmp-adaptiveform-textinput__errormessage").should('have.text',"Please lengthen this text to 12 characters or more.")
+ })
+ debugger;
+ cy.get(`#${textbox6}`).find("input").focus().clear().blur().then(x => {
+ cy.get(`#${textbox6}`).find(".cmp-adaptiveform-textinput__errormessage").should('have.text',"Please fill in this field.")
+ })
+
+ cy.expectNoConsoleErrors();
+
+ })
+
+})
\ No newline at end of file
diff --git a/ui.tests/test-module/specs/datepicker/datepicker.runtime.layout.spec.js b/ui.tests/test-module/specs/datepicker/datepicker.runtime.layout.spec.js
new file mode 100644
index 0000000000..ba57542199
--- /dev/null
+++ b/ui.tests/test-module/specs/datepicker/datepicker.runtime.layout.spec.js
@@ -0,0 +1,364 @@
+/*******************************************************************************
+ * Copyright 2024 Adobe
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **************************o****************************************************/
+describe("Form Runtime layout of Date Picker ", () => {
+
+ const pagePath = "content/forms/af/core-components-it/samples/datepicker/datepickerlayoutissue.html"
+ const bemBlock = 'cmp-adaptiveform-datepicker'
+
+ let formContainer = null
+
+ beforeEach(() => {
+ cy.previewForm(pagePath).then(p => {
+ formContainer = p;
+ })
+ });
+
+ const checkHTML = (id, state, displayValue) => {
+ const visible = state.visible;
+ const passVisibleCheck = `${visible === true ? "" : "not."}be.visible`;
+ const passDisabledAttributeCheck = `${state.enabled === false ? "" : "not."}have.attr`;
+ const passReadOnlyAttributeCheck = `${state.readOnly === true ? "" : "not."}have.attr`;
+ const value = state.value == null ? '' : state.value;
+ cy.get(`#${id}`)
+ .should(passVisibleCheck)
+ .invoke('attr', 'data-cmp-visible')
+ .should('eq', visible.toString());
+ cy.get(`#${id}`)
+ .invoke('attr', 'data-cmp-enabled')
+ .should('eq', state.enabled.toString());
+ return cy.get(`#${id}`).within((root) => {
+ cy.get('*').should(passVisibleCheck)
+ cy.get('input')
+ .should(passDisabledAttributeCheck, 'disabled');
+ cy.get('input').should(passReadOnlyAttributeCheck, 'readonly');
+ cy.get('input').should('have.value', value)
+ })
+ }
+
+ it(" should get model and view initialized properly ", () => {
+ expect(formContainer, "formcontainer is initialized").to.not.be.null;
+ expect(formContainer._model.items.length, "model and view elements match").to.equal(Object.keys(formContainer._fields).length);
+ Object.entries(formContainer._fields).forEach(([id, field]) => {
+ expect(field.getId()).to.equal(id)
+ expect(formContainer._model.getElement(id), `model and view are in sync`).to.equal(field.getModel())
+ // if non submit field, check that all have error message in them
+ if (id.indexOf('submit') === -1) {
+ checkHTML(id, field.getModel().getState())
+ }
+ });
+ })
+
+ it(" model's changes are reflected in the html ", () => {
+ const [datePicker7, datePicker7FieldView] = Object.entries(formContainer._fields)[0];
+ const model = formContainer._model.getElement(datePicker7)
+
+ const date = '2023-08-10';
+ cy.get(`#${datePicker7}`).find("input").clear().type(date).then(() => {
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Thursday, 10 August, 2023");
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get("#li-day-3").should("be.visible").click(); // clicking on the 2nd day of the month of October 2023
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Wednesday, 2 August, 2023");
+ cy.get(`#${datePicker7}`).find("input").focus().should("have.value", "Wednesday, 2 August, 2023");
+
+ });
+ });
+
+ it("Check for Feb month with 28 days starting on Sunday", () => {
+ const [datePicker7, datePicker7FieldView] = Object.entries(formContainer._fields)[0];
+ const model = formContainer._model.getElement(datePicker7)
+
+ const date = '2026-02-01';
+ cy.get(`#${datePicker7}`).find("input").clear().type(date);
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ cy.get("#li-day-2").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Sunday, 1 February, 2026");
+ });
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get("#li-day-29").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Saturday, 28 February, 2026");
+ });
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get(".dp-rightnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+ cy.get(".dp-leftnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+
+
+ });
+
+ });
+
+ it("Check for Feb month with 29 days starting on Sunday", () => {
+ const [datePicker7, datePicker7FieldView] = Object.entries(formContainer._fields)[0];
+ const model = formContainer._model.getElement(datePicker7)
+
+ const date = '2032-02-01';
+ cy.get(`#${datePicker7}`).find("input").clear().type(date);
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ cy.get("#li-day-2").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Sunday, 1 February, 2032");
+ });
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get("#li-day-30").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Sunday, 29 February, 2032");
+ });
+ });
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get(".dp-rightnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+ cy.get(".dp-leftnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+
+
+ });
+ });
+
+
+ it("Check for Feb month with 28 days starting on Saturday", () => {
+ const [datePicker7, datePicker7FieldView] = Object.entries(formContainer._fields)[0];
+ const model = formContainer._model.getElement(datePicker7)
+
+ const date = '2025-02-01';
+ cy.get(`#${datePicker7}`).find("input").clear().type(date);
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ cy.get("#li-day-2").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Saturday, 1 February, 2025");
+ });
+
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get("#li-day-29").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Friday, 28 February, 2025");
+ });
+ });
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get(".dp-rightnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+ cy.get(".dp-leftnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+
+ });
+ });
+
+ it("Check for Feb month with 29 days starting on Saturday", () => {
+ const [datePicker7, datePicker7FieldView] = Object.entries(formContainer._fields)[0];
+ const model = formContainer._model.getElement(datePicker7)
+
+ const date = '2020-02-01';
+ cy.get(`#${datePicker7}`).find("input").clear().type(date);
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ cy.get("#li-day-2").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Saturday, 1 February, 2020");
+ });
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get("#li-day-30").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Saturday, 29 February, 2020");
+ });
+ });
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get(".dp-rightnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+ cy.get(".dp-leftnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+
+
+ });
+ });
+
+ it("Check for March month with 31 days starting on Sunday", () => {
+ const [datePicker7, datePicker7FieldView] = Object.entries(formContainer._fields)[0];
+ const model = formContainer._model.getElement(datePicker7)
+
+ const date = '2020-03-01';
+ cy.get(`#${datePicker7}`).find("input").clear().type(date);
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ cy.get("#li-day-2").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Sunday, 1 March, 2020");
+ });
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get("#li-day-32").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Tuesday, 31 March, 2020");
+ });
+ });
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get(".dp-rightnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+ cy.get(".dp-leftnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+
+
+ });
+ });
+
+ it("Check for March month with 31 days starting on Saturday", () => {
+ const [datePicker7, datePicker7FieldView] = Object.entries(formContainer._fields)[0];
+ const model = formContainer._model.getElement(datePicker7)
+
+ const date = '2025-03-01';
+ cy.get(`#${datePicker7}`).find("input").clear().type(date);
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ cy.get("#li-day-2").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Saturday, 1 March, 2025");
+ });
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get("#li-day-32").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Monday, 31 March, 2025");
+ });
+ });
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get(".dp-rightnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+ cy.get(".dp-leftnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+
+
+ });
+ });
+
+ it("Check for April month with 30 days starting on Sunday", () => {
+ const [datePicker7, datePicker7FieldView] = Object.entries(formContainer._fields)[0];
+ const model = formContainer._model.getElement(datePicker7)
+
+ const date = '2029-04-01';
+ cy.get(`#${datePicker7}`).find("input").clear().type(date);
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ cy.get("#li-day-2").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Sunday, 1 April, 2029");
+ });
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get("#li-day-31").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Monday, 30 April, 2029");
+ });
+ });
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get(".dp-rightnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+ cy.get(".dp-leftnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+
+
+ });
+ });
+
+ it("Check for April month with 30 days starting on Satuday", () => {
+ const [datePicker7, datePicker7FieldView] = Object.entries(formContainer._fields)[0];
+ const model = formContainer._model.getElement(datePicker7)
+
+ const date = '2028-04-01';
+ cy.get(`#${datePicker7}`).find("input").clear().type(date);
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ cy.get("#li-day-2").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Saturday, 1 April, 2028");
+ });
+ });
+
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get("#li-day-31").should("be.visible").click();
+ cy.get(`#${datePicker7}`).find("input").blur().should("have.value", "Sunday, 30 April, 2028");
+ });
+ });
+ cy.get(`#${datePicker7}`).find(".cmp-adaptiveform-datepicker__calendar-icon").should("be.visible").click().then(() => {
+ cy.get(".dp-rightnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+ cy.get(".dp-leftnav").should("be.visible").click();
+ cy.get('.datetimepicker.datePickerTarget').then(($selectedElement) => {
+ cy.get('.view.dp-monthview').children().should("have.length", 7)
+ });
+
+
+ });
+ });
+
+})
\ No newline at end of file
diff --git a/ui.tests/test-module/specs/datepicker/datepicker.runtime.spec.js b/ui.tests/test-module/specs/datepicker/datepicker.runtime.spec.js
index 11f032d3d9..c05850fc7c 100644
--- a/ui.tests/test-module/specs/datepicker/datepicker.runtime.spec.js
+++ b/ui.tests/test-module/specs/datepicker/datepicker.runtime.spec.js
@@ -142,6 +142,8 @@ describe("Form Runtime with Date Picker", () => {
cy.get(`#${datePicker4}`).find("input").clear().type(incorrectInput).blur().then(x => {
cy.get(`#${datePicker4}`).find(".cmp-adaptiveform-datepicker__errormessage").should('have.text',"Please enter a valid value.")
+ cy.get(`#${datePicker4} > div.${bemBlock}__errormessage`).should('have.attr', 'id', `${datePicker4}__errormessage`)
+ cy.get(`#${datePicker4} > .${bemBlock}__widget`).should('have.attr', 'aria-describedby', `${datePicker4}__errormessage ${datePicker4}__longdescription ${datePicker4}__shortdescription`)
})
cy.get(`#${datePicker4}`).find("input").clear().type(correctInput).blur().then(x => {
diff --git a/ui.tests/test-module/specs/dropdown/dropdown.runtime.spec.js b/ui.tests/test-module/specs/dropdown/dropdown.runtime.spec.js
index 9b8154c61c..6d5bf37f9f 100644
--- a/ui.tests/test-module/specs/dropdown/dropdown.runtime.spec.js
+++ b/ui.tests/test-module/specs/dropdown/dropdown.runtime.spec.js
@@ -184,6 +184,8 @@ describe("Form with Dropdown", () => {
cy.get(`#${dropdown3} select`).select("cauliflower").blur().then(x => {
cy.get(`#${dropdown6} select`).select("beans")
cy.get(`#${dropdown6}`).find(".cmp-adaptiveform-dropdown__errormessage").should('have.text',"Please enter a valid value.")
+ cy.get(`#${dropdown6} > div.${bemBlock}__errormessage`).should('have.attr', 'id', `${dropdown6}__errormessage`)
+ cy.get(`#${dropdown6} > .${bemBlock}__widget`).should('have.attr', 'aria-describedby', `${dropdown6}__errormessage ${dropdown6}__longdescription ${dropdown6}__shortdescription`)
cy.get(`#${dropdown6} select`).select("carrot")
cy.get(`#${dropdown6}`).find(".cmp-adaptiveform-dropdown__errormessage").should('have.text',"")
diff --git a/ui.tests/test-module/specs/emailinput/emailinput.runtime.spec.js b/ui.tests/test-module/specs/emailinput/emailinput.runtime.spec.js
index d87241d60f..9e38b0ae90 100644
--- a/ui.tests/test-module/specs/emailinput/emailinput.runtime.spec.js
+++ b/ui.tests/test-module/specs/emailinput/emailinput.runtime.spec.js
@@ -88,11 +88,13 @@ describe("Form Runtime with Email Input", () => {
})
});
- it(" Invalid email ID generates error message ", () => {
+ it(" Invalid email ID generates error message email ", () => {
const [id, fieldView] = Object.entries(formContainer._fields)[0]
const notAllowed = "invalidEmail"
cy.get(`#${id}`).find("input").clear().type(notAllowed).blur().then(x => {
cy.get('.cmp-adaptiveform-emailinput__errormessage').should('be.visible');
+ cy.get(`#${id} > div.${bemBlock}__errormessage`).should('have.attr', 'id', `${id}__errormessage`);
+ cy.get(`#${id} > .${bemBlock}__widget`).should('have.attr', 'aria-describedby', `${id}__errormessage ${id}__longdescription ${id}__shortdescription`);
})
const invalidEmailPattern = "invalidEmail@domain"
cy.get(`#${id}`).find("input").clear().type(invalidEmailPattern).blur().then(x => {
diff --git a/ui.tests/test-module/specs/fileinput/fileinput.runtime.spec.js b/ui.tests/test-module/specs/fileinput/fileinput.runtime.spec.js
index 50e9fde0bd..8949994d8b 100644
--- a/ui.tests/test-module/specs/fileinput/fileinput.runtime.spec.js
+++ b/ui.tests/test-module/specs/fileinput/fileinput.runtime.spec.js
@@ -51,6 +51,7 @@ const checkFilePreviewInFileAttachment = (component) => {
const deleteSelectedFiles = (component, fileNames) => {
cy.get(component).then(() => {
fileNames.forEach((fileName) => {
+ cy.get(".cmp-adaptiveform-fileinput__filedelete").should('have.attr', 'role', 'button');
cy.get(".cmp-adaptiveform-fileinput__filename").contains(fileName).next().find('.cmp-adaptiveform-fileinput__filedelete').click();
})
});
@@ -172,6 +173,7 @@ describe("Form with File Input - Basic Tests", () => {
deleteSelectedFiles(fileInput, sampleFileNames)
cy.get('.cmp-adaptiveform-fileinput__filelist').eq(0).children().should('have.length', 0);
+ cy.get(".cmp-adaptiveform-fileinput__widgetlabel").should('have.attr', 'role', 'button');
})
})
diff --git a/ui.tests/test-module/specs/numberinput/numberinput.runtime.spec.js b/ui.tests/test-module/specs/numberinput/numberinput.runtime.spec.js
index 87c7c5eb33..0ea9407dd8 100644
--- a/ui.tests/test-module/specs/numberinput/numberinput.runtime.spec.js
+++ b/ui.tests/test-module/specs/numberinput/numberinput.runtime.spec.js
@@ -165,6 +165,8 @@ describe("Form with Number Input", () => {
cy.get(`#${numberInput4}`).find("input").clear().type(incorrectInput).blur().then(x => {
cy.get(`#${numberInput4}`).find(".cmp-adaptiveform-numberinput__errormessage").should('have.text',"Please enter a valid value.")
+ cy.get(`#${numberInput4} > div.${bemBlock}__errormessage`).should('have.attr', 'id', `${numberInput4}__errormessage`)
+ cy.get(`#${numberInput4} > .${bemBlock}__widget`).should('have.attr', 'aria-describedby', `${numberInput4}__errormessage ${numberInput4}__longdescription ${numberInput4}__shortdescription`)
})
cy.get(`#${numberInput4}`).find("input").clear().type(correctInput).blur().then(x => {
diff --git a/ui.tests/test-module/specs/radiobutton/radiobutton.runtime.spec.js b/ui.tests/test-module/specs/radiobutton/radiobutton.runtime.spec.js
index 5af6c2b00f..d877cb15d2 100644
--- a/ui.tests/test-module/specs/radiobutton/radiobutton.runtime.spec.js
+++ b/ui.tests/test-module/specs/radiobutton/radiobutton.runtime.spec.js
@@ -97,6 +97,9 @@ describe("Form with Radio Button Input", () => {
const [id, fieldView] = Object.entries(formContainer._fields)[0];
formContainer._model.validate();
cy.get(`#${id}`).find(".cmp-adaptiveform-radiobutton__errormessage").should('have.text',"This is a required radiobutton");
+ cy.get(`#${id} > div.${bemBlock}__errormessage`).should('have.attr', 'id', `${id}__errormessage`);
+ // cy.get(`#${id} > .${bemBlock}__option__widget`).should('have.attr', 'aria-describedby');
+ cy.get(`#${id}`).find(".cmp-adaptiveform-radiobutton__option__widget").should('have.attr', 'aria-describedby', `${id}__errormessage ${id}__longdescription ${id}__shortdescription`);
cy.get(`#${id}`).find("input").eq(1).click().then(x => {
cy.get(`#${id}`).find(".cmp-adaptiveform-radiobutton__errormessage").should('have.text',"");
diff --git a/ui.tests/test-module/specs/switch/switch.runtime.spec.js b/ui.tests/test-module/specs/switch/switch.runtime.spec.js
index b4bf6b7135..3adce9571b 100644
--- a/ui.tests/test-module/specs/switch/switch.runtime.spec.js
+++ b/ui.tests/test-module/specs/switch/switch.runtime.spec.js
@@ -109,7 +109,7 @@ describe("Form Runtime with Switch Input", () => {
})
});
- it(" should show error messages in the HTML ", () => {
+ it(" should show error messages in the HTML switch", () => {
const id = formContainer._model.items[2].id;
const model = formContainer._model.getElement(id)
@@ -118,7 +118,9 @@ describe("Form Runtime with Switch Input", () => {
})
cy.get(`#${id}`).find("input").click().then(x => {
- cy.get(`#${id}`).find(".cmp-adaptiveform-switch__errormessage").should('have.text',"This is a custom required switch")
+ cy.get(`#${id}`).find(".cmp-adaptiveform-switch__errormessage").should('have.text',"This is a custom required switch");
+ cy.get(`#${id} > div.${bemBlock}__errormessage`).should('have.attr', 'id', `${id}__errormessage`);
+ cy.get(`#${id} > .${bemBlock}__container > .${bemBlock}__widget-label > .${bemBlock}__widget`).should('have.attr', 'aria-describedby', `${id}__errormessage ${id}__longdescription ${id}__shortdescription`);
})
cy.get(`#${id}`).find("input").click().then(x => {
diff --git a/ui.tests/test-module/specs/telephoneinput/telephoneinput.runtime.spec.js b/ui.tests/test-module/specs/telephoneinput/telephoneinput.runtime.spec.js
index 2b92ddb3c9..ef5287f284 100644
--- a/ui.tests/test-module/specs/telephoneinput/telephoneinput.runtime.spec.js
+++ b/ui.tests/test-module/specs/telephoneinput/telephoneinput.runtime.spec.js
@@ -52,7 +52,7 @@ describe("Form Runtime with Telephone Input", () => {
cy.get('*').should(passVisibleCheck)
cy.get('input')
.should(passDisabledAttributeCheck, 'disabled');
- cy.get('input').should('have.value', value)
+ cy.get('input').should('have.value', value);
})
}
@@ -115,7 +115,10 @@ describe("Form Runtime with Telephone Input", () => {
// Validating international pattern
const [telephoneInput6, fieldView] = Object.entries(formContainer._fields)[5];
cy.get(`#${telephoneInput6}`).find("input").clear().type(internationalInvalid).blur().then(() => {
+ // cy.get(`.${bemBlock}__widget`).should('have.attr', 'aria-describedby', `${telephoneInput6}__errormessage`);
cy.get(`#${telephoneInput6} > div.${bemBlock}__errormessage`).should('have.text', 'Please match the format requested.');
+ cy.get(`#${telephoneInput6} > div.${bemBlock}__errormessage`).should('have.attr', 'id', `${telephoneInput6}__errormessage`);
+ cy.get(`#${telephoneInput6} > .${bemBlock}__widget`).should('have.attr', 'aria-describedby', `${telephoneInput6}__errormessage ${telephoneInput6}__longdescription ${telephoneInput6}__shortdescription`);
})
// Validating UK pattern
const [telephoneInput7, fieldView1] = Object.entries(formContainer._fields)[6];
diff --git a/ui.tests/test-module/specs/textinput/textinput.runtime.spec.js b/ui.tests/test-module/specs/textinput/textinput.runtime.spec.js
index a3f1ad86d7..a25da2faf4 100644
--- a/ui.tests/test-module/specs/textinput/textinput.runtime.spec.js
+++ b/ui.tests/test-module/specs/textinput/textinput.runtime.spec.js
@@ -179,6 +179,8 @@ describe("Form Runtime with Text Input", () => {
// 2. Pattern: [^'\x22]+
cy.get(`#${textbox6}`).find("input").clear().type("'").blur().then(x => {
cy.get(`#${textbox6}`).find(".cmp-adaptiveform-textinput__errormessage").should('have.text',"Please match the format requested.")
+ cy.get(`#${textbox6} > div.${bemBlock}__errormessage`).should('have.attr', 'id', `${textbox6}__errormessage`);
+ cy.get(`#${textbox6} > .${bemBlock}__widget`).should('have.attr', 'aria-describedby', `${textbox6}__errormessage ${textbox6}__longdescription ${textbox6}__shortdescription`);
})
// 3. Maximum Number of Characters: 20