@openui5/sap.ui.core 1.112.2 → 1.114.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 (400) hide show
  1. package/.dtsgenrc +102 -1
  2. package/THIRDPARTY.txt +1 -1
  3. package/package.json +1 -1
  4. package/src/jquery.sap.global.js +10 -4
  5. package/src/jquery.sap.properties.js +1 -1
  6. package/src/jquery.sap.resources.js +1 -1
  7. package/src/jquery.sap.script.js +1 -1
  8. package/src/jquery.sap.storage.js +7 -7
  9. package/src/jquery.sap.trace.js +14 -14
  10. package/src/sap/base/Log.js +92 -8
  11. package/src/sap/base/assert.js +1 -1
  12. package/src/sap/base/config/MemoryConfigurationProvider.js +22 -0
  13. package/src/sap/base/config.js +54 -0
  14. package/src/sap/base/security/URLWhitelist.js +1 -1
  15. package/src/sap/base/util/Deferred.js +3 -2
  16. package/src/sap/base/util/restricted/_CancelablePromise.js +2 -2
  17. package/src/sap/base/util/restricted/_castArray.js +1 -1
  18. package/src/sap/base/util/restricted/_compact.js +1 -1
  19. package/src/sap/base/util/restricted/_curry.js +1 -1
  20. package/src/sap/base/util/restricted/_debounce.js +1 -1
  21. package/src/sap/base/util/restricted/_difference.js +1 -1
  22. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  23. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  24. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  25. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  26. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  27. package/src/sap/base/util/restricted/_flatten.js +1 -1
  28. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  29. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  30. package/src/sap/base/util/restricted/_intersection.js +1 -1
  31. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  32. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  33. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  34. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  35. package/src/sap/base/util/restricted/_isNil.js +1 -1
  36. package/src/sap/base/util/restricted/_max.js +1 -1
  37. package/src/sap/base/util/restricted/_merge.js +1 -1
  38. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  39. package/src/sap/base/util/restricted/_min.js +1 -1
  40. package/src/sap/base/util/restricted/_omit.js +1 -1
  41. package/src/sap/base/util/restricted/_pick.js +1 -1
  42. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  43. package/src/sap/base/util/restricted/_throttle.js +1 -1
  44. package/src/sap/base/util/restricted/_toArray.js +1 -1
  45. package/src/sap/base/util/restricted/_union.js +1 -1
  46. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  47. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  48. package/src/sap/base/util/restricted/_uniq.js +1 -1
  49. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  50. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  51. package/src/sap/base/util/restricted/_without.js +1 -1
  52. package/src/sap/base/util/restricted/_xor.js +1 -1
  53. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  54. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  55. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  56. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  57. package/src/sap/ui/Device.js +8 -3
  58. package/src/sap/ui/Global.js +4 -4
  59. package/src/sap/ui/base/BindingParser.js +79 -18
  60. package/src/sap/ui/base/Event.js +1 -1
  61. package/src/sap/ui/base/EventProvider.js +1 -1
  62. package/src/sap/ui/base/ExpressionParser.js +15 -5
  63. package/src/sap/ui/base/Interface.js +1 -1
  64. package/src/sap/ui/base/ManagedObject.js +16 -13
  65. package/src/sap/ui/base/ManagedObjectMetadata.js +35 -35
  66. package/src/sap/ui/base/Metadata.js +23 -12
  67. package/src/sap/ui/base/Object.js +1 -1
  68. package/src/sap/ui/base/ObjectPool.js +1 -1
  69. package/src/sap/ui/core/.library +1 -1
  70. package/src/sap/ui/core/BusyIndicator.js +4 -4
  71. package/src/sap/ui/core/Component.js +10 -7
  72. package/src/sap/ui/core/ComponentContainer.js +1 -1
  73. package/src/sap/ui/core/ComponentMetadata.js +3 -1
  74. package/src/sap/ui/core/ComponentSupport.js +1 -1
  75. package/src/sap/ui/core/Configuration.js +104 -45
  76. package/src/sap/ui/core/Control.js +23 -6
  77. package/src/sap/ui/core/Core.js +36 -15
  78. package/src/sap/ui/core/CustomData.js +1 -1
  79. package/src/sap/ui/core/CustomStyleClassSupport.js +5 -2
  80. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  81. package/src/sap/ui/core/Element.js +1 -1
  82. package/src/sap/ui/core/ElementMetadata.js +19 -4
  83. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  84. package/src/sap/ui/core/EventBus.js +4 -4
  85. package/src/sap/ui/core/Fragment.js +1 -1
  86. package/src/sap/ui/core/HTML.js +1 -1
  87. package/src/sap/ui/core/History.js +1 -1
  88. package/src/sap/ui/core/Icon.js +1 -1
  89. package/src/sap/ui/core/IconPool.js +17 -2
  90. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  91. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  92. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  93. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  94. package/src/sap/ui/core/InvisibleText.js +1 -1
  95. package/src/sap/ui/core/Item.js +1 -1
  96. package/src/sap/ui/core/LabelEnablement.js +10 -2
  97. package/src/sap/ui/core/LayoutData.js +1 -1
  98. package/src/sap/ui/core/Lib.js +28 -2
  99. package/src/sap/ui/core/ListItem.js +1 -1
  100. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  101. package/src/sap/ui/core/Locale.js +2 -2
  102. package/src/sap/ui/core/LocaleData.js +87 -19
  103. package/src/sap/ui/core/Manifest.js +5 -5
  104. package/src/sap/ui/core/Message.js +1 -1
  105. package/src/sap/ui/core/Popup.js +34 -36
  106. package/src/sap/ui/core/RenderManager.js +8 -2
  107. package/src/sap/ui/core/Renderer.js +1 -1
  108. package/src/sap/ui/core/Rendering.js +2 -3
  109. package/src/sap/ui/core/ResizeHandler.js +2 -2
  110. package/src/sap/ui/core/ScrollBar.js +1 -1
  111. package/src/sap/ui/core/SeparatorItem.js +1 -1
  112. package/src/sap/ui/core/Title.js +1 -1
  113. package/src/sap/ui/core/TooltipBase.js +1 -1
  114. package/src/sap/ui/core/UIArea.js +9 -2
  115. package/src/sap/ui/core/UIComponent.js +16 -13
  116. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  117. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  118. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  119. package/src/sap/ui/core/XMLComposite.js +1 -1
  120. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  121. package/src/sap/ui/core/XMLTemplateProcessor.js +30 -6
  122. package/src/sap/ui/core/cache/CacheManager.js +1 -1
  123. package/src/sap/ui/core/cache/LRUPersistentCache.js +1 -1
  124. package/src/sap/ui/core/date/CalendarUtils.js +14 -26
  125. package/src/sap/ui/core/date/CalendarWeekNumbering.js +32 -0
  126. package/src/sap/ui/core/date/UI5Date.js +14 -8
  127. package/src/sap/ui/core/date/UniversalDate.js +15 -53
  128. package/src/sap/ui/core/date/UniversalDateUtils.js +4 -4
  129. package/src/sap/ui/core/date/_Calendars.js +1 -1
  130. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  131. package/src/sap/ui/core/delegate/ScrollEnablement.js +1 -1
  132. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  133. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  134. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  135. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  136. package/src/sap/ui/core/format/DateFormat.js +166 -59
  137. package/src/sap/ui/core/format/NumberFormat.js +40 -5
  138. package/src/sap/ui/core/format/TimezoneUtil.js +1 -1
  139. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  140. package/src/sap/ui/core/library.js +3 -3
  141. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  142. package/src/sap/ui/core/message/Message.js +1 -1
  143. package/src/sap/ui/core/message/MessageManager.js +1 -1
  144. package/src/sap/ui/core/message/MessageParser.js +1 -1
  145. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  146. package/src/sap/ui/core/messagebundle.properties +2 -0
  147. package/src/sap/ui/core/messagebundle_ar.properties +2 -1
  148. package/src/sap/ui/core/messagebundle_bg.properties +1 -0
  149. package/src/sap/ui/core/messagebundle_ca.properties +1 -0
  150. package/src/sap/ui/core/messagebundle_cs.properties +2 -1
  151. package/src/sap/ui/core/messagebundle_cy.properties +2 -1
  152. package/src/sap/ui/core/messagebundle_da.properties +2 -1
  153. package/src/sap/ui/core/messagebundle_de.properties +2 -1
  154. package/src/sap/ui/core/messagebundle_el.properties +2 -1
  155. package/src/sap/ui/core/messagebundle_en.properties +2 -1
  156. package/src/sap/ui/core/messagebundle_en_GB.properties +2 -1
  157. package/src/sap/ui/core/messagebundle_en_US_sappsd.properties +1 -0
  158. package/src/sap/ui/core/messagebundle_en_US_saprigi.properties +1 -0
  159. package/src/sap/ui/core/messagebundle_es.properties +5 -4
  160. package/src/sap/ui/core/messagebundle_es_MX.properties +2 -1
  161. package/src/sap/ui/core/messagebundle_et.properties +2 -1
  162. package/src/sap/ui/core/messagebundle_fi.properties +2 -1
  163. package/src/sap/ui/core/messagebundle_fr.properties +2 -1
  164. package/src/sap/ui/core/messagebundle_fr_CA.properties +2 -1
  165. package/src/sap/ui/core/messagebundle_hi.properties +2 -1
  166. package/src/sap/ui/core/messagebundle_hr.properties +2 -1
  167. package/src/sap/ui/core/messagebundle_hu.properties +2 -1
  168. package/src/sap/ui/core/messagebundle_id.properties +2 -1
  169. package/src/sap/ui/core/messagebundle_it.properties +2 -1
  170. package/src/sap/ui/core/messagebundle_iw.properties +2 -1
  171. package/src/sap/ui/core/messagebundle_ja.properties +1 -0
  172. package/src/sap/ui/core/messagebundle_kk.properties +2 -1
  173. package/src/sap/ui/core/messagebundle_ko.properties +2 -1
  174. package/src/sap/ui/core/messagebundle_lt.properties +2 -1
  175. package/src/sap/ui/core/messagebundle_lv.properties +2 -1
  176. package/src/sap/ui/core/messagebundle_ms.properties +2 -1
  177. package/src/sap/ui/core/messagebundle_nl.properties +2 -1
  178. package/src/sap/ui/core/messagebundle_no.properties +2 -1
  179. package/src/sap/ui/core/messagebundle_pl.properties +2 -1
  180. package/src/sap/ui/core/messagebundle_pt.properties +2 -1
  181. package/src/sap/ui/core/messagebundle_pt_PT.properties +2 -1
  182. package/src/sap/ui/core/messagebundle_ro.properties +2 -1
  183. package/src/sap/ui/core/messagebundle_ru.properties +3 -2
  184. package/src/sap/ui/core/messagebundle_sh.properties +2 -1
  185. package/src/sap/ui/core/messagebundle_sk.properties +2 -1
  186. package/src/sap/ui/core/messagebundle_sl.properties +2 -1
  187. package/src/sap/ui/core/messagebundle_sv.properties +2 -1
  188. package/src/sap/ui/core/messagebundle_th.properties +2 -1
  189. package/src/sap/ui/core/messagebundle_tr.properties +2 -1
  190. package/src/sap/ui/core/messagebundle_uk.properties +2 -1
  191. package/src/sap/ui/core/messagebundle_vi.properties +2 -1
  192. package/src/sap/ui/core/messagebundle_zh_CN.properties +2 -1
  193. package/src/sap/ui/core/messagebundle_zh_TW.properties +2 -1
  194. package/src/sap/ui/core/mvc/Controller.js +2 -3
  195. package/src/sap/ui/core/mvc/ControllerExtension.js +1 -1
  196. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  197. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  198. package/src/sap/ui/core/mvc/JSView.js +1 -1
  199. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  200. package/src/sap/ui/core/mvc/View.js +24 -17
  201. package/src/sap/ui/core/mvc/XMLView.js +2 -2
  202. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  203. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  204. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  205. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  206. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  207. package/src/sap/ui/core/routing/Route.js +30 -22
  208. package/src/sap/ui/core/routing/Router.js +5 -3
  209. package/src/sap/ui/core/routing/Target.js +170 -3
  210. package/src/sap/ui/core/routing/Targets.js +5 -214
  211. package/src/sap/ui/core/routing/Views.js +1 -1
  212. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  213. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  214. package/src/sap/ui/core/service/Service.js +1 -1
  215. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  216. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  217. package/src/sap/ui/core/support/Plugin.js +1 -1
  218. package/src/sap/ui/core/support/Support.js +1 -1
  219. package/src/sap/ui/core/support/controls/InteractionTree.js +5 -3
  220. package/src/sap/ui/core/support/plugins/Breakpoint.js +2 -2
  221. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  222. package/src/sap/ui/core/support/plugins/Interaction.js +6 -4
  223. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  224. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  225. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  226. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  227. package/src/sap/ui/core/support/plugins/Trace.js +4 -3
  228. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  229. package/src/sap/ui/core/themes/base/base.less +4358 -78
  230. package/src/sap/ui/core/themes/base/global.less +114 -8
  231. package/src/sap/ui/core/themes/sap_hcb/global.less +114 -8
  232. package/src/sap/ui/core/theming/Parameters.js +10 -2
  233. package/src/sap/ui/core/theming/ThemeManager.js +16 -12
  234. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  235. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  236. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  237. package/src/sap/ui/core/tmpl/Template.js +1 -1
  238. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  239. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  240. package/src/sap/ui/core/util/Export.js +1 -1
  241. package/src/sap/ui/core/util/ExportCell.js +1 -1
  242. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  243. package/src/sap/ui/core/util/ExportRow.js +1 -1
  244. package/src/sap/ui/core/util/ExportType.js +1 -1
  245. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  246. package/src/sap/ui/core/util/File.js +1 -1
  247. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  248. package/src/sap/ui/core/util/MockServer.js +1 -1
  249. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  250. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  251. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  252. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  253. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  254. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  255. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  256. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  257. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  258. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  259. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  260. package/src/sap/ui/debug/ControlTree.js +1 -1
  261. package/src/sap/ui/debug/DebugEnv.js +1 -1
  262. package/src/sap/ui/debug/PropertyList.js +1 -1
  263. package/src/sap/ui/dom/includeScript.js +3 -3
  264. package/src/sap/ui/dom/includeStylesheet.js +3 -3
  265. package/src/sap/ui/events/ControlEvents.js +2 -2
  266. package/src/sap/ui/events/PseudoEvents.js +4 -2
  267. package/src/sap/ui/model/ClientModel.js +1 -1
  268. package/src/sap/ui/model/CompositeBinding.js +1 -1
  269. package/src/sap/ui/model/CompositeDataState.js +1 -1
  270. package/src/sap/ui/model/CompositeType.js +1 -1
  271. package/src/sap/ui/model/DataState.js +1 -1
  272. package/src/sap/ui/model/ManagedObjectBindingSupport.js +19 -2
  273. package/src/sap/ui/model/MetaModel.js +1 -1
  274. package/src/sap/ui/model/Model.js +1 -1
  275. package/src/sap/ui/model/SelectionModel.js +1 -1
  276. package/src/sap/ui/model/SimpleType.js +7 -3
  277. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  278. package/src/sap/ui/model/Type.js +1 -1
  279. package/src/sap/ui/model/base/ManagedObjectModel.js +12 -4
  280. package/src/sap/ui/model/controlhelper/TreeBindingProxy.js +2 -0
  281. package/src/sap/ui/model/json/JSONModel.js +1 -1
  282. package/src/sap/ui/model/message/MessageModel.js +1 -1
  283. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  284. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  285. package/src/sap/ui/model/odata/ODataMetaModel.js +1 -1
  286. package/src/sap/ui/model/odata/ODataMetadata.js +1 -1
  287. package/src/sap/ui/model/odata/ODataModel.js +1 -1
  288. package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +1 -1
  289. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  290. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  291. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  292. package/src/sap/ui/model/odata/type/Date.js +67 -21
  293. package/src/sap/ui/model/odata/type/DateTime.js +51 -8
  294. package/src/sap/ui/model/odata/type/DateTimeBase.js +55 -26
  295. package/src/sap/ui/model/odata/type/DateTimeOffset.js +42 -1
  296. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +37 -21
  297. package/src/sap/ui/model/odata/type/Decimal.js +28 -33
  298. package/src/sap/ui/model/odata/type/Double.js +21 -26
  299. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  300. package/src/sap/ui/model/odata/type/Int.js +15 -20
  301. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  302. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  303. package/src/sap/ui/model/odata/type/Int64.js +16 -21
  304. package/src/sap/ui/model/odata/type/ODataType.js +33 -6
  305. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  306. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  307. package/src/sap/ui/model/odata/type/Single.js +20 -25
  308. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  309. package/src/sap/ui/model/odata/type/String.js +1 -1
  310. package/src/sap/ui/model/odata/type/Time.js +91 -21
  311. package/src/sap/ui/model/odata/type/TimeOfDay.js +70 -24
  312. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  313. package/src/sap/ui/model/odata/v2/Context.js +72 -28
  314. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +5 -4
  315. package/src/sap/ui/model/odata/v2/ODataListBinding.js +29 -10
  316. package/src/sap/ui/model/odata/v2/ODataModel.js +92 -36
  317. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +8 -1
  318. package/src/sap/ui/model/odata/v4/Context.js +36 -21
  319. package/src/sap/ui/model/odata/v4/ODataBinding.js +50 -21
  320. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +7 -25
  321. package/src/sap/ui/model/odata/v4/ODataListBinding.js +208 -74
  322. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +4 -1
  323. package/src/sap/ui/model/odata/v4/ODataModel.js +4 -3
  324. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +42 -28
  325. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +1 -1
  326. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +100 -21
  327. package/src/sap/ui/model/odata/v4/lib/_AggregationHelper.js +1 -1
  328. package/src/sap/ui/model/odata/v4/lib/_Cache.js +99 -64
  329. package/src/sap/ui/model/odata/v4/lib/_Helper.js +75 -2
  330. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +6 -0
  331. package/src/sap/ui/model/odata/v4/lib/_V2Requestor.js +3 -0
  332. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  333. package/src/sap/ui/model/type/Boolean.js +1 -1
  334. package/src/sap/ui/model/type/Currency.js +1 -1
  335. package/src/sap/ui/model/type/Date.js +15 -1
  336. package/src/sap/ui/model/type/DateInterval.js +15 -1
  337. package/src/sap/ui/model/type/DateTime.js +1 -1
  338. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  339. package/src/sap/ui/model/type/FileSize.js +1 -1
  340. package/src/sap/ui/model/type/Float.js +1 -1
  341. package/src/sap/ui/model/type/Integer.js +1 -1
  342. package/src/sap/ui/model/type/String.js +1 -1
  343. package/src/sap/ui/model/type/Time.js +1 -1
  344. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  345. package/src/sap/ui/model/type/Unit.js +1 -1
  346. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  347. package/src/sap/ui/performance/Measurement.js +9 -9
  348. package/src/sap/ui/performance/trace/Interaction.js +50 -4
  349. package/src/sap/ui/performance/trace/initTraces.js +20 -14
  350. package/src/sap/ui/qunit/qunit-coverage-istanbul.js +180 -0
  351. package/src/sap/ui/qunit/qunit-coverage.js +9 -4
  352. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  353. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  354. package/src/sap/ui/test/Opa.js +54 -21
  355. package/src/sap/ui/test/Opa5.js +181 -131
  356. package/src/sap/ui/test/OpaBuilder.js +106 -73
  357. package/src/sap/ui/test/OpaPlugin.js +27 -28
  358. package/src/sap/ui/test/PageObjectFactory.js +17 -7
  359. package/src/sap/ui/test/RecordReplay.js +7 -3
  360. package/src/sap/ui/test/_ParameterValidator.js +3 -3
  361. package/src/sap/ui/test/_UsageReport.js +3 -3
  362. package/src/sap/ui/test/_ValidationParameters.js +8 -10
  363. package/src/sap/ui/test/actions/Action.js +3 -3
  364. package/src/sap/ui/test/actions/EnterText.js +3 -2
  365. package/src/sap/ui/test/actions/Press.js +4 -4
  366. package/src/sap/ui/test/autowaiter/WaiterBase.js +5 -3
  367. package/src/sap/ui/test/autowaiter/_autoWaiter.js +6 -3
  368. package/src/sap/ui/test/autowaiter/_cssAnimationWaiter.js +3 -3
  369. package/src/sap/ui/test/autowaiter/_cssTransitionWaiter.js +3 -3
  370. package/src/sap/ui/test/autowaiter/_fetchWaiter.js +73 -0
  371. package/src/sap/ui/test/autowaiter/_moduleWaiter.js +2 -2
  372. package/src/sap/ui/test/autowaiter/_promiseWaiter.js +4 -4
  373. package/src/sap/ui/test/autowaiter/_resourceWaiter.js +2 -2
  374. package/src/sap/ui/test/autowaiter/_timeoutWaiter.js +4 -4
  375. package/src/sap/ui/test/generic/TestBase.js +1 -1
  376. package/src/sap/ui/test/generic/_EnforceSemanticRendering.js +3 -1
  377. package/src/sap/ui/test/gherkin/GherkinTestGenerator.js +424 -423
  378. package/src/sap/ui/test/gherkin/StepDefinitions.js +160 -158
  379. package/src/sap/ui/test/gherkin/dataTableUtils.js +387 -385
  380. package/src/sap/ui/test/gherkin/opa5TestHarness.js +188 -189
  381. package/src/sap/ui/test/gherkin/qUnitTestHarness.js +74 -71
  382. package/src/sap/ui/test/gherkin/simpleGherkinParser.js +195 -193
  383. package/src/sap/ui/test/launchers/componentLauncher.js +11 -9
  384. package/src/sap/ui/test/launchers/iFrameLauncher.js +34 -20
  385. package/src/sap/ui/test/matchers/Descendant.js +1 -1
  386. package/src/sap/ui/test/matchers/Interactable.js +2 -2
  387. package/src/sap/ui/test/matchers/LabelFor.js +2 -2
  388. package/src/sap/ui/test/matchers/MatcherFactory.js +10 -9
  389. package/src/sap/ui/test/matchers/Properties.js +5 -4
  390. package/src/sap/ui/test/matchers/Sibling.js +1 -1
  391. package/src/sap/ui/test/matchers/matchers.js +35 -3
  392. package/src/sap/ui/test/pipelines/PipelineFactory.js +2 -2
  393. package/src/sap/ui/test/qunitPause.js +3 -2
  394. package/src/sap/ui/test/starter/_configureLoader.js +7 -5
  395. package/src/sap/ui/test/starter/_setupAndStart.js +113 -27
  396. package/src/sap/ui/test/starter/_utils.js +4 -1
  397. package/src/sap/ui/util/Mobile.js +8 -1
  398. package/src/sap/ui/util/Storage.js +1 -1
  399. package/src/ui5loader-autoconfig.js +661 -49
  400. package/src/ui5loader.js +18 -5
