@sapui5/sap.fe.test 1.109.0 → 1.110.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.
Files changed (84) hide show
  1. package/README.md +5 -1
  2. package/package.json +8 -6
  3. package/src/sap/fe/test/.library +17 -18
  4. package/src/sap/fe/test/BaseActions.js +3 -2
  5. package/src/sap/fe/test/BaseArrangements.js +3 -2
  6. package/src/sap/fe/test/BaseAssertions.js +3 -2
  7. package/src/sap/fe/test/CollaborationClient.js +12 -5
  8. package/src/sap/fe/test/CollaborationClient.ts +12 -1
  9. package/src/sap/fe/test/ConfirmDialog.js +12 -11
  10. package/src/sap/fe/test/FCLView.js +16 -15
  11. package/src/sap/fe/test/FeMocks.js +1 -11
  12. package/src/sap/fe/test/Flexibility.js +12 -7
  13. package/src/sap/fe/test/FlexibleColumnLayout.js +12 -11
  14. package/src/sap/fe/test/JestFlexibilityHelper.js +113 -102
  15. package/src/sap/fe/test/JestFlexibilityHelper.ts +112 -99
  16. package/src/sap/fe/test/JestTemplatingHelper.js +73 -170
  17. package/src/sap/fe/test/JestTemplatingHelper.ts +53 -39
  18. package/src/sap/fe/test/JourneyRunner.js +3 -2
  19. package/src/sap/fe/test/ListReport.js +3 -2
  20. package/src/sap/fe/test/LocationUtil.js +3 -2
  21. package/src/sap/fe/test/ObjectPage.js +121 -17
  22. package/src/sap/fe/test/Shell.js +9 -4
  23. package/src/sap/fe/test/Stubs.js +18 -17
  24. package/src/sap/fe/test/TemplatePage.js +3 -2
  25. package/src/sap/fe/test/TemplatingTestUtils.js +3 -2
  26. package/src/sap/fe/test/UI5MockHelper.js +39 -72
  27. package/src/sap/fe/test/UI5MockHelper.ts +3 -0
  28. package/src/sap/fe/test/Utils.js +4 -3
  29. package/src/sap/fe/test/api/APIHelper.js +3 -2
  30. package/src/sap/fe/test/api/BaseAPI.js +3 -2
  31. package/src/sap/fe/test/api/ChartActions.js +3 -2
  32. package/src/sap/fe/test/api/ChartAssertions.js +3 -2
  33. package/src/sap/fe/test/api/CollaborationAPI.js +2 -30
  34. package/src/sap/fe/test/api/DialogAPI.js +3 -2
  35. package/src/sap/fe/test/api/DialogActions.js +3 -2
  36. package/src/sap/fe/test/api/DialogAssertions.js +4 -3
  37. package/src/sap/fe/test/api/DialogCreateActions.js +6 -5
  38. package/src/sap/fe/test/api/DialogCreateAssertions.js +48 -49
  39. package/src/sap/fe/test/api/DialogHelper.js +4 -3
  40. package/src/sap/fe/test/api/DialogMassEditActions.js +3 -2
  41. package/src/sap/fe/test/api/DialogMassEditAssertions.js +3 -2
  42. package/src/sap/fe/test/api/DialogMessageActions.js +3 -2
  43. package/src/sap/fe/test/api/DialogMessageAssertions.js +82 -79
  44. package/src/sap/fe/test/api/DialogType.js +3 -2
  45. package/src/sap/fe/test/api/DialogValueHelpActions.js +3 -2
  46. package/src/sap/fe/test/api/DialogValueHelpAssertions.js +3 -2
  47. package/src/sap/fe/test/api/EditState.js +4 -3
  48. package/src/sap/fe/test/api/FilterBarAPI.js +3 -2
  49. package/src/sap/fe/test/api/FilterBarActions.js +3 -2
  50. package/src/sap/fe/test/api/FilterBarAssertions.js +3 -2
  51. package/src/sap/fe/test/api/FooterAPI.js +5 -4
  52. package/src/sap/fe/test/api/FooterActionsBase.js +3 -2
  53. package/src/sap/fe/test/api/FooterActionsOP.js +3 -2
  54. package/src/sap/fe/test/api/FooterAssertionsBase.js +3 -2
  55. package/src/sap/fe/test/api/FooterAssertionsOP.js +3 -2
  56. package/src/sap/fe/test/api/FormAPI.js +3 -2
  57. package/src/sap/fe/test/api/FormActions.js +3 -2
  58. package/src/sap/fe/test/api/FormAssertions.js +3 -2
  59. package/src/sap/fe/test/api/HeaderAPI.js +3 -2
  60. package/src/sap/fe/test/api/HeaderActions.js +3 -2
  61. package/src/sap/fe/test/api/HeaderActionsLR.js +3 -2
  62. package/src/sap/fe/test/api/HeaderAssertions.js +3 -2
  63. package/src/sap/fe/test/api/HeaderAssertionsLR.js +3 -2
  64. package/src/sap/fe/test/api/HeaderLR.js +3 -2
  65. package/src/sap/fe/test/api/KPICardAPI.js +5 -4
  66. package/src/sap/fe/test/api/KPICardActions.js +7 -11
  67. package/src/sap/fe/test/api/KPICardAssertions.js +3 -2
  68. package/src/sap/fe/test/api/TableAPI.js +5 -4
  69. package/src/sap/fe/test/api/TableActions.js +16 -9
  70. package/src/sap/fe/test/api/TableAssertions.js +8 -7
  71. package/src/sap/fe/test/builder/DialogBuilder.js +99 -102
  72. package/src/sap/fe/test/builder/FEBuilder.js +3 -2
  73. package/src/sap/fe/test/builder/KPIBuilder.js +16 -25
  74. package/src/sap/fe/test/builder/MacroFieldBuilder.js +4 -2
  75. package/src/sap/fe/test/builder/MdcFieldBuilder.js +3 -2
  76. package/src/sap/fe/test/builder/MdcFilterBarBuilder.js +3 -2
  77. package/src/sap/fe/test/builder/MdcFilterFieldBuilder.js +3 -2
  78. package/src/sap/fe/test/builder/MdcTableBuilder.js +186 -95
  79. package/src/sap/fe/test/builder/OverflowToolbarBuilder.js +3 -2
  80. package/src/sap/fe/test/builder/VMBuilder.js +3 -2
  81. package/src/sap/fe/test/internal/ConsoleErrorChecker.js +13 -48
  82. package/src/sap/fe/test/internal/FEArrangements.js +3 -2
  83. package/src/sap/fe/test/internal/FEJourneyRunner.js +5 -3
  84. package/src/sap/fe/test/library.js +3 -2
