@sapui5/sap.fe.test 1.130.6 → 1.132.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/package.json +1 -1
- package/src/sap/fe/test/.library +1 -1
- package/src/sap/fe/test/AppStateAdapter.js +1 -1
- package/src/sap/fe/test/JestFlexibilityHelper.js +3 -5
- package/src/sap/fe/test/JestTemplatingHelper.js +213 -34
- package/src/sap/fe/test/JestTemplatingHelper.tsx +200 -3
- package/src/sap/fe/test/ListReport.js +4 -1
- package/src/sap/fe/test/ObjectPage.js +3 -3
- package/src/sap/fe/test/Shell.js +277 -272
- package/src/sap/fe/test/Stubs.js +20 -18
- package/src/sap/fe/test/UI5MockHelper.js +13 -10
- package/src/sap/fe/test/UI5MockHelper.ts +12 -2
- package/src/sap/fe/test/Utils.js +4 -0
- package/src/sap/fe/test/api/CollaborationAPI.js +3 -3
- package/src/sap/fe/test/api/CollaborationAPI.ts +2 -1
- package/src/sap/fe/test/api/TableAssertions.js +2 -1
- package/src/sap/fe/test/builder/KPIBuilder.js +13 -0
- package/src/sap/fe/test/builder/MdcTableBuilder.js +15 -10
- package/src/sap/fe/test/internal/ConsoleErrorChecker.js +3 -5
- package/src/sap/fe/test/library.js +3 -2
- package/src/sap/fe/test/library.ts +1 -0
|
@@ -10,6 +10,7 @@ import merge from "sap/base/util/merge";
|
|
|
10
10
|
import uid from "sap/base/util/uid";
|
|
11
11
|
import jsx from "sap/fe/base/jsx-runtime/jsx";
|
|
12
12
|
import AppComponent from "sap/fe/core/AppComponent";
|
|
13
|
+
import PageController from "sap/fe/core/PageController";
|
|
13
14
|
import type TemplateComponent from "sap/fe/core/TemplateComponent";
|
|
14
15
|
import TemplateModel from "sap/fe/core/TemplateModel";
|
|
15
16
|
import { parseXMLString } from "sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor";
|
|
@@ -101,7 +102,8 @@ const nameSpaceMap: Record<string, string> = {
|
|
|
101
102
|
valueHelp: "sap.fe.macros.valueHelp",
|
|
102
103
|
contentSwitcher: "sap.fe.macros.contentSwitcher",
|
|
103
104
|
filterBar: "sap.fe.macros.filterBar",
|
|
104
|
-
fbControls: "sap.fe.macros.controls.filterbar"
|
|
105
|
+
fbControls: "sap.fe.macros.controls.filterbar",
|
|
106
|
+
draftIndicator: "sap.fe.macros.draftIndicator"
|
|
105
107
|
};
|
|
106
108
|
const reveseNamespaceMap = Object.keys(nameSpaceMap).reduce((reverseMap: Record<string, string>, currentName) => {
|
|
107
109
|
reverseMap[nameSpaceMap[currentName]] = currentName;
|
|
@@ -840,6 +842,188 @@ export function serializeControl(controlToSerialize?: UI5Element | UI5Element[],
|
|
|
840
842
|
}
|
|
841
843
|
}
|
|
842
844
|
|
|
845
|
+
export function serializeControlAsXML(controlToSerialize?: UI5Element | UI5Element[], showCustomStyleClasses = false) {
|
|
846
|
+
let tabCount = 0;
|
|
847
|
+
const UID = /uid--id-\d{13}-\d{1,3}/;
|
|
848
|
+
const CONTROLID = /id-\d{13}-\d{1,3}/;
|
|
849
|
+
const definedNamespaces: Record<string, boolean> = {};
|
|
850
|
+
|
|
851
|
+
function getNamespaceAlias(className: string): string {
|
|
852
|
+
const namesSplit = className.split(".");
|
|
853
|
+
const namespace = namesSplit.slice(0, -1);
|
|
854
|
+
const name = namesSplit[namesSplit.length - 1];
|
|
855
|
+
let namespaceAlias = namespace[namespace.length - 1];
|
|
856
|
+
if (reveseNamespaceMap[namespace.join(".")]) {
|
|
857
|
+
namespaceAlias = reveseNamespaceMap[namespace.join(".")];
|
|
858
|
+
}
|
|
859
|
+
if (namespaceAlias === undefined) {
|
|
860
|
+
namespaceAlias = "test";
|
|
861
|
+
}
|
|
862
|
+
return namespaceAlias;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
function getTab(toAdd = 0) {
|
|
866
|
+
let tab = "";
|
|
867
|
+
for (let i = 0; i < tabCount + toAdd; i++) {
|
|
868
|
+
tab += "\t";
|
|
869
|
+
}
|
|
870
|
+
return tab;
|
|
871
|
+
}
|
|
872
|
+
const serializeDelegate = {
|
|
873
|
+
start: function (control: any, sAggregationName: string) {
|
|
874
|
+
let controlDetail = "";
|
|
875
|
+
if (sAggregationName) {
|
|
876
|
+
if (control.getParent()) {
|
|
877
|
+
const indexInParent = (control.getParent().getAggregation(sAggregationName) as ManagedObject[])?.indexOf?.(control);
|
|
878
|
+
if (indexInParent > 0) {
|
|
879
|
+
controlDetail += `\n${getTab()}`;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
const nameFull = control.getMetadata().getName();
|
|
884
|
+
const namesSplit = nameFull.split(".");
|
|
885
|
+
const name = namesSplit[namesSplit.length - 1];
|
|
886
|
+
const namespaceAlias = getNamespaceAlias(nameFull);
|
|
887
|
+
controlDetail += `<${namespaceAlias}:${name}\n`;
|
|
888
|
+
if (!definedNamespaces[namespaceAlias]) {
|
|
889
|
+
definedNamespaces[namespaceAlias] = true;
|
|
890
|
+
controlDetail += `${getTab()}xmlns:${namespaceAlias}="${nameSpaceMap[namespaceAlias]}"`;
|
|
891
|
+
}
|
|
892
|
+
return controlDetail;
|
|
893
|
+
},
|
|
894
|
+
end: function (control: any) {
|
|
895
|
+
const nameFull = control.getMetadata().getName();
|
|
896
|
+
const namesSplit = nameFull.split(".");
|
|
897
|
+
const name = namesSplit[namesSplit.length - 1];
|
|
898
|
+
const namespaceAlias = getNamespaceAlias(nameFull);
|
|
899
|
+
let hasAggregation = false;
|
|
900
|
+
for (const mAggregationsKey in control.mAggregations) {
|
|
901
|
+
if (
|
|
902
|
+
(!Array.isArray(control.mAggregations[mAggregationsKey]) &&
|
|
903
|
+
control.mAggregations[mAggregationsKey] !== null &&
|
|
904
|
+
control.mAggregations[mAggregationsKey] !== undefined) ||
|
|
905
|
+
(Array.isArray(control.mAggregations[mAggregationsKey]) && control.mAggregations[mAggregationsKey].length > 0)
|
|
906
|
+
) {
|
|
907
|
+
hasAggregation = true;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
if (hasAggregation) {
|
|
911
|
+
return `</${namespaceAlias}:${name}>`;
|
|
912
|
+
} else {
|
|
913
|
+
return `/>`;
|
|
914
|
+
}
|
|
915
|
+
},
|
|
916
|
+
middle: function (control: any) {
|
|
917
|
+
let id = control.getId();
|
|
918
|
+
id = typeof id === "string" ? id?.replace?.(CONTROLID, "id") : id;
|
|
919
|
+
let data = "";
|
|
920
|
+
if (!ManagedObjectMetadata.isGeneratedId(id)) {
|
|
921
|
+
data = `id="${id}"`;
|
|
922
|
+
}
|
|
923
|
+
let keys = Object.keys(control.mProperties)
|
|
924
|
+
.concat(Object.keys(control.mBindingInfos))
|
|
925
|
+
.concat(Object.keys(control.mAssociations))
|
|
926
|
+
.concat(Object.keys(control.mEventRegistry));
|
|
927
|
+
keys = keys.sort((a, b) => a.localeCompare(b));
|
|
928
|
+
const uniqueKeys = new Set(keys);
|
|
929
|
+
keys = Array.from(uniqueKeys);
|
|
930
|
+
for (const oControlKey of keys) {
|
|
931
|
+
if (control.mBindingInfos.hasOwnProperty(oControlKey)) {
|
|
932
|
+
const bindingDetail = { ...control.mBindingInfos[oControlKey] };
|
|
933
|
+
if (bindingDetail.bindingString) {
|
|
934
|
+
data += `\n${getTab()}${oControlKey}="${bindingDetail.bindingString.replace(">", ">")}"`;
|
|
935
|
+
} else {
|
|
936
|
+
if (bindingDetail.type?.oOutputFormat) {
|
|
937
|
+
delete bindingDetail.type.oOutputFormat;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
if (bindingDetail.binding) {
|
|
941
|
+
delete bindingDetail.binding;
|
|
942
|
+
}
|
|
943
|
+
if (bindingDetail.template) {
|
|
944
|
+
delete bindingDetail.template;
|
|
945
|
+
}
|
|
946
|
+
data += `\n${getTab()}${oControlKey}='${JSON.stringify(bindingDetail)}'`;
|
|
947
|
+
}
|
|
948
|
+
} else if (control.mProperties.hasOwnProperty(oControlKey) && control.mProperties[oControlKey] !== undefined) {
|
|
949
|
+
let propertyValue = control.mProperties[oControlKey];
|
|
950
|
+
propertyValue = typeof propertyValue === "string" ? propertyValue?.replace?.(UID, "uid--id") : propertyValue;
|
|
951
|
+
propertyValue = typeof propertyValue === "string" ? propertyValue?.replace?.(CONTROLID, "id") : propertyValue;
|
|
952
|
+
try {
|
|
953
|
+
propertyValue = typeof propertyValue === "object" ? JSON.stringify(propertyValue) : propertyValue;
|
|
954
|
+
} catch (e) {
|
|
955
|
+
// Stringify may fail for circular references but it's not the end of the world
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
data += `\n${getTab()} ${oControlKey}="${propertyValue}"`;
|
|
959
|
+
} else if (control.mAssociations.hasOwnProperty(oControlKey)) {
|
|
960
|
+
let associationValue = control.mAssociations[oControlKey];
|
|
961
|
+
if (!Array.isArray(associationValue)) {
|
|
962
|
+
associationValue = [associationValue];
|
|
963
|
+
}
|
|
964
|
+
associationValue = associationValue.map((associationValueElement: string) => {
|
|
965
|
+
return typeof associationValueElement === "string"
|
|
966
|
+
? associationValueElement?.replace?.(CONTROLID, "id")
|
|
967
|
+
: associationValueElement;
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
data += `\n${getTab()} ${oControlKey}="${(associationValue?.join?.(",") ?? associationValue) || undefined}"`;
|
|
971
|
+
} else if (control.mEventRegistry.hasOwnProperty(oControlKey)) {
|
|
972
|
+
if (control.mEventRegistry[oControlKey][0]?.fFunction?.name) {
|
|
973
|
+
data += `\n${getTab()} ${oControlKey}="${control.mEventRegistry[oControlKey][0]?.fFunction?.name}"`;
|
|
974
|
+
} else {
|
|
975
|
+
data += `\n${getTab()} ${oControlKey}="someEventHandler"`;
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
if (showCustomStyleClasses && control.aCustomStyleClasses?.length > 0) {
|
|
980
|
+
data += `\n${getTab()} customStyleClasses : ${control.aCustomStyleClasses.join(", ")}`;
|
|
981
|
+
}
|
|
982
|
+
data += `\n`;
|
|
983
|
+
let hasAggregation = false;
|
|
984
|
+
for (const mAggregationsKey in control.mAggregations) {
|
|
985
|
+
if (
|
|
986
|
+
(!Array.isArray(control.mAggregations[mAggregationsKey]) &&
|
|
987
|
+
control.mAggregations[mAggregationsKey] !== null &&
|
|
988
|
+
control.mAggregations[mAggregationsKey] !== undefined) ||
|
|
989
|
+
(Array.isArray(control.mAggregations[mAggregationsKey]) && control.mAggregations[mAggregationsKey].length > 0)
|
|
990
|
+
) {
|
|
991
|
+
hasAggregation = true;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
if (hasAggregation) {
|
|
995
|
+
data += ">";
|
|
996
|
+
}
|
|
997
|
+
return data;
|
|
998
|
+
},
|
|
999
|
+
startAggregation: function (control: any, sName: string) {
|
|
1000
|
+
const namespaceAlias = getNamespaceAlias(control.getMetadata().getName());
|
|
1001
|
+
let out = `\n${getTab()}<${namespaceAlias}:${sName}>`;
|
|
1002
|
+
tabCount++;
|
|
1003
|
+
out += `\n${getTab()}`;
|
|
1004
|
+
return out;
|
|
1005
|
+
},
|
|
1006
|
+
endAggregation: function (control: any, sName: string) {
|
|
1007
|
+
tabCount--;
|
|
1008
|
+
const namespaceAlias = getNamespaceAlias(control.getMetadata().getName());
|
|
1009
|
+
if (control.mBindingInfos[sName]) {
|
|
1010
|
+
return `\n${getTab()}</${namespaceAlias}:${sName}>\n`;
|
|
1011
|
+
} else {
|
|
1012
|
+
return `\n${getTab()}</${namespaceAlias}:${sName}>\n`;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
};
|
|
1016
|
+
let outXML;
|
|
1017
|
+
if (Array.isArray(controlToSerialize)) {
|
|
1018
|
+
outXML = controlToSerialize.map((controlToRender: UI5Element) => {
|
|
1019
|
+
return new Serializer(controlToRender, serializeDelegate).serialize();
|
|
1020
|
+
});
|
|
1021
|
+
} else {
|
|
1022
|
+
outXML = new Serializer(controlToSerialize, serializeDelegate).serialize();
|
|
1023
|
+
}
|
|
1024
|
+
return formatXML(`<root>${outXML}</root>`);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
843
1027
|
export function createAwaiter() {
|
|
844
1028
|
let fnResolve!: Function;
|
|
845
1029
|
const myPromise = new Promise((resolve) => {
|
|
@@ -911,7 +1095,11 @@ export async function initializeAppComponent(
|
|
|
911
1095
|
const id = options?.componentId ?? `sap.fe.test.${guid}`;
|
|
912
1096
|
const cdsContent = fs.readFileSync(cdsFile).toString();
|
|
913
1097
|
sap.jest.registerFakeFragment(`/sap/fe/core/mock/${guid}/$metadata?sap-language=EN`, cdsContent);
|
|
914
|
-
|
|
1098
|
+
class DefaultPageContent extends PageController {
|
|
1099
|
+
render() {
|
|
1100
|
+
return <Page></Page>;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
915
1103
|
sap.ui.define(`sap/fe/test/${guid}/Component`, ["sap/fe/core/AppComponent"], function (_AppComponent: AppComponent) {
|
|
916
1104
|
"use strict";
|
|
917
1105
|
|
|
@@ -919,6 +1107,7 @@ export async function initializeAppComponent(
|
|
|
919
1107
|
metadata: {
|
|
920
1108
|
manifest: {
|
|
921
1109
|
"sap.app": {
|
|
1110
|
+
id: `test${guid}`,
|
|
922
1111
|
dataSources: {
|
|
923
1112
|
mainService: {
|
|
924
1113
|
uri: `/sap/fe/core/mock/${guid}/`,
|
|
@@ -948,7 +1137,7 @@ export async function initializeAppComponent(
|
|
|
948
1137
|
...(options?.manifestSettings ?? {}),
|
|
949
1138
|
contextPath: options?.mainContextPath ?? "/Products",
|
|
950
1139
|
viewType: "JSX",
|
|
951
|
-
viewContent: options?.pageContent ??
|
|
1140
|
+
viewContent: options?.pageContent ?? DefaultPageContent,
|
|
952
1141
|
content: options?.content
|
|
953
1142
|
}
|
|
954
1143
|
}
|
|
@@ -1003,3 +1192,11 @@ export async function waitForEvent(control: EventProvider, eventName: string): P
|
|
|
1003
1192
|
});
|
|
1004
1193
|
});
|
|
1005
1194
|
}
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* Tell the binding parser to keep the binding strings for testing.
|
|
1198
|
+
* @param enabled
|
|
1199
|
+
*/
|
|
1200
|
+
export function keepBindingStringForTest(enabled: boolean): void {
|
|
1201
|
+
BindingParser._keepBindingStrings = enabled;
|
|
1202
|
+
}
|
|
@@ -293,6 +293,9 @@ sap.ui.define(
|
|
|
293
293
|
.clickKPITag(sTitle)
|
|
294
294
|
.description("Opening card for KPI '" + sTitle + "'")
|
|
295
295
|
.execute();
|
|
296
|
+
},
|
|
297
|
+
iCloseKPICard: function () {
|
|
298
|
+
return KPIBuilder.create(this).closeKPICard().description("Closing KPI card").execute();
|
|
296
299
|
}
|
|
297
300
|
},
|
|
298
301
|
/**
|
|
@@ -464,7 +467,7 @@ sap.ui.define(
|
|
|
464
467
|
return OpaBuilder.create(this)
|
|
465
468
|
.hasType("sap.f.DynamicPageTitle")
|
|
466
469
|
.has(function (oDynamicPageTitle) {
|
|
467
|
-
return oDynamicPageTitle.getSnappedContent()[0].getText() === sAppliedFilters;
|
|
470
|
+
return oDynamicPageTitle.getSnappedContent()[0].getContent().getText() === sAppliedFilters;
|
|
468
471
|
})
|
|
469
472
|
.description("The correct text on the collapsed filterbar is displayed")
|
|
470
473
|
.execute();
|
|
@@ -585,8 +585,8 @@ sap.ui.define(
|
|
|
585
585
|
return OpaBuilder.create(this)
|
|
586
586
|
.hasType("sap.m.MessageListItem")
|
|
587
587
|
.hasProperties({
|
|
588
|
-
title: oMessageInfo.MessageText
|
|
589
|
-
groupAnnouncement: oMessageInfo.GroupLabel
|
|
588
|
+
title: oMessageInfo.MessageText
|
|
589
|
+
//groupAnnouncement: oMessageInfo.GroupLabel => with openui5/+/6328248 groups are no longer announced
|
|
590
590
|
})
|
|
591
591
|
.isDialogElement(true)
|
|
592
592
|
.description("MessageItem with correct text and group label")
|
|
@@ -746,7 +746,7 @@ sap.ui.define(
|
|
|
746
746
|
},
|
|
747
747
|
iSeeBetterLinkWithText: function (sText) {
|
|
748
748
|
return OpaBuilder.create(this)
|
|
749
|
-
.hasType("sap.fe.macros.controls.
|
|
749
|
+
.hasType("sap.fe.macros.controls.TextLink")
|
|
750
750
|
.hasProperties({ text: sText })
|
|
751
751
|
.description("Seeing Text with text '" + sText + "'")
|
|
752
752
|
.execute();
|