@sap-ux/ui5-test-writer 0.7.96 → 0.7.98

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/dist/types.d.ts CHANGED
@@ -67,12 +67,26 @@ export type ObjectPageNavigationParents = {
67
67
  parentOPName?: string;
68
68
  parentOPTableSection?: string;
69
69
  };
70
+ export type BodySubSectionFeatureData = {
71
+ id: string;
72
+ isTable: boolean;
73
+ custom: boolean;
74
+ order: number;
75
+ };
76
+ export type BodySectionFeatureData = {
77
+ id: string;
78
+ isTable: boolean;
79
+ custom: boolean;
80
+ order: number;
81
+ subSections: BodySubSectionFeatureData[];
82
+ };
70
83
  export type ObjectPageFeatures = {
71
84
  name?: string;
72
85
  navigationParents?: ObjectPageNavigationParents;
73
86
  headerTitle?: string;
74
87
  headerDescription?: string;
75
88
  headerSections?: HeaderSectionFeatureData[];
89
+ bodySections?: BodySectionFeatureData[];
76
90
  };
77
91
  export type ListReportFeatures = {
78
92
  name?: string;
@@ -121,6 +135,11 @@ export type AppFeatures = {
121
135
  objectPages?: ObjectPageFeatures[];
122
136
  fpm?: FPMFeatures;
123
137
  };
138
+ export type FormField = {
139
+ fieldGroupQualifier?: string;
140
+ field?: string;
141
+ targetAnnotation?: string;
142
+ };
124
143
  export type HeaderSectionFeatureData = {
125
144
  facetId?: string;
126
145
  title?: string;
@@ -129,10 +148,7 @@ export type HeaderSectionFeatureData = {
129
148
  microChart?: boolean;
130
149
  form?: boolean;
131
150
  stashed?: boolean | string;
132
- fields?: {
133
- fieldGroupQualifier?: string;
134
- field?: string;
135
- }[];
151
+ fields?: FormField[];
136
152
  };
137
153
  export interface ButtonState {
138
154
  visible: boolean;
@@ -10,6 +10,7 @@ export interface AggregationItem extends TreeAggregation {
10
10
  name: string;
11
11
  value: string;
12
12
  }[];
13
+ dataType?: string;
13
14
  };
14
15
  }
15
16
  export interface FieldItem extends AggregationItem {
@@ -19,6 +20,7 @@ export interface SectionItem extends AggregationItem {
19
20
  title?: string;
20
21
  custom?: boolean;
21
22
  name?: string;
23
+ order?: number;
22
24
  schema: {
23
25
  keys: {
24
26
  name: string;
@@ -27,6 +29,9 @@ export interface SectionItem extends AggregationItem {
27
29
  dataType?: string;
28
30
  };
29
31
  }
32
+ export interface BodySectionItem extends SectionItem {
33
+ isTable?: boolean;
34
+ }
30
35
  export interface HeaderSectionItem extends SectionItem {
31
36
  properties: {
32
37
  stashed: {
@@ -25,6 +25,8 @@ async function getObjectPageFeatures(objectPages, listReportPageKey, log) {
25
25
  pageFeatureData.navigationParents = getObjectPageNavigationParents(objectPage.name, objectPages, listReportPageKey);
26
26
  // extract header sections (facets)
27
27
  pageFeatureData.headerSections = extractObjectPageHeaderSectionsData(objectPage);
28
+ // extract body sections
29
+ pageFeatureData.bodySections = extractObjectPageBodySectionsData(objectPage);
28
30
  objectPageFeatures.push(pageFeatureData);
29
31
  }
30
32
  return objectPageFeatures;
@@ -103,6 +105,53 @@ function extractObjectPageHeaderSectionsData(objectPage) {
103
105
  }
104
106
  return headerSections;
105
107
  }
108
+ /**
109
+ * Extracts body sections data from an object page model.
110
+ *
111
+ * @param objectPage - object page from the application model
112
+ * @returns body sections data including sub-sections
113
+ */
114
+ function extractObjectPageBodySectionsData(objectPage) {
115
+ const bodySections = [];
116
+ if (objectPage.model) {
117
+ const sectionsAggregation = (0, modelUtils_1.getAggregations)(objectPage.model.root)['sections'];
118
+ const sections = (0, modelUtils_1.getAggregations)(sectionsAggregation);
119
+ Object.entries(sections).forEach(([sectionKey, section]) => {
120
+ const sectionId = getSectionIdentifier(section) ?? sectionKey;
121
+ const subSections = extractBodySubSectionsData(section, sectionId);
122
+ bodySections.push({
123
+ id: sectionId,
124
+ isTable: !!section.isTable,
125
+ custom: !!section.custom,
126
+ order: section?.order ?? -1, // put a negative order number to signal that order was not in spec
127
+ subSections
128
+ });
129
+ });
130
+ }
131
+ return bodySections;
132
+ }
133
+ /**
134
+ * Extracts sub-sections data from a body section.
135
+ *
136
+ * @param section - body section entry from the application model
137
+ * @param parentSectionId - identifier of the parent section (used as fallback key prefix)
138
+ * @returns array of sub-section feature data
139
+ */
140
+ function extractBodySubSectionsData(section, parentSectionId) {
141
+ const subSections = [];
142
+ const subSectionsAggregation = (0, modelUtils_1.getAggregations)(section)['subSections'];
143
+ const subSectionItems = (0, modelUtils_1.getAggregations)(subSectionsAggregation);
144
+ Object.entries(subSectionItems).forEach(([subSectionKey, subSection]) => {
145
+ const subSectionId = getSectionIdentifier(subSection) ?? `${parentSectionId}_${subSectionKey}`;
146
+ subSections.push({
147
+ id: subSectionId,
148
+ isTable: !!subSection.isTable,
149
+ custom: !!subSection.custom,
150
+ order: subSection?.order ?? -1 // put a negative order number to signal that order was not in spec
151
+ });
152
+ });
153
+ return subSections;
154
+ }
106
155
  /**
107
156
  * Gets the identifier of a section for OPA5 tests.
108
157
  *
@@ -113,14 +162,14 @@ function getSectionIdentifier(section) {
113
162
  return getSectionIdentifierFromKey(section) ?? getSectionIdentifierFromTitle(section);
114
163
  }
115
164
  /**
116
- * Gets the identifier of a section from the 'ID' entry in the schema keys for OPA5 tests.
165
+ * Gets the identifier of a section from the 'ID' or 'Key' entry in the schema keys for OPA5 tests.
117
166
  * If no such entry is found, undefined is returned.
118
167
  *
119
168
  * @param section - section entry from ux specification
120
- * @returns identifier of the section for OPA5 tests; can be undefined if no 'ID' entry is found
169
+ * @returns identifier of the section for OPA5 tests; can be undefined if no 'ID' or 'Key' entry is found
121
170
  */
122
171
  function getSectionIdentifierFromKey(section) {
123
- const keyEntry = section?.schema?.keys?.find((key) => key.name === 'ID');
172
+ const keyEntry = section?.schema?.keys?.find((key) => key.name === 'ID' || key.name === 'Key');
124
173
  return keyEntry ? keyEntry.value.replace('#', '::') : undefined;
125
174
  }
126
175
  /**
@@ -155,16 +204,38 @@ function getHeaderSectionFormFields(section) {
155
204
  if (fields) {
156
205
  Object.keys(fields).forEach((fieldKey) => {
157
206
  const field = fields[fieldKey];
158
- if (field?.name) {
159
- formFields.push({
160
- fieldGroupQualifier: getFieldGroupQualifier(formAggregation),
161
- field: field.schema.keys.find((key) => key.name === 'Value')?.value
162
- });
207
+ const fieldData = getFormFieldData(field, formAggregation);
208
+ if (fieldData) {
209
+ formFields.push(fieldData);
163
210
  }
164
211
  });
165
212
  }
166
213
  return formFields;
167
214
  }
215
+ /**
216
+ * Gets field data for a form field in a header section for OPA5 tests, including its identifier, bound property, and target annotation.
217
+ *
218
+ * @param field - field entry from ux specification
219
+ * @param formAggregation - form aggregation entry from ux specification, used to get field group qualifier for the field
220
+ * @returns field data including its identifier, bound property, and target annotation for OPA5 tests; can be undefined if the field type is not supported or necessary information is missing
221
+ */
222
+ function getFormFieldData(field, formAggregation) {
223
+ if (!field.name) {
224
+ return undefined;
225
+ }
226
+ let [_, propertyName, targetAnnotation] = field.name.split('::');
227
+ // fall back to Value property in case of malformed or otherwise irregular field name
228
+ if (!propertyName) {
229
+ propertyName = field.schema.keys.find((key) => key.name === 'Value')?.value;
230
+ }
231
+ const fieldIdentifier = {
232
+ fieldGroupQualifier: getFieldGroupQualifier(formAggregation),
233
+ field: propertyName,
234
+ targetAnnotation: targetAnnotation
235
+ };
236
+ // avoid creating identifier if field property could not be determined
237
+ return fieldIdentifier.field ? fieldIdentifier : undefined;
238
+ }
168
239
  /**
169
240
  * Gets the field group qualifier of a form aggregation for OPA5 tests.
170
241
  *
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sap-ux/ui5-test-writer",
3
3
  "description": "SAP UI5 tests writer",
4
- "version": "0.7.96",
4
+ "version": "0.7.98",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -51,6 +51,7 @@ sap.ui.define([
51
51
  Then.onThe<%- name%>.onHeader().iCheckFieldInFieldGroup({
52
52
  fieldGroup: "FieldGroup::<%- field.fieldGroupQualifier %>",
53
53
  field: "<%- field.field %>",
54
+ targetAnnotation: "<%- field.targetAnnotation %>"
54
55
  });
55
56
  <% }) -%>
56
57
  <% } -%>
@@ -59,6 +60,22 @@ sap.ui.define([
59
60
  });
60
61
  <% } -%>
61
62
 
63
+ <% if (bodySections?.length > 0) { -%>
64
+ opaTest("Check body sections of the Object Page", function (Given, When, Then) {
65
+ Then.onThe<%- name%>.iCheckNumberOfSections(<%- bodySections.length %>);
66
+ <% bodySections.forEach(function(section) { -%>
67
+ When.onThe<%- name%>.iGoToSection({ section: "<%- section.id %>" });
68
+ Then.onThe<%- name%>.iCheckSection({ section: "<%- section.id %>" });
69
+ <% if (section?.subSections?.length > 0) { -%>
70
+ <% section.subSections.forEach(function(subSection) { -%>
71
+ When.onThe<%- name%>.iGoToSection({ section: "<%- section.id %>", subSection: "<%- subSection.id %>" });
72
+ Then.onThe<%- name%>.iCheckSubSection({ section: "<%- subSection.id %>" });
73
+ <% }) -%>
74
+ <% } -%>
75
+ <% }) -%>
76
+ });
77
+ <% } -%>
78
+
62
79
  opaTest("Teardown", function (Given, When, Then) {
63
80
  // Cleanup
64
81
  Given.iTearDownMyApp();