@@ -1,8 +1,11 @@
1
1
  import type { AnyAnnotation, ConvertedMetadata, EntitySet, Property } from "@sap-ux/vocabularies-types";
2
2
  import compiler from "@sap/cds-compiler";
3
3
  import * as fs from "fs";
4
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5
+ // @ts-ignore
6
+ import * as plugin from "@prettier/plugin-xml";
4
7
  import * as path from "path";
5
- import type { RequiredOptions } from "prettier";
8
+ import type { Options } from "prettier";
6
9
  import { format } from "prettier";
7
10
  import Log from "sap/base/Log";
8
11
  import LoaderExtensions from "sap/base/util/LoaderExtensions";
@@ -18,6 +21,7 @@ import TemplateModel from "sap/fe/core/TemplateModel";
18
21
  import type { DataModelObjectPath } from "sap/fe/core/templating/DataModelPathHelper";
19
22
  import BindingParser from "sap/ui/base/BindingParser";
20
23
  import ManagedObject from "sap/ui/base/ManagedObject";
24
+ import ManagedObjectMetadata from "sap/ui/base/ManagedObjectMetadata";
21
25
  import Component from "sap/ui/core/Component";
22
26
  import Control from "sap/ui/core/Control";
23
27
  import InvisibleText from "sap/ui/core/InvisibleText";
@@ -56,25 +60,27 @@ Log.setLevel(1 as any, "sap.ui.core.util.XMLPreprocessor");
56
60
  jest.setTimeout(40000);
57
61
 