@@ -5,430 +5,431 @@
5
5
  */
6
6
 
7
7
  sap.ui.define([
8
+ "sap/base/util/deepExtend",
9
+ "sap/base/util/each",
8
10
  "sap/ui/base/Object",
9
11
  "sap/ui/test/gherkin/dataTableUtils",
10
12
  "sap/ui/test/gherkin/simpleGherkinParser",
11
- "sap/base/strings/escapeRegExp",
12
- "sap/ui/thirdparty/jquery"
13
- ], function(UI5Object, dataTableUtils, simpleGherkinParser, escapeRegExp, jQueryDOM) {
14
- "use strict";
15
-
16
- /**
17
- * Generates a generic FeatureTest object based on a Gherkin feature file and a steps definition object. This
18
- * FeatureTest object can then be used to easily generate tests in any test framework, e.g. QUnit.
19
- *
20
- * Full details on how Gherkin is supposed to work are provided on the Gherkin home page:
21
- * https://github.com/cucumber/cucumber/wiki/Gherkin
22
- *
23
- * The standard implementation of Gherkin is in Ruby. This is a JavaScript implementation for English only.
24
- *
25
- * This class generates a FeatureTest object. The FeatureTest object is composed of a series of TestScenarios, each of
26
- * which is composed of a series of TestSteps. Each TestStep is created by matching a Gherkin test step with a step
27
- * definition.
28
- *
29
- * A FeatureTest object looks like this:
30
- * <pre>
31
- * { // {FeatureTest} an executable object for testing a Gherkin feature
32
- * name: "Feature: Serve expensive coffee", // {string} the feature name from the Gherkin file
33
- * skip: false, // {boolean} true if the feature should not be executed
34
- * wip: false, // {boolean} true if the feature is a work in progress
35
- * testScenarios: [{ // {[TestScenario]} test scenarios to be run in this FeatureTest
36
- * name: "Scenario: Buy first coffee", // {string} the scenario name from the Gherkin file
37
- * skip: false, // {boolean} true if the scenario should not be executed
38
- * wip: false, // {boolean} true if the scenario is a work in progress
39
- * testSteps: [{ // {[TestStep]} test steps that are part of this TestScenario
40
- * isMatch: true, // {boolean} true if the Gherkin scenario matched a step definition
41
- * skip: false, // {boolean} true if the test step should not be executed
42
- * text: "coffee costs $18 per cup", // {string} the test step's text as defined in the Gherkin file
43
- * regex: /regex/, // {RegExp} the matching regular expression from step definitions
44
- * parameters: [], // {[object]} parameters derived from regular expression match
45
- * func: function(){} // {function} the matching step definition function
46
- * },{
47
- * isMatch: true,
48
- * skip: false,
49
- * text: "I should be served a coffee",
50
- * regex: /regex/,
51
- * parameters: [],
52
- * func: function(){}
53
- * }]},{
54
- * name: "Scenario: Buy second coffee",
55
- * skip: false,
56
- * wip: false,
57
- * testSteps: [{
58
- * isMatch: true,
59
- * skip: false,
60
- * text: "coffee costs $18 per cup",
61
- * regex: /regex/,
62
- * parameters: [],
63
- * func: function(){}
64
- * },{
65
- * isMatch: true,
66
- * skip: false,
67
- * text: "I should be served a second coffee",
68
- * regex: /regex/,
69
- * parameters: [],
70
- * func: function(){}
71
- * }]}]
72
- * }
73
- * </pre>
74
- *
75
- * @param {(object|string)} vFeature - a feature object generated by sap.ui.test.gherkin.simpleGherkinParser.
76
- * Alternatively, this could be the {string} path pointing to a feature file.
77
- * @param {function} fnStepDefsConstructor - the constructor for a child class of type
78
- * sap.ui.test.gherkin.StepDefinitions
79
- * @param {function} [fnAlternateTestStepGenerator] - Optional. If it's specified, this function will be executed
80
- * whenever a Gherkin test step has no matching Step Definition. The
81
- * function accepts one parameter, a Gherkin test step object with
82
- * two {string} attributes "text" and "keyword". The function
83
- * returns a TestStep object, as defined above. It is the function
84
- * writer's responsibility to prepend "(NOT FOUND)" to the "text" if
85
- * the attribute "isMatch" is set to "false".
86
- *
87
- * @class
88
- * @author Rodrigo Jordao
89
- * @author Jonathan Benn
90
- * @extends sap.ui.base.Object
91
- * @alias sap.ui.test.gherkin.GherkinTestGenerator
92
- * @since 1.40
93
- * @private
94
- */
95
- var GherkinTestGenerator = UI5Object.extend("sap.ui.test.gherkin.GherkinTestGenerator",
96
- /** @lends sap.ui.test.gherkin.GherkinTestGenerator.prototype */ {
97
-
98
- constructor : function(vFeature, fnStepDefsConstructor, fnAlternateTestStepGenerator) {
99
- UI5Object.apply(this, arguments);
100
-
101
- if (typeof vFeature === "string" || vFeature instanceof String) {
102
- vFeature = simpleGherkinParser.parseFile(vFeature);
103
-
104
- // else if the type is not a String and not a Feature object (or not given)
105
- } else if (!vFeature || (typeof vFeature !== "object") || !vFeature.scenarios) {
106
- throw new Error("GherkinTestGenerator constructor: parameter 'vFeature' must be a valid String or a valid Feature object");
107
- }
108
-
109
- if ((typeof fnStepDefsConstructor !== "function") || !((new fnStepDefsConstructor())._generateTestStep)) {
110
- throw new Error("GherkinTestGenerator constructor: parameter 'fnStepDefsConstructor' must be a valid StepDefinitions constructor");
111
- }
112
-
113
- if (fnAlternateTestStepGenerator && typeof fnAlternateTestStepGenerator !== "function") {
114
- throw new Error("GherkinTestGenerator constructor: if specified, parameter 'fnAlternateTestStepGenerator' must be a valid Function");
115
- }
116
-
117
- /**
118
- * {Feature} a feature object generated by sap.ui.test.gherkin.simpleGherkinParser
119
- *
120
- * @see sap.ui.test.gherkin.simpleGherkinParser
121
- * @private
122
- */
123
- this._oFeature = vFeature;
124
-
125
- /**
126
- * {function} the constructor for a child class of type sap.ui.test.gherkin.StepDefinitions
127
- *
128
- * @see sap.ui.test.gherkin.StepDefinitions
129
- * @private
130
- */
131
- this._fnStepDefsConstructor = fnStepDefsConstructor;
132
-
133
- /**
134
- * {StepDefinitions} the concrete StepDefinitions object that holds an array of step definitions
135
- *
136
- * @see sap.ui.test.gherkin.StepDefinitions
137
- * @private
138
- */
139
- this._oStepDefs = null;
140
-
141
- /**
142
- * {function} generates and returns a TestStep object. If this function is defined, it will be executed whenever
143
- * we fail to find a matching Step Definition for a Gherkin step.
144
- *
145
- * @private
146
- */
147
- this._fnAlternateTestStepGenerator = fnAlternateTestStepGenerator || null;
148
- },
149
-
150
- /**
151
- * Creates a new shared context for running tests. Execute this method before testing a new scenario.
152
- *
153
- * @public
154
- */
155
- setUp: function() {
156
- this._oStepDefs = new this._fnStepDefsConstructor();
157
- },
158
-
159
- /**
160
- * If any tests were run, executes the Step Definitions' "closeApplication" method. Also clears the shared
161
- * context for running tests.
162
- *
163
- * @public
164
- */
165
- tearDown: function() {
166
- if (this._oStepDefs && this._oStepDefs._needsTearDown) {
167
- this._oStepDefs.closeApplication();
168
- }
169
- this._oStepDefs = null;
170
- },
171
-
172
- /**
173
- * Creates a FeatureTest object, which is generated by stitching together the Gherkin Feature File and Step
174
- * Definitions file inputed to the constructor.
175
- *
176
- * @returns {FeatureTest} an executable test object
177
- * @public
178
- */
179
- generate : function() {
180
- if (!this._oStepDefs) {
181
- this.setUp();
182
- }
183
- return this._generateFeatureTest();
184
- },
185
-
186
- /**
187
- * Executes the given TestStep in the shared context of the Step Definitions, with the correct parameters. The
188
- * TestStep will not be executed if it should be skipped, in which case this method will return "false".
189
- *
190
- * @param {TestStep} oTestStep - the test step to execute, obtained from the result of "generate".
191
- * @param {boolean} oTestStep.skip - false if the test step should be executed, otherwise true
192
- * @param {function} [oTestStep.func] - the step definition function to execute (ignored if "oTestStep.skip" is
193
- * true)
194
- * @param {any[]} [oTestStep.parameters] - the parameters to pass to "oTestStep.func" during its execution
195
- * (ignored if "oTestStep.skip" is true)
196
- * @param {object} [assert] - (optional) the QUnit local assert object for this test
197
- * @returns {boolean} true if the test step was executed, otherwise false
198
- * @throws {Error} if you attempt to call this method before calling "generate" or after calling "tearDown", or if
199
- * oTestStep is an invalid TestStep object
200
- * @public
201
- */
202
- execute: function(oTestStep, assert) {
203
- if (!this._oStepDefs) {
204
- throw new Error("Run 'generate' before calling 'execute'");
205
- }
206
- if (!oTestStep ||
207
- (!oTestStep.skip && ((typeof oTestStep.func !== "function") || !Array.isArray(oTestStep.parameters)))) {
208
- throw new Error("Input parameter 'oTestStep' is not a valid TestStep object.");
209
- }
210
-
211
- // If this test step should not be skipped
212
- if (!oTestStep.skip) {
213
- // then execute the test step in the Step Definitions shared context
214
- this._oStepDefs.assert = assert;
215
- oTestStep.func.apply(this._oStepDefs, oTestStep.parameters);
216
- this._oStepDefs._needsTearDown = true;
217
- }
218
-
219
- return (!oTestStep.skip);
220
- },
221
-
222
- /**
223
- * Creates an executable feature test, composed of 0 or more test scenarios, each of which is composed of 0 or more
224
- * basic test steps. The generated feature test is based on Gherkin document and step definitions fed into the
225
- * constructor.
226
- *
227
- * @private
228
- */
229
- _generateFeatureTest: function() {
230
-
231
- var aExpandedScenarios = [];
232
- this._oFeature.scenarios.forEach(function(oScenario) {
233
- aExpandedScenarios = aExpandedScenarios.concat(this._expandScenarioOutline(oScenario));
234
- }, this);
235
-
236
- var aTestScenarios = aExpandedScenarios.map(function(oScenario) {
237
- return this._generateTestScenario(oScenario, this._oFeature.background);
238
- }, this);
239
-
240
- var bFeatureIsWip = this._isWip(this._oFeature);
241
- var bAllScenariosAreSkipped = aTestScenarios.every(function(oTestScenario) {return oTestScenario.skip;});
242
-
243
- return {
244
- name: ((bFeatureIsWip) ? "(WIP) " : "") + "Feature: " + this._oFeature.name,
245
- skip: bFeatureIsWip || bAllScenariosAreSkipped,
246
- wip: bFeatureIsWip,
247
- testScenarios: aTestScenarios
248
- };
249
- },
250
-
251
- /**
252
- * Expands a scenario outline into 1 or more concrete scenarios (one concrete scenario for each line in the examples).
253
- *
254
- * Each concrete scenario will have ": <Examples name> #1", ": <Examples name> #2", etc. appended to its text to
255
- * differentiate it.
256
- *
257
- * @param {Scenario} oScenario - a Gherkin scenario that may or may not be a scenario outline
258
- * @returns {Scenario[]} - an array of 1 or more scenarios. If the input was a scenario outline, then the output
259
- * is an array of 1 or more concrete scenarios that implement that outline. One concrete
260
- * scenario is generated per example line specified in the feature file. If the input was a
261
- * regular scenario, then the return value is an array with 1 element: the inputed
262
- * scenario.
263
- * @private
264
- */
265
- _expandScenarioOutline: function(oScenario) {
266
-
267
- // if this is not a scenario outline OR it's a scenario outline with no active Examples
268
- if (!this._isScenarioOutlineWithExamples(oScenario)) {
269
- // then don't change anything
270
- return [oScenario];
271
- }
272
-
273
- // else this is a scenario outline with at least one set of Examples
274
- var aConcreteScenarios = [];
275
-
276
- // for each set of active Examples in the Scenario Outline
277
- oScenario.examples.filter(this._isNotWip).forEach(function(oExample, i) {
278
-
279
- var aConvertedExamples = this._convertScenarioExamplesToListOfObjects(oExample.data);
280
-
281
- // create a concrete scenario from each example in the Examples
282
- aConcreteScenarios = aConcreteScenarios.concat(aConvertedExamples.map(function(oConvertedExample, i) {
283
-
284
- var oScenarioCopy = jQueryDOM.extend(true, {}, oScenario);
285
- oScenarioCopy.name += (oExample.name) ? ": " + oExample.name : "";
286
- oScenarioCopy.name += " #" + (i + 1);
287
-
288
- // for each variable specified for this concrete example
289
- jQueryDOM.each(oConvertedExample, function(sVariableName, sVariableValue) {
290
-
291
- // for each test step in the scenario
292
- oScenarioCopy.steps.forEach(function(oStep) {
293
- // in the scenario text, replace all occurences of the variable with the concrete value
294
- var sEscapedVariableName = escapeRegExp(sVariableName);
295
- oStep.text = oStep.text.replace(new RegExp("<" + sEscapedVariableName + ">", "g"), sVariableValue);
296
- });
297
- });
298
-
299
- return oScenarioCopy;
300
- }, this));
301
-
302
- }, this);
303
-
304
- return aConcreteScenarios;
305
- },
306
-
307
- /**
308
- * Prepares an executable test scenario based on a Gherkin document's scenario.
309
- *
310
- * @param {Scenario} oScenario - the Gherkin scenario for which to generate tests
311
- * @param {Scenario} [oBackground] - the Gherkin background scenario that must be run before each regular scenario
312
- * @returns {TestScenario} - the test scenario to be executed during testing
313
- * @see sap.ui.test.gherkin.simpleGherkinParser#parse
314
- * @private
315
- */
316
- _generateTestScenario: function(oScenario, oBackground) {
317
- var bWip = this._isWip(oScenario);
318
- var sScenarioPrependText = this._isScenarioOutline(oScenario) ? "Scenario Outline: " : "Scenario: ";
319
- var sScenarioName = (bWip ? "(WIP) " : "") + sScenarioPrependText + oScenario.name;
320
- var aTestSteps = (oBackground) ? this._generateTestSteps(bWip, oBackground, false) : [];
321
- var bNoActiveExamples = this._isScenarioOutline(oScenario) && !this._isScenarioOutlineWithExamples(oScenario);
322
- var bSkip = bNoActiveExamples || aTestSteps.some(function(o) {return !o.isMatch;});
323
-
324
- aTestSteps = aTestSteps.concat(this._generateTestSteps(bWip, oScenario, bSkip));
325
-
326
- return {
327
- name: sScenarioName,
328
- skip: bWip || bNoActiveExamples || aTestSteps.every(function(o) {return o.skip && o.isMatch;}),
329
- wip: bWip,
330
- testSteps: aTestSteps
331
- };
332
- },
333
-
334
- /**
335
- * Creates all the tests for all of the given scenario's steps. It does this by stitching together the Gherkin
336
- * specification's steps with the JavaScript step definitions. If any Gherkin step cannot be matched to a
337
- * JavaScript step definition then that test and all remaining tests will be skipped.
338
- *
339
- * If the _fnAlternateTestStepGenerator is defined then it will be used to generate a TestStep if we fail to match
340
- * a step definition.
341
- *
342
- * @param {boolean} bIsWip - true if this test is a work in progress that should be skipped
343
- * @param {Scenario} oScenario - the Gherkin scenario on which to base these generated tests
344
- * @param {boolean} bSkipping - true if this scenario and all of its steps should be skipped (e.g. because the
345
- * background step was not found)
346
- * @returns {TestStep[]} - the list of test step objects to be executed during testing
347
- * @see sap.ui.test.gherkin.simpleGherkinParser#parse
348
- * @private
349
- */
350
- _generateTestSteps: function(bIsWip, oScenario, bSkipping) {
351
-
352
- var aTestSteps = [];
353
-
354
- for (var i = 0; i < oScenario.steps.length; ++i) {
355
- var oStep = oScenario.steps[i];
356
- var oTestStep = this._oStepDefs._generateTestStep(oStep);
357
-
358
- // if there is no matching regular expression and there is an alternate TestStep generator
359
- if (!oTestStep.isMatch && this._fnAlternateTestStepGenerator) {
360
- // then use the alternate function to generate a TestStep
361
- oTestStep = this._fnAlternateTestStepGenerator(oStep);
362
- }
363
-
364
- // If there is still not a match
365
- if (!oTestStep.isMatch) {
366
- // then we will skip this and all future test steps
367
- bSkipping = true;
368
- }
369
-
370
- oTestStep.skip = bSkipping || bIsWip;
371
- if (oTestStep.isMatch && oTestStep.skip) {
372
- oTestStep.text = "(SKIPPED) " + oTestStep.text;
373
- }
374
- aTestSteps.push(oTestStep);
375
- }
376
-
377
- return aTestSteps;
378
- },
379
-
380
- /**
381
- * Converts the given scenario outline examples into a list of objects
382
- *
383
- * @param {string[]} aExamples - scenario outline examples, can be a 1D or 2D array
384
- * @returns {object[]} - a list of objects equivalent to the input data
385
- * @see sap.ui.test.gherkin.dataTableUtils.toTable
386
- * @private
387
- */
388
- _convertScenarioExamplesToListOfObjects: function(aExamples) {
389
- // if aExamples is a simple list then convert from simple list to list-of-lists before executing toTable
390
- aExamples = aExamples.map(function(i){return (typeof i === "string" || i instanceof String) ? [i] : i;});
391
- return dataTableUtils.toTable(aExamples);
392
- },
393
-
394
-
395
- /**
396
- * @param {Scenario} oScenario - a Gherkin scenario (as created by the parser)
397
- * @returns true if the given scenario is a scenario outline
398
- * @private
399
- */
400
- _isScenarioOutline: function(oScenario) {
401
- return !!oScenario.examples;
402
- },
403
-
404
- /**
405
- * @param {Scenario} oScenario - a Gherkin scenario (as created by the parser)
406
- * @returns true if the given scenario is a scenario outline AND it has active (non-WIP) Examples
407
- * @private
408
- */
409
- _isScenarioOutlineWithExamples: function(oScenario) {
410
- return !!oScenario.examples && (oScenario.examples.length !== 0) && oScenario.examples.some(this._isNotWip);
411
- },
412
-
413
- /**
414
- * @param {object} oObject - any object with a 'tags' attribute (tags are of type array)
415
- * @returns true if the given oObject does not have an '@wip' tag
416
- * @private
417
- */
418
- _isNotWip: function(oObject) {
419
- return (jQueryDOM.inArray("@wip", oObject.tags) === -1);
420
- },
421
-
422
- /**
423
- * @param {object} oObject - any object with a 'tags' attribute (tags are of type array)
424
- * @returns true if the given oObject has an '@wip' tag
425
- * @private
426
- */
427
- _isWip: function(oObject) {
428
- return !this._isNotWip(oObject);
429
- }
430
-
431
- });
432
-
433
- return GherkinTestGenerator;
13
+ "sap/base/strings/escapeRegExp"
14
+ ], function(deepExtend, each, UI5Object, dataTableUtils, simpleGherkinParser, escapeRegExp) {
15
+ "use strict";
16
+
17
+ /**
18
+ * Generates a generic FeatureTest object based on a Gherkin feature file and a steps definition object. This
19
+ * FeatureTest object can then be used to easily generate tests in any test framework, e.g. QUnit.
20
+ *
21
+ * Full details on how Gherkin is supposed to work are provided on the Gherkin home page:
22
+ * https://github.com/cucumber/cucumber/wiki/Gherkin
23
+ *
24
+ * The standard implementation of Gherkin is in Ruby. This is a JavaScript implementation for English only.
25
+ *
26
+ * This class generates a FeatureTest object. The FeatureTest object is composed of a series of TestScenarios, each of
27
+ * which is composed of a series of TestSteps. Each TestStep is created by matching a Gherkin test step with a step
28
+ * definition.
29
+ *
30
+ * A FeatureTest object looks like this:
31
+ * <pre>
32
+ * { // {FeatureTest} an executable object for testing a Gherkin feature
33
+ * name: "Feature: Serve expensive coffee", // {string} the feature name from the Gherkin file
34
+ * skip: false, // {boolean} true if the feature should not be executed
35
+ * wip: false, // {boolean} true if the feature is a work in progress
36
+ * testScenarios: [{ // {[TestScenario]} test scenarios to be run in this FeatureTest
37
+ * name: "Scenario: Buy first coffee", // {string} the scenario name from the Gherkin file
38
+ * skip: false, // {boolean} true if the scenario should not be executed
39
+ * wip: false, // {boolean} true if the scenario is a work in progress
40
+ * testSteps: [{ // {[TestStep]} test steps that are part of this TestScenario
41
+ * isMatch: true, // {boolean} true if the Gherkin scenario matched a step definition
42
+ * skip: false, // {boolean} true if the test step should not be executed
43
+ * text: "coffee costs $18 per cup", // {string} the test step's text as defined in the Gherkin file
44
+ * regex: /regex/, // {RegExp} the matching regular expression from step definitions
45
+ * parameters: [], // {[object]} parameters derived from regular expression match
46
+ * func: function(){} // {function} the matching step definition function
47
+ * },{
48
+ * isMatch: true,
49
+ * skip: false,
50
+ * text: "I should be served a coffee",
51
+ * regex: /regex/,
52
+ * parameters: [],
53
+ * func: function(){}
54
+ * }]},{
55
+ * name: "Scenario: Buy second coffee",
56
+ * skip: false,
57
+ * wip: false,
58
+ * testSteps: [{
59
+ * isMatch: true,
60
+ * skip: false,
61
+ * text: "coffee costs $18 per cup",
62
+ * regex: /regex/,
63
+ * parameters: [],
64
+ * func: function(){}
65
+ * },{
66
+ * isMatch: true,
67
+ * skip: false,
68
+ * text: "I should be served a second coffee",
69
+ * regex: /regex/,
70
+ * parameters: [],
71
+ * func: function(){}
72
+ * }]}]
73
+ * }
74
+ * </pre>
75
+ *
76
+ * @param {(object|string)} vFeature - a feature object generated by sap.ui.test.gherkin.simpleGherkinParser.
77
+ * Alternatively, this could be the {string} path pointing to a feature file.
78
+ * @param {function} fnStepDefsConstructor - the constructor for a child class of type
79
+ * sap.ui.test.gherkin.StepDefinitions
80
+ * @param {function} [fnAlternateTestStepGenerator] - Optional. If it's specified, this function will be executed
81
+ * whenever a Gherkin test step has no matching Step Definition. The
82
+ * function accepts one parameter, a Gherkin test step object with
83
+ * two {string} attributes "text" and "keyword". The function
84
+ * returns a TestStep object, as defined above. It is the function
85
+ * writer's responsibility to prepend "(NOT FOUND)" to the "text" if
86
+ * the attribute "isMatch" is set to "false".
87
+ *
88
+ * @class
89
+ * @author Rodrigo Jordao
90
+ * @author Jonathan Benn
91
+ * @extends sap.ui.base.Object
92
+ * @alias sap.ui.test.gherkin.GherkinTestGenerator
93
+ * @since 1.40
94
+ * @private
95
+ */
96
+ var GherkinTestGenerator = UI5Object.extend("sap.ui.test.gherkin.GherkinTestGenerator",
97
+ /** @lends sap.ui.test.gherkin.GherkinTestGenerator.prototype */ {
98
+
99
+ constructor : function(vFeature, fnStepDefsConstructor, fnAlternateTestStepGenerator) {
100
+ UI5Object.apply(this, arguments);
101
+
102
+ if (typeof vFeature === "string" || vFeature instanceof String) {
103
+ vFeature = simpleGherkinParser.parseFile(vFeature);
104
+
105
+ // else if the type is not a String and not a Feature object (or not given)
106
+ } else if (!vFeature || (typeof vFeature !== "object") || !vFeature.scenarios) {
107
+ throw new Error("GherkinTestGenerator constructor: parameter 'vFeature' must be a valid String or a valid Feature object");
108
+ }
109
+
110
+ if ((typeof fnStepDefsConstructor !== "function") || !((new fnStepDefsConstructor())._generateTestStep)) {
111
+ throw new Error("GherkinTestGenerator constructor: parameter 'fnStepDefsConstructor' must be a valid StepDefinitions constructor");
112
+ }
113
+
114
+ if (fnAlternateTestStepGenerator && typeof fnAlternateTestStepGenerator !== "function") {
115
+ throw new Error("GherkinTestGenerator constructor: if specified, parameter 'fnAlternateTestStepGenerator' must be a valid Function");
116
+ }
117
+
118
+ /**
119
+ * {Feature} a feature object generated by sap.ui.test.gherkin.simpleGherkinParser
120
+ *
121
+ * @see sap.ui.test.gherkin.simpleGherkinParser
122
+ * @private
123
+ */
124
+ this._oFeature = vFeature;
125
+
126
+ /**
127
+ * {function} the constructor for a child class of type sap.ui.test.gherkin.StepDefinitions
128
+ *
129
+ * @see sap.ui.test.gherkin.StepDefinitions
130
+ * @private
131
+ */
132
+ this._fnStepDefsConstructor = fnStepDefsConstructor;
133
+
134
+ /**
135
+ * {StepDefinitions} the concrete StepDefinitions object that holds an array of step definitions
136
+ *
137
+ * @see sap.ui.test.gherkin.StepDefinitions
138
+ * @private
139
+ */
140
+ this._oStepDefs = null;
141
+
142
+ /**
143
+ * {function} generates and returns a TestStep object. If this function is defined, it will be executed whenever
144
+ * we fail to find a matching Step Definition for a Gherkin step.
145
+ *
146
+ * @private
147
+ */
148
+ this._fnAlternateTestStepGenerator = fnAlternateTestStepGenerator || null;
149
+ },
150
+
151
+ /**
152
+ * Creates a new shared context for running tests. Execute this method before testing a new scenario.
153
+ *
154
+ * @public
155
+ */
156
+ setUp: function() {
157
+ this._oStepDefs = new this._fnStepDefsConstructor();
158
+ },
159
+
160
+ /**
161
+ * If any tests were run, executes the Step Definitions' "closeApplication" method. Also clears the shared
162
+ * context for running tests.
163
+ *
164
+ * @public
165
+ */
166
+ tearDown: function() {
167
+ if (this._oStepDefs && this._oStepDefs._needsTearDown) {
168
+ this._oStepDefs.closeApplication();
169
+ }
170
+ this._oStepDefs = null;
171
+ },
172
+
173
+ /**
174
+ * Creates a FeatureTest object, which is generated by stitching together the Gherkin Feature File and Step
175
+ * Definitions file inputed to the constructor.
176
+ *
177
+ * @returns {FeatureTest} an executable test object
178
+ * @public
179
+ */
180
+ generate : function() {
181
+ if (!this._oStepDefs) {
182
+ this.setUp();
183
+ }
184
+ return this._generateFeatureTest();
185
+ },
186
+
187
+ /**
188
+ * Executes the given TestStep in the shared context of the Step Definitions, with the correct parameters. The
189
+ * TestStep will not be executed if it should be skipped, in which case this method will return "false".
190
+ *
191
+ * @param {TestStep} oTestStep - the test step to execute, obtained from the result of "generate".
192
+ * @param {boolean} oTestStep.skip - false if the test step should be executed, otherwise true
193
+ * @param {function} [oTestStep.func] - the step definition function to execute (ignored if "oTestStep.skip" is
194
+ * true)
195
+ * @param {any[]} [oTestStep.parameters] - the parameters to pass to "oTestStep.func" during its execution
196
+ * (ignored if "oTestStep.skip" is true)
197
+ * @param {object} [assert] - (optional) the QUnit local assert object for this test
198
+ * @returns {boolean} true if the test step was executed, otherwise false
199
+ * @throws {Error} if you attempt to call this method before calling "generate" or after calling "tearDown", or if
200
+ * oTestStep is an invalid TestStep object
201
+ * @public
202
+ */
203
+ execute: function(oTestStep, assert) {
204
+ if (!this._oStepDefs) {
205
+ throw new Error("Run 'generate' before calling 'execute'");
206
+ }
207
+ if (!oTestStep ||
208
+ (!oTestStep.skip && ((typeof oTestStep.func !== "function") || !Array.isArray(oTestStep.parameters)))) {
209
+ throw new Error("Input parameter 'oTestStep' is not a valid TestStep object.");
210
+ }
211
+
212
+ // If this test step should not be skipped
213
+ if (!oTestStep.skip) {
214
+ // then execute the test step in the Step Definitions shared context
215
+ this._oStepDefs.assert = assert;
216
+ oTestStep.func.apply(this._oStepDefs, oTestStep.parameters);
217
+ this._oStepDefs._needsTearDown = true;
218
+ }
219
+
220
+ return (!oTestStep.skip);
221
+ },
222
+
223
+ /**
224
+ * Creates an executable feature test, composed of 0 or more test scenarios, each of which is composed of 0 or more
225
+ * basic test steps. The generated feature test is based on Gherkin document and step definitions fed into the
226
+ * constructor.
227
+ *
228
+ * @private
229
+ */
230
+ _generateFeatureTest: function() {
231
+
232
+ var aExpandedScenarios = [];
233
+ this._oFeature.scenarios.forEach(function(oScenario) {
234
+ aExpandedScenarios = aExpandedScenarios.concat(this._expandScenarioOutline(oScenario));
235
+ }, this);
236
+
237
+ var aTestScenarios = aExpandedScenarios.map(function(oScenario) {
238
+ return this._generateTestScenario(oScenario, this._oFeature.background);
239
+ }, this);
240
+
241
+ var bFeatureIsWip = this._isWip(this._oFeature);
242
+ var bAllScenariosAreSkipped = aTestScenarios.every(function(oTestScenario) {return oTestScenario.skip;});
243
+
244
+ return {
245
+ name: ((bFeatureIsWip) ? "(WIP) " : "") + "Feature: " + this._oFeature.name,
246
+ skip: bFeatureIsWip || bAllScenariosAreSkipped,
247
+ wip: bFeatureIsWip,
248
+ testScenarios: aTestScenarios
249
+ };
250
+ },
251
+
252
+ /**
253
+ * Expands a scenario outline into 1 or more concrete scenarios (one concrete scenario for each line in the examples).
254
+ *
255
+ * Each concrete scenario will have ": <Examples name> #1", ": <Examples name> #2", etc. appended to its text to
256
+ * differentiate it.
257
+ *
258
+ * @param {Scenario} oScenario - a Gherkin scenario that may or may not be a scenario outline
259
+ * @returns {Scenario[]} - an array of 1 or more scenarios. If the input was a scenario outline, then the output
260
+ * is an array of 1 or more concrete scenarios that implement that outline. One concrete
261
+ * scenario is generated per example line specified in the feature file. If the input was a
262
+ * regular scenario, then the return value is an array with 1 element: the inputed
263
+ * scenario.
264
+ * @private
265
+ */
266
+ _expandScenarioOutline: function(oScenario) {
267
+
268
+ // if this is not a scenario outline OR it's a scenario outline with no active Examples
269
+ if (!this._isScenarioOutlineWithExamples(oScenario)) {
270
+ // then don't change anything
271
+ return [oScenario];
272
+ }
273
+
274
+ // else this is a scenario outline with at least one set of Examples
275
+ var aConcreteScenarios = [];
276
+
277
+ // for each set of active Examples in the Scenario Outline
278
+ oScenario.examples.filter(this._isNotWip).forEach(function(oExample, i) {
279
+
280
+ var aConvertedExamples = this._convertScenarioExamplesToListOfObjects(oExample.data);
281
+
282
+ // create a concrete scenario from each example in the Examples
283
+ aConcreteScenarios = aConcreteScenarios.concat(aConvertedExamples.map(function(oConvertedExample, i) {
284
+
285
+ var oScenarioCopy = deepExtend({}, oScenario);
286
+ oScenarioCopy.name += (oExample.name) ? ": " + oExample.name : "";
287
+ oScenarioCopy.name += " #" + (i + 1);
288
+
289
+ // for each variable specified for this concrete example
290
+ each(oConvertedExample, function(sVariableName, sVariableValue) {
291
+
292
+ // for each test step in the scenario
293
+ oScenarioCopy.steps.forEach(function(oStep) {
294
+ // in the scenario text, replace all occurences of the variable with the concrete value
295
+ var sEscapedVariableName = escapeRegExp(sVariableName);
296
+ oStep.text = oStep.text.replace(new RegExp("<" + sEscapedVariableName + ">", "g"), sVariableValue);
297
+ });
298
+ });
299
+
300
+ return oScenarioCopy;
301
+ }, this));
302
+
303
+ }, this);
304
+
305
+ return aConcreteScenarios;
306
+ },
307
+
308
+ /**
309
+ * Prepares an executable test scenario based on a Gherkin document's scenario.
310
+ *
311
+ * @param {Scenario} oScenario - the Gherkin scenario for which to generate tests
312
+ * @param {Scenario} [oBackground] - the Gherkin background scenario that must be run before each regular scenario
313
+ * @returns {TestScenario} - the test scenario to be executed during testing
314
+ * @see sap.ui.test.gherkin.simpleGherkinParser#parse
315
+ * @private
316
+ */
317
+ _generateTestScenario: function(oScenario, oBackground) {
318
+ var bWip = this._isWip(oScenario);
319
+ var sScenarioPrependText = this._isScenarioOutline(oScenario) ? "Scenario Outline: " : "Scenario: ";
320
+ var sScenarioName = (bWip ? "(WIP) " : "") + sScenarioPrependText + oScenario.name;
321
+ var aTestSteps = (oBackground) ? this._generateTestSteps(bWip, oBackground, false) : [];
322
+ var bNoActiveExamples = this._isScenarioOutline(oScenario) && !this._isScenarioOutlineWithExamples(oScenario);
323
+ var bSkip = bNoActiveExamples || aTestSteps.some(function(o) {return !o.isMatch;});
324
+
325
+ aTestSteps = aTestSteps.concat(this._generateTestSteps(bWip, oScenario, bSkip));
326
+
327
+ return {
328
+ name: sScenarioName,
329
+ skip: bWip || bNoActiveExamples || aTestSteps.every(function(o) {return o.skip && o.isMatch;}),
330
+ wip: bWip,
331
+ testSteps: aTestSteps
332
+ };
333
+ },
334
+
335
+ /**
336
+ * Creates all the tests for all of the given scenario's steps. It does this by stitching together the Gherkin
337
+ * specification's steps with the JavaScript step definitions. If any Gherkin step cannot be matched to a
338
+ * JavaScript step definition then that test and all remaining tests will be skipped.
339
+ *
340
+ * If the _fnAlternateTestStepGenerator is defined then it will be used to generate a TestStep if we fail to match
341
+ * a step definition.
342
+ *
343
+ * @param {boolean} bIsWip - true if this test is a work in progress that should be skipped
344
+ * @param {Scenario} oScenario - the Gherkin scenario on which to base these generated tests
345
+ * @param {boolean} bSkipping - true if this scenario and all of its steps should be skipped (e.g. because the
346
+ * background step was not found)
347
+ * @returns {TestStep[]} - the list of test step objects to be executed during testing
348
+ * @see sap.ui.test.gherkin.simpleGherkinParser#parse
349
+ * @private
350
+ */
351
+ _generateTestSteps: function(bIsWip, oScenario, bSkipping) {
352
+
353
+ var aTestSteps = [];
354
+
355
+ for (var i = 0; i < oScenario.steps.length; ++i) {
356
+ var oStep = oScenario.steps[i];
357
+ var oTestStep = this._oStepDefs._generateTestStep(oStep);
358
+
359
+ // if there is no matching regular expression and there is an alternate TestStep generator
360
+ if (!oTestStep.isMatch && this._fnAlternateTestStepGenerator) {
361
+ // then use the alternate function to generate a TestStep
362
+ oTestStep = this._fnAlternateTestStepGenerator(oStep);
363
+ }
364
+
365
+ // If there is still not a match
366
+ if (!oTestStep.isMatch) {
367
+ // then we will skip this and all future test steps
368
+ bSkipping = true;
369
+ }
370
+
371
+ oTestStep.skip = bSkipping || bIsWip;
372
+ if (oTestStep.isMatch && oTestStep.skip) {
373
+ oTestStep.text = "(SKIPPED) " + oTestStep.text;
374
+ }
375
+ aTestSteps.push(oTestStep);
376
+ }
377
+
378
+ return aTestSteps;
379
+ },
380
+
381
+ /**
382
+ * Converts the given scenario outline examples into a list of objects
383
+ *
384
+ * @param {string[]} aExamples - scenario outline examples, can be a 1D or 2D array
385
+ * @returns {object[]} - a list of objects equivalent to the input data
386
+ * @see sap.ui.test.gherkin.dataTableUtils.toTable
387
+ * @private
388
+ */
389
+ _convertScenarioExamplesToListOfObjects: function(aExamples) {
390
+ // if aExamples is a simple list then convert from simple list to list-of-lists before executing toTable
391
+ aExamples = aExamples.map(function(i){return (typeof i === "string" || i instanceof String) ? [i] : i;});
392
+ return dataTableUtils.toTable(aExamples);
393
+ },
394
+
395
+
396
+ /**
397
+ * @param {Scenario} oScenario - a Gherkin scenario (as created by the parser)
398
+ * @returns true if the given scenario is a scenario outline
399
+ * @private
400
+ */
401
+ _isScenarioOutline: function(oScenario) {
402
+ return !!oScenario.examples;
403
+ },
404
+
405
+ /**
406
+ * @param {Scenario} oScenario - a Gherkin scenario (as created by the parser)
407
+ * @returns true if the given scenario is a scenario outline AND it has active (non-WIP) Examples
408
+ * @private
409
+ */
410
+ _isScenarioOutlineWithExamples: function(oScenario) {
411
+ return !!oScenario.examples && (oScenario.examples.length !== 0) && oScenario.examples.some(this._isNotWip);
412
+ },
413
+
414
+ /**
415
+ * @param {object} oObject - any object with a 'tags' attribute (tags are of type array)
416
+ * @returns true if the given oObject does not have an '@wip' tag
417
+ * @private
418
+ */
419
+ _isNotWip: function(oObject) {
420
+ return (oObject.tags == null || !oObject.tags.includes("@wip", oObject.tags));
421
+ },
422
+
423
+ /**
424
+ * @param {object} oObject - any object with a 'tags' attribute (tags are of type array)
425
+ * @returns true if the given oObject has an '@wip' tag
426
+ * @private
427
+ */
428
+ _isWip: function(oObject) {
429
+ return !this._isNotWip(oObject);
430
+ }
431
+
432
+ });
433
+
434
+ return GherkinTestGenerator;
434
435
  });