58
62
  const nameSpaceMap = {
59
- "macros": "sap.fe.macros",
60
- "macro": "sap.fe.macros",
61
- "macroField": "sap.fe.macros.field",
62
- "macrodata": "http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1",
63
- "log": "http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1",
64
- "unittest": "http://schemas.sap.com/sapui5/preprocessorextension/sap.fe.unittesting/1",
65
- "control": "sap.fe.core.controls",
66
- "core": "sap.ui.core",
67
- "m": "sap.m",
68
- "f": "sap.ui.layout.form",
69
- "internalMacro": "sap.fe.macros.internal",
70
- "mdc": "sap.ui.mdc",
71
- "mdcat": "sap.ui.mdc.actiontoolbar",
72
- "mdcField": "sap.ui.mdc.field",
73
- "mdcTable": "sap.ui.mdc.table",
74
- "u": "sap.ui.unified",
75
- "macroMicroChart": "sap.fe.macros.microchart",
76
- "microChart": "sap.suite.ui.microchart",
77
- "macroTable": "sap.fe.macros.table"
63
+ macros: "sap.fe.macros",
64
+ macro: "sap.fe.macros",
65
+ macroField: "sap.fe.macros.field",
66
+ macrodata: "http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1",
67
+ log: "http://schemas.sap.com/sapui5/extension/sap.ui.core.CustomData/1",
68
+ unittest: "http://schemas.sap.com/sapui5/preprocessorextension/sap.fe.unittesting/1",
69
+ control: "sap.fe.core.controls",
70
+ core: "sap.ui.core",
71
+ dt: "sap.ui.dt",
72
+ m: "sap.m",
73
+ f: "sap.ui.layout.form",
74
+ fl: "sap.ui.fl",
75
+ internalMacro: "sap.fe.macros.internal",
76
+ mdc: "sap.ui.mdc",
77
+ mdcat: "sap.ui.mdc.actiontoolbar",
78
+ mdcField: "sap.ui.mdc.field",
79
+ mdcTable: "sap.ui.mdc.table",
80
+ u: "sap.ui.unified",
81
+ macroMicroChart: "sap.fe.macros.microchart",
82
+ microChart: "sap.suite.ui.microchart",
83
+ macroTable: "sap.fe.macros.table"
78
84
  };
79
85
  const select = xpath.useNamespaces(nameSpaceMap);
80
86
 
@@ -97,7 +103,7 @@ async function _buildPreProcessorSettings(
97
103
  // To ensure our macro can use #setBindingContext we ensure there is a pre existing JSONModel for converterContext
98
104
  // if not already passed to teh templating
99
105
  if (!mModels.hasOwnProperty("converterContext")) {
100
- mModels = Object.assign(mModels, { "converterContext": new TemplateModel({}, oMetaModel) });
106
+ mModels = Object.assign(mModels, { converterContext: new TemplateModel({}, oMetaModel) });
101
107
  }
102
108
 
103
109
  Object.keys(mModels).forEach(function (sModelName) {
@@ -196,10 +202,11 @@ export const serializeXML = function (xmlDom: Node) {
196
202
  };
197
203
 
198
204
  export const formatXML = function (xmlString: string) {
199
- return format(
200
- xmlString,
201
- { parser: "xml", xmlWhitespaceSensitivity: "ignore" } as Partial<RequiredOptions> /* options by the Prettier XML plugin */
202
- );
205
+ return format(xmlString, {
206
+ parser: "xml",
207
+ xmlWhitespaceSensitivity: "ignore",
208
+ plugins: [plugin]
209
+ } as Options & { xmlWhitespaceSensitivity: "ignore" | "strict" });
203
210
  };
204
211
 
205
212
  /**
@@ -383,12 +390,12 @@ export function evaluateBindingWithModel(
383
390
 
384
391
  const TESTVIEWID = "testViewId";
385
392
 
386
- const applyFlexChanges = async function (aVariantDependentControlChanges: any[], oMetaModel: MetaModel, resultXML: any) {
393
+ const applyFlexChanges = async function (flexChanges: { [x: string]: object[] }, oMetaModel: MetaModel, resultXML: any) {
387
394
  // prefix Ids
388
395
  [...resultXML.querySelectorAll("[id]")].forEach((node) => {
389
396
  node.id = `${TESTVIEWID}--${node.id}`;
390
397
  });
391
- const changes = createFlexibilityChangesObject(TESTVIEWID, aVariantDependentControlChanges);
398
+ const changes = createFlexibilityChangesObject(TESTVIEWID, flexChanges);
392
399
  const appId = "someComponent";
393
400
  const oManifest = {
394
401
  "sap.app": {
@@ -409,7 +416,8 @@ const applyFlexChanges = async function (aVariantDependentControlChanges: any[],
409
416
  getEntry: function (name: string) {
410
417
  return (oManifest as any)[name];
411
418
  }
412
- })
419
+ }),
420
+ getLocalId: jest.fn((sId) => sId)
413
421
  } as unknown as AppComponent;
414
422
  //fake changes
415
423
  jest.spyOn(AppStorage, "loadFlexData").mockReturnValue(Promise.resolve(changes));
@@ -422,7 +430,7 @@ const applyFlexChanges = async function (aVariantDependentControlChanges: any[],
422
430
 
423
431
  //Assert that all changes have been applied
424
432
  const changesApplied = getChangesFromXML(resultXML);
425
- expect(changesApplied.length).toBe(aVariantDependentControlChanges.length);
433
+ expect(changesApplied.length).toBe(flexChanges?.changes?.length ?? 0 + flexChanges?.variantDependentControlChanges?.length ?? 0);
426
434
  return resultXML;
427
435
  };
428
436
 
@@ -436,7 +444,7 @@ export const getTemplatingResult = async function (
436
444
  sMetadataUrl: string,
437
445
  mBindingContexts: { [x: string]: any; entitySet?: string },
438
446
  mModels: { [x: string]: any },
439
- aVariantDependentControlChanges?: any[]
447
+ flexChanges?: { [x: string]: object[] }
440
448
  ) {
441
449
  const templatedXml = `<root>${xmlInput}</root>`;
442
450
  const parser = new window.DOMParser();
@@ -454,9 +462,9 @@ export const getTemplatingResult = async function (
454
462
 
455
463
  let resultXML = (await XMLPreprocessor.process(xmlDoc.firstElementChild!, { name: "Test Fragment" }, oPreprocessorSettings)) as any;
456
464
 
457
- if (aVariantDependentControlChanges) {
465
+ if (flexChanges) {
458
466
  // apply flex changes
459
- resultXML = await applyFlexChanges(aVariantDependentControlChanges, oMetaModel, resultXML);
467
+ resultXML = await applyFlexChanges(flexChanges, oMetaModel, resultXML);
460
468
  }
461
469
  return resultXML;
462
470
  };
@@ -466,9 +474,9 @@ export const getTemplatedXML = async function (
466
474
  sMetadataUrl: string,
467
475
  mBindingContexts: { [x: string]: string },
468
476
  mModels: { [x: string]: any },
469
- aVariantDependentControlChanges?: any[]
477
+ flexChanges?: { [x: string]: object[] }
470
478
  ) {
471
- const templatedXML = await getTemplatingResult(xmlInput, sMetadataUrl, mBindingContexts, mModels, aVariantDependentControlChanges);
479
+ const templatedXML = await getTemplatingResult(xmlInput, sMetadataUrl, mBindingContexts, mModels, flexChanges);
472
480
  return serializeXML(templatedXML);
473
481
  };
474
482
 
@@ -479,7 +487,7 @@ export const getTemplatedXML = async function (
479
487
  * @param sMetadataUrl Url of the metadata.
480
488
  * @param mBindingContexts Map of the bindingContexts to set on the models.
481
489
  * @param mModels Map of the models.
482
- * @param aVariantDependentControlChanges
490
+ * @param flexChanges Object with UI changes like 'changes' or 'variantDependentControlChanges'
483
491
  * @returns Templated view as string
484
492
  */
485
493
  export async function processView(
@@ -487,14 +495,14 @@ export async function processView(
487
495
  sMetadataUrl: string,
488
496
  mBindingContexts: { [x: string]: string },
489
497
  mModels: { [x: string]: any },
490
- aVariantDependentControlChanges?: any[]
498
+ flexChanges?: { [x: string]: object[] }
491
499
  ): Promise<JestTemplatedView> {
492
500
  const oMetaModel = await getMetaModel(sMetadataUrl);
493
501
  const oViewDocument = _loadResourceView(name);
494
502
  const oPreprocessorSettings = await _buildPreProcessorSettings(sMetadataUrl, mBindingContexts, mModels);
495
503
  let oPreprocessedView = await XMLPreprocessor.process(oViewDocument, { name: name }, oPreprocessorSettings);
496
- if (aVariantDependentControlChanges) {
497
- oPreprocessedView = await applyFlexChanges(aVariantDependentControlChanges || [], oMetaModel, oPreprocessedView);
504
+ if (flexChanges) {
505
+ oPreprocessedView = await applyFlexChanges(flexChanges ?? [], oMetaModel, oPreprocessedView);
498
506
  }
499
507
  return {
500
508
  asElement: oPreprocessedView,
@@ -570,7 +578,8 @@ export function serializeControl(controlToSerialize: Control | Control[]) {
570
578
  return "})";
571
579
  },
572
580
  middle: function (control: any) {
573
- let data = `{id: ${control.getId()}`;
581
+ const id = control.getId();
582
+ let data = `{id: ${ManagedObjectMetadata.isGeneratedId(id) ? "__dynamicId" : id}`;
574
583
  for (const oControlKey in control.mProperties) {
575
584
  if (control.mProperties.hasOwnProperty(oControlKey)) {
576
585
  data += `,\n${getTab()} ${oControlKey}: ${control.mProperties[oControlKey]}`;
@@ -586,6 +595,11 @@ export function serializeControl(controlToSerialize: Control | Control[]) {
586
595
  data += `,\n${getTab()} ${oControlKey}: ${control.mAssociations[oControlKey][0]}`;
587
596
  }
588
597
  }
598
+ for (const oControlKey in control.mEventRegistry) {
599
+ if (control.mEventRegistry.hasOwnProperty(oControlKey)) {
600
+ data += `,\n${getTab()} ${oControlKey}: true}`;
601
+ }
602
+ }
589
603
  data += ``;
590
604
  return data;
591
605
  },
@@ -1,7 +1,8 @@
1
1
  /*
2
- * ! SAP UI development toolkit for HTML5 (SAPUI5)
2
+ * !
3
+ SAP UI development toolkit for HTML5 (SAPUI5)
3
4
  (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
5
+
5
6
  */
6
7
  /* global QUnit */
7
8
  sap.ui.define(
@@ -1,7 +1,8 @@
1
1
  /*
2
- * ! SAP UI development toolkit for HTML5 (SAPUI5)
2
+ * !
3
+ SAP UI development toolkit for HTML5 (SAPUI5)
3
4
  (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
5
+
5
6
  */
6
7
  sap.ui.define(
7
8
  [
@@ -1,7 +1,8 @@
1
1
  /*
2
- * ! SAP UI development toolkit for HTML5 (SAPUI5)
2
+ * !
3
+ SAP UI development toolkit for HTML5 (SAPUI5)
3
4
  (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
5
+
5
6
  */
6
7
  sap.ui.define(["sap/ui/test/OpaBuilder", "sap/ui/test/Opa5", "sap/fe/test/Utils"], function (OpaBuilder, Opa5, Utils) {
7
8
  "use strict";
@@ -1,7 +1,8 @@
1
1
  /*
2
- * ! SAP UI development toolkit for HTML5 (SAPUI5)
2
+ * !
3
+ SAP UI development toolkit for HTML5 (SAPUI5)
3
4
  (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
5
+
5
6
  */
6
7
  sap.ui.define(
7
8
  [
@@ -114,6 +115,36 @@ sap.ui.define(
114
115
  .description(Utils.formatMessage("Executing action '{0}' from currently open action menu", vMenuAction));
115
116
  }
116
117
 
118
+ function _getObjectPageSectionSubSectionBuilder(vOpaInstance, SectionSubSectionIdentifier, SectionSubSectionIdPrefix, ControlType) {
119
+ var SectionSubSectionBuilder = FEBuilder.create(vOpaInstance).hasType(ControlType);
120
+ if (Utils.isOfType(SectionSubSectionIdentifier, String)) {
121
+ SectionSubSectionBuilder.hasProperties({ title: SectionSubSectionIdentifier });
122
+ } else if (SectionSubSectionIdentifier.section) {
123
+ SectionSubSectionBuilder.hasId(SectionSubSectionIdPrefix + "::" + SectionSubSectionIdentifier.section);
124
+ } else {
125
+ throw new Error(
126
+ "section or sub-section parameters not supported for creating a control id: " + SectionSubSectionIdentifier
127
+ );
128
+ }
129
+ return SectionSubSectionBuilder;
130
+ }
131
+ function _getObjectPageSectionBuilder(vOpaInstance, ObjectPageSectionIdentifier, OPSectionIdPrefix) {
132
+ return _getObjectPageSectionSubSectionBuilder(
133
+ vOpaInstance,
134
+ ObjectPageSectionIdentifier,
135
+ OPSectionIdPrefix,
136
+ "sap.uxap.ObjectPageSection"
137
+ );
138
+ }
139
+ function _getObjectPageSubSectionBuilder(vOpaInstance, ObjectPageSubSectionIdentifier, OPSubSectionIdPrefix) {
140
+ return _getObjectPageSectionSubSectionBuilder(
141
+ vOpaInstance,
142
+ ObjectPageSubSectionIdentifier,
143
+ OPSubSectionIdPrefix,
144
+ "sap.uxap.ObjectPageSubSection"
145
+ );
146
+ }
147
+
117
148
  /**
118
149
  * Constructs a new ObjectPage instance.
119
150
  *
@@ -439,14 +470,14 @@ sap.ui.define(
439
470
  iClickOnMessageButton: function () {
440
471
  return OpaBuilder.create(this)
441
472
 
442
- .hasType("sap.fe.common.MessageButton")
473
+ .hasType("sap.fe.macros.messages.MessageButton")
443
474
  .doPress()
444
475
  .description("Clicked on Message Button")
445
476
  .execute();
446
477
  },
447
478
  iCheckMessageButtonTooltip: function (sText) {
448
479
  return OpaBuilder.create(this)
449
- .hasType("sap.fe.common.MessageButton")
480
+ .hasType("sap.fe.macros.messages.MessageButton")
450
481
  .check(function (oControl) {
451
482
  return oControl[0].getTooltip() === sText;
452
483
  }, true)
@@ -590,17 +621,17 @@ sap.ui.define(
590
621
  iSeeMessageButton: function (messageType, messageButtonText) {
591
622
  var message = {
592
623
  Error: {
593
- "type": "Negative"
624
+ type: "Negative"
594
625
  },
595
626
  Warning: {
596
- "type": "Critical"
627
+ type: "Critical"
597
628
  },
598
629
  Information: {
599
- "type": "Neutral"
630
+ type: "Neutral"
600
631
  }
601
632
  };
602
633
  return OpaBuilder.create(this)
603
- .hasType("sap.fe.common.MessageButton")
634
+ .hasType("sap.fe.macros.messages.MessageButton")
604
635
  .hasProperties({
605
636
  text: messageButtonText,
606
637
  type: message[messageType]["type"]
@@ -684,20 +715,93 @@ sap.ui.define(
684
715
  .description("Object Page is in mode '" + sMode + "'")
685
716
  .execute();
686
717
  },
718
+ /**
719
+ * Checks a section.
720
+ * It is checked if a section is already loaded and therefore the data is visible to the user. This function does not check properties of the anchor bar buttons for section selection.
721
+ *
722
+ * @param {string | sap.fe.test.api.SectionIdentifier} SectionIdentifier The identifier of the section.
723
+ * This can either be a string containing the label of the section or an object having the pattern
724
+ * <code><pre>
725
+ * {
726
+ * section: <section id>
727
+ * }
728
+ * </pre></code>
729
+ * @param {object} mState Defines the expected state of the section, e.g. its visibility
730
+ * @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, to be used for chained statements
731
+ * @public
732
+ */
733
+ iCheckSection: function (SectionIdentifier, mState) {
734
+ var SectionBuilder = _getObjectPageSectionBuilder(this, SectionIdentifier, OPSectionIdPrefix);
735
+ return SectionBuilder.hasState(mState)
736
+ .description(
737
+ Utils.formatMessage("Checking section '{0}' having state='{1}'", SectionIdentifier, mState)
738
+ )
739
+ .execute();
740
+ },
741
+ /**
742
+ * TODO This function is only here for legacy reasons and therefore private. Use iCheckSection instead.
743
+ *
744
+ * @param {string} sTitle The name of the section
745
+ * @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, to be used for chained statements
746
+ * @private
747
+ */
687
748
  iSeeSectionWithTitle: function (sTitle) {
688
- return OpaBuilder.create(this)
689
- .hasType("sap.uxap.ObjectPageSection")
690
- .hasProperties({ title: sTitle })
691
- .description("Seeing section with title '" + sTitle + "'")
749
+ return this.iCheckSection(sTitle, { visible: true });
750
+ },
751
+
752
+ /**
753
+ * Checks the expected number of sections in an object page.
754
+ *
755
+ * @param {number} ExpectedNumberOfSections The number of expected sections within the object page.
756
+ * @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, to be used for chained statements
757
+ * @public
758
+ */
759
+ iCheckNumberOfSections: function (ExpectedNumberOfSections) {
760
+ return FEBuilder.create(this)
761
+ .hasId(AnchorBarId)
762
+ .hasAggregationLength("content", ExpectedNumberOfSections)
763
+ .description(
764
+ Utils.formatMessage(
765
+ "Object Page contains the expected number of {0} sections",
766
+ ExpectedNumberOfSections
767
+ )
768
+ )
692
769
  .execute();
693
770
  },
694
- iSeeSubSectionWithTitle: function (sTitle) {
695
- return OpaBuilder.create(this)
696
- .hasType("sap.uxap.ObjectPageSubSection")
697
- .hasProperties({ title: sTitle })
698
- .description("Seeing sub-section with title '" + sTitle + "'")
771
+
772
+ /**
773
+ * Checks a sub-section.
774
+ *
775
+ * @param {string | sap.fe.test.api.SectionIdentifier} SubSectionIdentifier The identifier of the sub-section to be checked for visibility.
776
+ * This can either be a string containing the label of the sub-section or an object having the pattern
777
+ * <code><pre>
778
+ * {
779
+ * section: <sub-section id>
780
+ * }
781
+ * </pre></code>
782
+ * @param {object} mState Defines the expected state of the sub-section, e.g. its visibility
783
+ * @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, to be used for chained statements
784
+ * @public
785
+ */
786
+ iCheckSubSection: function (SubSectionIdentifier, mState) {
787
+ var SubSectionBuilder = _getObjectPageSubSectionBuilder(this, SubSectionIdentifier, OPSubSectionIdPrefix);
788
+ return SubSectionBuilder.hasState(mState)
789
+ .description(
790
+ Utils.formatMessage("Checking sub-section '{0}' having state='{1}'", SubSectionIdentifier, mState)
791
+ )
699
792
  .execute();
700
793
  },
794
+ /**
795
+ * TODO This function is only here for legacy reasons and therefore private. Use iCheckSubSection instead.
796
+ *
797
+ * @param {string} sTitle The name of the sub-section
798
+ * @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, to be used for chained statements
799
+ * @private
800
+ */
801
+ iSeeSubSectionWithTitle: function (sTitle) {
802
+ return this.iCheckSubSection(sTitle, { visible: true });
803
+ },
804
+
701
805
  iSeeSectionButtonWithTitle: function (sTitle, mState) {
702
806
  return FEBuilder.create(this)
703
807
  .hasId(AnchorBarId)
@@ -1,7 +1,8 @@
1
1
  /*
2
- * ! SAP UI development toolkit for HTML5 (SAPUI5)
2
+ * !
3
+ SAP UI development toolkit for HTML5 (SAPUI5)
3
4
  (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
5
+
5
6
  */
6
7
  sap.ui.define(["sap/ui/test/OpaBuilder", "sap/ui/test/Opa5", "sap/fe/test/Utils"], function (OpaBuilder, Opa5, Utils) {
7
8
  "use strict";
@@ -57,15 +58,19 @@ sap.ui.define(["sap/ui/test/OpaBuilder", "sap/ui/test/Opa5", "sap/fe/test/Utils"
57
58
  /**
58
59
  * Opens the navigation menu in the shell header.
59
60
  *
61
+ * @param {string} [NavigationTitle] The title of the navigation menu to be clicked. If undefined the menu is identified by the internal id only.
60
62
  * @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, to be used for chained statements
61
63
  * @function
62
64
  * @name sap.fe.test.Shell#iOpenNavigationMenu
63
65
  * @public
64
66
  */
65
- iOpenNavigationMenu: function () {
67
+ iOpenNavigationMenu: function (NavigationTitle) {
66
68
  return OpaBuilder.create(this)
67
69
  .pollingInterval(1000) // the shell needs some time to prepare the navigation menu
68
70
  .hasId("shellAppTitle")
71
+ .has(function (oShellObject) {
72
+ return NavigationTitle ? oShellObject.getText() === NavigationTitle : true;
73
+ })
69
74
  .doPress()
70
75
  .description("Expanding Shell Navigation Menu")
71
76
  .execute();
@@ -112,7 +117,7 @@ sap.ui.define(["sap/ui/test/OpaBuilder", "sap/ui/test/Opa5", "sap/fe/test/Utils"
112
117
  },
113
118
  iOpenDefaultValues: function () {
114
119
  return OpaBuilder.create(this)
115
- .hasId("meAreaHeaderButton")
120
+ .hasId("userActionsMenuHeaderButton")
116
121
  .doPress()
117
122
  .description("Opening FLP Default Values dialog")
118
123
  .execute();
@@ -1,42 +1,43 @@
1
1
  /*
2
- * ! SAP UI development toolkit for HTML5 (SAPUI5)
2
+ * !
3
+ SAP UI development toolkit for HTML5 (SAPUI5)
3
4
  (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
5
+
5
6
  */
6
7
  /**
7
8
  * Actions and assertions to be used with a page hosted in an FCL
8
9
  */
9
- sap.ui.define(["sap/ui/test/OpaBuilder"], function(OpaBuilder) {
10
+ sap.ui.define(["sap/ui/test/OpaBuilder"], function (OpaBuilder) {
10
11
  "use strict";
11
12
  var Stubs = {
12
- prepareStubs: function(oWindow) {
13
+ prepareStubs: function (oWindow) {
13
14
  if (!oWindow.sapFEStubs) {
14
15
  oWindow.sapFEStubs = {};
15
16
  }
16
17
  },
17
18
 
18
- stubAll: function(oWindow) {
19
+ stubAll: function (oWindow) {
19
20
  this.stubConfirm(oWindow);
20
21
  this.stubMessageToast(oWindow);
21
22
  this.stubMisc(oWindow);
22
23
  },
23
24
 
24
- restoreAll: function(oWindow) {
25
+ restoreAll: function (oWindow) {
25
26
  this.restoreConfirm(oWindow);
26
27
  this.restoreMessageToast(oWindow);
27
28
  this.restoreMisc(oWindow);
28
29
  },
29
30
 
30
- stubConfirm: function(oWindow) {
31
+ stubConfirm: function (oWindow) {
31
32
  Stubs.prepareStubs(oWindow);
32
33
 
33
34
  oWindow.sapFEStubs._confirmOriginal = oWindow.confirm;
34
- oWindow.confirm = function(sMessage) {
35
+ oWindow.confirm = function (sMessage) {
35
36
  throw "Unexpected confirm dialog - " + sMessage;
36
37
  };
37
38
  },
38
39
 
39
- restoreConfirm: function(oWindow) {
40
+ restoreConfirm: function (oWindow) {
40
41
  if (!oWindow.sapFEStubs || !oWindow.sapFEStubs._confirmOriginal) {
41
42
  return;
42
43
  }
@@ -44,22 +45,22 @@ sap.ui.define(["sap/ui/test/OpaBuilder"], function(OpaBuilder) {
44
45
  delete oWindow.sapFEStubs._confirmOriginal;
45
46
  },
46
47
 
47
- stubMessageToast: function(oWindow) {
48
+ stubMessageToast: function (oWindow) {
48
49
  Stubs.prepareStubs(oWindow);
49
50
  var oMessageToast = oWindow.sap.ui.require("sap/m/MessageToast");
50
51
  oWindow.sapFEStubs._sapMMessageToastShowOriginal = oMessageToast.show;
51
- oWindow.sapFEStubs.setLastToastMessage = function(sMessage) {
52
+ oWindow.sapFEStubs.setLastToastMessage = function (sMessage) {
52
53
  oWindow.sapFEStubs._sapMMessageToastLastMessage = sMessage;
53
54
  };
54
- oWindow.sapFEStubs.getLastToastMessage = function() {
55
+ oWindow.sapFEStubs.getLastToastMessage = function () {
55
56
  return oWindow.sapFEStubs._sapMMessageToastLastMessage;
56
57
  };
57
- oMessageToast.show = function(sMessage) {
58
+ oMessageToast.show = function (sMessage) {
58
59
  oWindow.sapFEStubs.setLastToastMessage(sMessage);
59
60
  return oWindow.sapFEStubs._sapMMessageToastShowOriginal.apply(this, arguments);
60
61
  };
61
62
  },
62
- restoreMessageToast: function(oWindow) {
63
+ restoreMessageToast: function (oWindow) {
63
64
  if (!oWindow.sapFEStubs || !oWindow.sapFEStubs._sapMMessageToastShowOriginal) {
64
65
  return;
65
66
  }
@@ -71,18 +72,18 @@ sap.ui.define(["sap/ui/test/OpaBuilder"], function(OpaBuilder) {
71
72
  delete oWindow.sapFEStubs.getLastToastMessage;
72
73
  },
73
74
 
74
- stubMisc: function(oWindow) {
75
+ stubMisc: function (oWindow) {
75
76
  Stubs.prepareStubs(oWindow);
76
77
 
77
78
  // TODO workaround
78
79
  // pressing Enter in the creation row triggers creation of a new row, but we need Enter key for value validation
79
- oWindow.sap.ui.require(["sap/ui/table/CreationRow"], function(oCreationRow) {
80
+ oWindow.sap.ui.require(["sap/ui/table/CreationRow"], function (oCreationRow) {
80
81
  oWindow.sapFEStubs._sapUiTableCreationRowOnSapEnter = oCreationRow.prototype.onsapenter;
81
82
  delete oCreationRow.prototype.onsapenter;
82
83
  });
83
84
  },
84
85
 
85
- restoreMisc: function(oWindow) {
86
+ restoreMisc: function (oWindow) {
86
87
  if (!oWindow.sapFEStubs || !oWindow.sapFEStubs._sapUiTableCreationRowOnSapEnter) {
87
88
  return;
88
89
  }
@@ -1,7 +1,8 @@
1
1
  /*
2
- * ! SAP UI development toolkit for HTML5 (SAPUI5)
2
+ * !
3
+ SAP UI development toolkit for HTML5 (SAPUI5)
3
4
  (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
5
+
5
6
  */
6
7
  sap.ui.define(
7
8
  [
@@ -1,7 +1,8 @@
1
1
  /*
2
- * ! SAP UI development toolkit for HTML5 (SAPUI5)
2
+ * !
3
+ SAP UI development toolkit for HTML5 (SAPUI5)
3
4
  (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
5
+
5
6
  */
6
7
  sap.ui.define(
7
8
  [