quasar 2.15.2 → 2.15.3

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 (646) hide show
  1. package/dist/api/AddressbarColor.json +1 -1
  2. package/dist/api/AppFullscreen.json +1 -1
  3. package/dist/api/BottomSheet.json +1 -1
  4. package/dist/api/Cookies.json +1 -1
  5. package/dist/api/Dark.json +1 -1
  6. package/dist/api/Dialog.json +1 -1
  7. package/dist/api/IconSet.json +1 -0
  8. package/dist/api/Lang.json +1 -1
  9. package/dist/api/Loading.json +1 -1
  10. package/dist/api/LoadingBar.json +1 -1
  11. package/dist/api/LocalStorage.json +1 -1
  12. package/dist/api/Morph.json +1 -1
  13. package/dist/api/Notify.json +1 -1
  14. package/dist/api/Platform.json +1 -1
  15. package/dist/api/QAjaxBar.json +1 -1
  16. package/dist/api/QBreadcrumbsEl.json +1 -1
  17. package/dist/api/QBtn.json +1 -1
  18. package/dist/api/QBtnDropdown.json +1 -1
  19. package/dist/api/QBtnToggle.json +1 -1
  20. package/dist/api/QCard.json +1 -1
  21. package/dist/api/QCardSection.json +1 -1
  22. package/dist/api/QCarousel.json +1 -1
  23. package/dist/api/QCarouselControl.json +1 -1
  24. package/dist/api/QCheckbox.json +1 -1
  25. package/dist/api/QChip.json +1 -1
  26. package/dist/api/QDate.json +1 -1
  27. package/dist/api/QDialog.json +1 -1
  28. package/dist/api/QDrawer.json +1 -1
  29. package/dist/api/QEditor.json +1 -1
  30. package/dist/api/QExpansionItem.json +1 -1
  31. package/dist/api/QFab.json +1 -1
  32. package/dist/api/QFabAction.json +1 -1
  33. package/dist/api/QField.json +1 -1
  34. package/dist/api/QFile.json +1 -1
  35. package/dist/api/QForm.json +1 -1
  36. package/dist/api/QFormChildMixin.json +1 -1
  37. package/dist/api/QIcon.json +1 -1
  38. package/dist/api/QInfiniteScroll.json +1 -1
  39. package/dist/api/QInput.json +1 -1
  40. package/dist/api/QIntersection.json +1 -1
  41. package/dist/api/QItem.json +1 -1
  42. package/dist/api/QList.json +1 -1
  43. package/dist/api/QMenu.json +1 -1
  44. package/dist/api/QNoSsr.json +1 -1
  45. package/dist/api/QOptionGroup.json +1 -1
  46. package/dist/api/QPageScroller.json +1 -1
  47. package/dist/api/QPageSticky.json +1 -1
  48. package/dist/api/QPagination.json +1 -1
  49. package/dist/api/QParallax.json +1 -1
  50. package/dist/api/QPopupEdit.json +1 -1
  51. package/dist/api/QPopupProxy.json +1 -1
  52. package/dist/api/QPullToRefresh.json +1 -1
  53. package/dist/api/QRadio.json +1 -1
  54. package/dist/api/QRating.json +1 -1
  55. package/dist/api/QResizeObserver.json +1 -1
  56. package/dist/api/QScrollArea.json +1 -1
  57. package/dist/api/QScrollObserver.json +1 -1
  58. package/dist/api/QSelect.json +1 -1
  59. package/dist/api/QSkeleton.json +1 -1
  60. package/dist/api/QSlideItem.json +1 -1
  61. package/dist/api/QSplitter.json +1 -1
  62. package/dist/api/QStepper.json +1 -1
  63. package/dist/api/QTabPanel.json +1 -1
  64. package/dist/api/QTabPanels.json +1 -1
  65. package/dist/api/QTable.json +1 -1
  66. package/dist/api/QTime.json +1 -1
  67. package/dist/api/QTimelineEntry.json +1 -1
  68. package/dist/api/QToggle.json +1 -1
  69. package/dist/api/QTooltip.json +1 -1
  70. package/dist/api/QTree.json +1 -1
  71. package/dist/api/QUploader.json +1 -1
  72. package/dist/api/QVirtualScroll.json +1 -1
  73. package/dist/api/Ripple.json +1 -1
  74. package/dist/api/Screen.json +1 -1
  75. package/dist/api/ScrollFire.json +1 -1
  76. package/dist/api/SessionStorage.json +1 -1
  77. package/dist/icon-set/bootstrap-icons.umd.prod.js +2 -2
  78. package/dist/icon-set/eva-icons.umd.prod.js +2 -2
  79. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +2 -2
  80. package/dist/icon-set/fontawesome-v5.umd.prod.js +2 -2
  81. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +2 -2
  82. package/dist/icon-set/fontawesome-v6.umd.prod.js +2 -2
  83. package/dist/icon-set/ionicons-v4.umd.prod.js +2 -2
  84. package/dist/icon-set/line-awesome.umd.prod.js +2 -2
  85. package/dist/icon-set/material-icons-outlined.umd.prod.js +2 -2
  86. package/dist/icon-set/material-icons-round.umd.prod.js +2 -2
  87. package/dist/icon-set/material-icons-sharp.umd.prod.js +2 -2
  88. package/dist/icon-set/material-icons.umd.prod.js +2 -2
  89. package/dist/icon-set/material-symbols-outlined.umd.prod.js +2 -2
  90. package/dist/icon-set/material-symbols-rounded.umd.prod.js +2 -2
  91. package/dist/icon-set/material-symbols-sharp.umd.prod.js +2 -2
  92. package/dist/icon-set/mdi-v3.umd.prod.js +2 -2
  93. package/dist/icon-set/mdi-v4.umd.prod.js +2 -2
  94. package/dist/icon-set/mdi-v5.umd.prod.js +2 -2
  95. package/dist/icon-set/mdi-v6.umd.prod.js +2 -2
  96. package/dist/icon-set/mdi-v7.umd.prod.js +2 -2
  97. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +2 -2
  98. package/dist/icon-set/svg-eva-icons.umd.prod.js +2 -2
  99. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +2 -2
  100. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +2 -2
  101. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +2 -2
  102. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +2 -2
  103. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +2 -2
  104. package/dist/icon-set/svg-line-awesome.umd.prod.js +2 -2
  105. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +2 -2
  106. package/dist/icon-set/svg-material-icons-round.umd.prod.js +2 -2
  107. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +2 -2
  108. package/dist/icon-set/svg-material-icons.umd.prod.js +2 -2
  109. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +2 -2
  110. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +2 -2
  111. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +2 -2
  112. package/dist/icon-set/svg-mdi-v6.umd.prod.js +2 -2
  113. package/dist/icon-set/svg-mdi-v7.umd.prod.js +2 -2
  114. package/dist/icon-set/svg-themify.umd.prod.js +2 -2
  115. package/dist/icon-set/themify.umd.prod.js +2 -2
  116. package/dist/lang/ar-TN.umd.prod.js +2 -2
  117. package/dist/lang/ar.umd.prod.js +2 -2
  118. package/dist/lang/az-Latn.umd.prod.js +2 -2
  119. package/dist/lang/bg.umd.prod.js +2 -2
  120. package/dist/lang/bn.umd.prod.js +2 -2
  121. package/dist/lang/ca.umd.prod.js +2 -2
  122. package/dist/lang/cs.umd.prod.js +2 -2
  123. package/dist/lang/da.umd.prod.js +2 -2
  124. package/dist/lang/de-CH.umd.prod.js +2 -2
  125. package/dist/lang/de-DE.umd.prod.js +2 -2
  126. package/dist/lang/de.umd.prod.js +2 -2
  127. package/dist/lang/el.umd.prod.js +2 -2
  128. package/dist/lang/en-GB.umd.prod.js +2 -2
  129. package/dist/lang/en-US.umd.prod.js +2 -2
  130. package/dist/lang/eo.umd.prod.js +2 -2
  131. package/dist/lang/es.umd.prod.js +2 -2
  132. package/dist/lang/et.umd.prod.js +2 -2
  133. package/dist/lang/eu.umd.prod.js +2 -2
  134. package/dist/lang/fa-IR.umd.prod.js +2 -2
  135. package/dist/lang/fa.umd.prod.js +2 -2
  136. package/dist/lang/fi.umd.prod.js +2 -2
  137. package/dist/lang/fr.umd.prod.js +2 -2
  138. package/dist/lang/gn.umd.prod.js +2 -2
  139. package/dist/lang/he.umd.prod.js +2 -2
  140. package/dist/lang/hi.umd.prod.js +2 -2
  141. package/dist/lang/hr.umd.prod.js +2 -2
  142. package/dist/lang/hu.umd.prod.js +2 -2
  143. package/dist/lang/id.umd.prod.js +2 -2
  144. package/dist/lang/is.umd.prod.js +2 -2
  145. package/dist/lang/it.umd.prod.js +2 -2
  146. package/dist/lang/ja.umd.prod.js +2 -2
  147. package/dist/lang/kk.umd.prod.js +2 -2
  148. package/dist/lang/km.umd.prod.js +2 -2
  149. package/dist/lang/ko-KR.umd.prod.js +2 -2
  150. package/dist/lang/kur-CKB.umd.prod.js +2 -2
  151. package/dist/lang/lt.umd.prod.js +2 -2
  152. package/dist/lang/lu.umd.prod.js +2 -2
  153. package/dist/lang/lv.umd.prod.js +2 -2
  154. package/dist/lang/mk.umd.prod.js +2 -2
  155. package/dist/lang/ml.umd.prod.js +2 -2
  156. package/dist/lang/mm.umd.prod.js +2 -2
  157. package/dist/lang/ms-MY.umd.prod.js +2 -2
  158. package/dist/lang/ms.umd.prod.js +2 -2
  159. package/dist/lang/my.umd.prod.js +2 -2
  160. package/dist/lang/nb-NO.umd.prod.js +2 -2
  161. package/dist/lang/nl.umd.prod.js +2 -2
  162. package/dist/lang/pl.umd.prod.js +2 -2
  163. package/dist/lang/pt-BR.umd.prod.js +2 -2
  164. package/dist/lang/pt.umd.prod.js +2 -2
  165. package/dist/lang/ro.umd.prod.js +2 -2
  166. package/dist/lang/ru.umd.prod.js +2 -2
  167. package/dist/lang/sk.umd.prod.js +2 -2
  168. package/dist/lang/sl.umd.prod.js +2 -2
  169. package/dist/lang/sm.umd.prod.js +2 -2
  170. package/dist/lang/sr-CYR.umd.prod.js +2 -2
  171. package/dist/lang/sr.umd.prod.js +2 -2
  172. package/dist/lang/sv.umd.prod.js +2 -2
  173. package/dist/lang/ta.umd.prod.js +2 -2
  174. package/dist/lang/th.umd.prod.js +2 -2
  175. package/dist/lang/tl.umd.prod.js +2 -2
  176. package/dist/lang/tr.umd.prod.js +2 -2
  177. package/dist/lang/ug.umd.prod.js +2 -2
  178. package/dist/lang/uk.umd.prod.js +2 -2
  179. package/dist/lang/uz-Cyrl.umd.prod.js +2 -2
  180. package/dist/lang/uz-Latn.umd.prod.js +2 -2
  181. package/dist/lang/vi.umd.prod.js +2 -2
  182. package/dist/lang/zh-CN.umd.prod.js +2 -2
  183. package/dist/lang/zh-TW.umd.prod.js +2 -2
  184. package/dist/quasar.addon.prod.css +1 -1
  185. package/dist/quasar.addon.rtl.prod.css +1 -1
  186. package/dist/quasar.cjs.prod.js +12 -12
  187. package/dist/quasar.esm.js +567 -520
  188. package/dist/quasar.esm.prod.js +17 -17
  189. package/dist/quasar.prod.css +1 -1
  190. package/dist/quasar.rtl.prod.css +1 -1
  191. package/dist/quasar.sass +1 -1
  192. package/dist/quasar.umd.js +554 -506
  193. package/dist/quasar.umd.prod.js +22 -22
  194. package/dist/transforms/api-list.json +1 -1
  195. package/dist/transforms/import-map.json +1 -1
  196. package/dist/types/config.d.ts +3 -3
  197. package/dist/types/globals.d.ts +1 -1
  198. package/dist/types/index.d.ts +1921 -102
  199. package/dist/vetur/quasar-attributes.json +1 -1
  200. package/dist/vetur/quasar-tags.json +1 -1
  201. package/dist/web-types/web-types.json +1 -1
  202. package/lang/uk.js +1 -1
  203. package/lang/uk.mjs +1 -1
  204. package/package.json +18 -17
  205. package/src/api.extends.json +7 -5
  206. package/src/components/ajax-bar/QAjaxBar.js +2 -2
  207. package/src/components/ajax-bar/QAjaxBar.json +1 -0
  208. package/src/components/avatar/QAvatar.js +3 -3
  209. package/src/components/avatar/QAvatar.json +1 -1
  210. package/src/components/avatar/QAvatar.test.js +169 -83
  211. package/src/components/badge/QBadge.js +2 -2
  212. package/src/components/badge/QBadge.test.js +200 -100
  213. package/src/components/banner/QBanner.js +3 -3
  214. package/src/components/banner/QBanner.test.js +88 -50
  215. package/src/components/bar/QBar.js +3 -3
  216. package/src/components/bar/QBar.test.js +44 -19
  217. package/src/components/breadcrumbs/QBreadcrumbs.js +6 -4
  218. package/src/components/breadcrumbs/QBreadcrumbs.test.js +134 -59
  219. package/src/components/breadcrumbs/QBreadcrumbsEl.js +3 -3
  220. package/src/components/breadcrumbs/QBreadcrumbsEl.json +1 -1
  221. package/src/components/breadcrumbs/QBreadcrumbsEl.test.js +491 -61
  222. package/src/components/btn/QBtn.js +11 -5
  223. package/src/components/btn/QBtn.json +2 -1
  224. package/src/components/btn/QBtn.test.js +1391 -212
  225. package/src/components/btn/use-btn.js +8 -6
  226. package/src/components/btn/use-btn.json +1 -1
  227. package/src/components/btn/use-btn.test.js +86 -542
  228. package/src/components/btn-dropdown/QBtnDropdown.js +9 -10
  229. package/src/components/btn-dropdown/QBtnDropdown.json +3 -3
  230. package/src/components/btn-group/QBtnGroup.js +2 -2
  231. package/src/components/btn-toggle/QBtnToggle.js +3 -3
  232. package/src/components/btn-toggle/QBtnToggle.json +2 -2
  233. package/src/components/card/QCard.js +3 -3
  234. package/src/components/card/QCardActions.js +3 -3
  235. package/src/components/card/QCardSection.js +2 -2
  236. package/src/components/carousel/QCarousel.js +6 -6
  237. package/src/components/carousel/QCarousel.json +1 -1
  238. package/src/components/carousel/QCarouselControl.js +2 -2
  239. package/src/components/carousel/QCarouselControl.json +1 -1
  240. package/src/components/carousel/QCarouselSlide.js +3 -3
  241. package/src/components/carousel/QCarouselSlide.json +1 -1
  242. package/src/components/chat/QChatMessage.js +2 -2
  243. package/src/components/checkbox/QCheckbox.js +1 -1
  244. package/src/components/checkbox/use-checkbox.js +8 -8
  245. package/src/components/checkbox/use-checkbox.json +5 -3
  246. package/src/components/chip/QChip.js +6 -5
  247. package/src/components/chip/QChip.json +4 -0
  248. package/src/components/chip/QChip.test.js +685 -317
  249. package/src/components/circular-progress/QCircularProgress.js +5 -5
  250. package/src/components/circular-progress/QCircularProgress.json +1 -1
  251. package/src/components/circular-progress/{use-circular-progress.js → circular-progress.js} +1 -1
  252. package/src/components/circular-progress/circular-progress.test.js +14 -0
  253. package/src/components/color/QColor.js +10 -10
  254. package/src/components/color/QColor.json +1 -1
  255. package/src/components/date/QDate.js +9 -9
  256. package/src/components/date/QDate.json +17 -11
  257. package/src/components/date/use-datetime.js +2 -2
  258. package/src/components/date/use-datetime.json +6 -6
  259. package/src/components/dialog/QDialog.js +33 -22
  260. package/src/components/dialog/QDialog.json +5 -3
  261. package/src/components/dialog/QDialog.test.js +1094 -220
  262. package/src/components/drawer/QDrawer.js +9 -9
  263. package/src/components/drawer/QDrawer.json +7 -4
  264. package/src/components/editor/QEditor.js +9 -9
  265. package/src/components/editor/QEditor.json +11 -5
  266. package/src/components/editor/editor-caret.js +1 -1
  267. package/src/components/editor/editor-utils.js +3 -3
  268. package/src/components/expansion-item/QExpansionItem.js +9 -9
  269. package/src/components/expansion-item/QExpansionItem.json +2 -2
  270. package/src/components/fab/QFab.js +5 -5
  271. package/src/components/fab/QFab.json +1 -1
  272. package/src/components/fab/QFabAction.js +4 -4
  273. package/src/components/fab/QFabAction.json +2 -1
  274. package/src/components/fab/use-fab.json +1 -1
  275. package/src/components/field/QField.js +2 -2
  276. package/src/components/field/QField.json +7 -3
  277. package/src/components/file/QFile.js +9 -9
  278. package/src/components/file/QFile.json +11 -4
  279. package/src/components/footer/QFooter.js +3 -3
  280. package/src/components/form/QForm.js +6 -6
  281. package/src/components/form/QForm.json +11 -4
  282. package/src/components/form/QFormChildMixin.js +2 -2
  283. package/src/components/form/QFormChildMixin.json +4 -1
  284. package/src/components/header/QHeader.js +3 -3
  285. package/src/components/icon/QIcon.js +3 -3
  286. package/src/components/icon/QIcon.json +1 -1
  287. package/src/components/img/QImg.js +5 -5
  288. package/src/components/img/QImg.json +1 -1
  289. package/src/components/infinite-scroll/QInfiniteScroll.js +6 -6
  290. package/src/components/infinite-scroll/QInfiniteScroll.json +20 -7
  291. package/src/components/inner-loading/QInnerLoading.js +3 -3
  292. package/src/components/inner-loading/QInnerLoading.json +1 -1
  293. package/src/components/input/QInput.js +9 -9
  294. package/src/components/input/QInput.json +16 -5
  295. package/src/components/input/use-mask.js +1 -1
  296. package/src/components/intersection/QIntersection.js +2 -2
  297. package/src/components/item/QItem.js +6 -6
  298. package/src/components/item/QItem.json +1 -1
  299. package/src/components/item/QItemLabel.js +2 -2
  300. package/src/components/item/QItemSection.js +2 -2
  301. package/src/components/item/QList.js +3 -3
  302. package/src/components/knob/QKnob.js +6 -6
  303. package/src/components/knob/QKnob.json +1 -1
  304. package/src/components/layout/QLayout.js +4 -4
  305. package/src/components/linear-progress/QLinearProgress.js +4 -4
  306. package/src/components/linear-progress/QLinearProgress.json +1 -1
  307. package/src/components/markup-table/QMarkupTable.js +3 -3
  308. package/src/components/menu/QMenu.js +20 -20
  309. package/src/components/menu/QMenu.json +8 -4
  310. package/src/components/no-ssr/QNoSsr.js +3 -3
  311. package/src/components/option-group/QOptionGroup.js +2 -2
  312. package/src/components/option-group/QOptionGroup.json +4 -4
  313. package/src/components/page/QPage.js +3 -3
  314. package/src/components/page/QPageContainer.js +3 -3
  315. package/src/components/page-scroller/QPageScroller.js +2 -2
  316. package/src/components/page-sticky/QPageSticky.js +1 -1
  317. package/src/components/page-sticky/QPageSticky.json +1 -1
  318. package/src/components/page-sticky/use-page-sticky.js +2 -2
  319. package/src/components/pagination/QPagination.js +4 -4
  320. package/src/components/pagination/QPagination.json +5 -3
  321. package/src/components/parallax/QParallax.js +6 -6
  322. package/src/components/popup-edit/QPopupEdit.js +4 -4
  323. package/src/components/popup-edit/QPopupEdit.json +30 -14
  324. package/src/components/popup-proxy/QPopupProxy.js +3 -3
  325. package/src/components/popup-proxy/QPopupProxy.json +9 -5
  326. package/src/components/pull-to-refresh/QPullToRefresh.js +5 -5
  327. package/src/components/pull-to-refresh/QPullToRefresh.json +6 -2
  328. package/src/components/radio/QRadio.js +9 -9
  329. package/src/components/radio/QRadio.json +4 -2
  330. package/src/components/range/QRange.js +3 -3
  331. package/src/components/rating/QRating.js +6 -6
  332. package/src/components/rating/QRating.json +2 -2
  333. package/src/components/resize-observer/QResizeObserver.js +3 -3
  334. package/src/components/resize-observer/QResizeObserver.json +2 -1
  335. package/src/components/responsive/QResponsive.js +3 -3
  336. package/src/components/responsive/QResponsive.json +1 -1
  337. package/src/components/scroll-area/QScrollArea.js +6 -6
  338. package/src/components/scroll-area/QScrollArea.json +8 -2
  339. package/src/components/scroll-observer/QScrollObserver.js +3 -3
  340. package/src/components/scroll-observer/QScrollObserver.json +5 -2
  341. package/src/components/select/QSelect.js +10 -10
  342. package/src/components/select/QSelect.json +38 -17
  343. package/src/components/separator/QSeparator.js +2 -2
  344. package/src/components/skeleton/QSkeleton.js +3 -3
  345. package/src/components/slide-item/QSlideItem.js +4 -4
  346. package/src/components/slide-item/QSlideItem.json +3 -1
  347. package/src/components/slide-transition/QSlideTransition.js +1 -1
  348. package/src/components/slider/QSlider.js +4 -4
  349. package/src/components/slider/use-slider.js +6 -6
  350. package/src/components/slider/use-slider.json +1 -1
  351. package/src/components/space/QSpace.js +1 -1
  352. package/src/components/space/QSpace.test.js +17 -0
  353. package/src/components/spinner/QSpinner.js +1 -1
  354. package/src/components/spinner/QSpinner.json +1 -1
  355. package/src/components/spinner/QSpinnerAudio.js +1 -1
  356. package/src/components/spinner/QSpinnerBall.js +1 -1
  357. package/src/components/spinner/QSpinnerBars.js +1 -1
  358. package/src/components/spinner/QSpinnerBox.js +1 -1
  359. package/src/components/spinner/QSpinnerClock.js +1 -1
  360. package/src/components/spinner/QSpinnerComment.js +1 -1
  361. package/src/components/spinner/QSpinnerCube.js +1 -1
  362. package/src/components/spinner/QSpinnerDots.js +1 -1
  363. package/src/components/spinner/QSpinnerFacebook.js +1 -1
  364. package/src/components/spinner/QSpinnerGears.js +1 -1
  365. package/src/components/spinner/QSpinnerGrid.js +1 -1
  366. package/src/components/spinner/QSpinnerHearts.js +1 -1
  367. package/src/components/spinner/QSpinnerHourglass.js +1 -1
  368. package/src/components/spinner/QSpinnerInfinity.js +1 -1
  369. package/src/components/spinner/QSpinnerIos.js +1 -1
  370. package/src/components/spinner/QSpinnerOrbit.js +1 -1
  371. package/src/components/spinner/QSpinnerOval.js +1 -1
  372. package/src/components/spinner/QSpinnerPie.js +1 -1
  373. package/src/components/spinner/QSpinnerPuff.js +1 -1
  374. package/src/components/spinner/QSpinnerRadio.js +1 -1
  375. package/src/components/spinner/QSpinnerRings.js +1 -1
  376. package/src/components/spinner/QSpinnerTail.js +1 -1
  377. package/src/components/spinner/spinner.json +1 -1
  378. package/src/components/spinner/use-spinner.js +1 -1
  379. package/src/components/splitter/QSplitter.js +3 -3
  380. package/src/components/splitter/QSplitter.json +4 -4
  381. package/src/components/stepper/QStep.js +5 -5
  382. package/src/components/stepper/QStep.json +1 -1
  383. package/src/components/stepper/QStepper.js +5 -5
  384. package/src/components/stepper/QStepper.json +1 -1
  385. package/src/components/stepper/QStepperNavigation.js +2 -2
  386. package/src/components/stepper/StepHeader.js +1 -1
  387. package/src/components/tab-panels/QTabPanel.js +3 -3
  388. package/src/components/tab-panels/QTabPanel.json +1 -7
  389. package/src/components/tab-panels/QTabPanels.js +4 -4
  390. package/src/components/tab-panels/QTabPanels.json +1 -1
  391. package/src/components/table/QTable.js +7 -7
  392. package/src/components/table/QTable.json +41 -22
  393. package/src/components/table/QTd.js +2 -2
  394. package/src/components/table/QTh.js +2 -2
  395. package/src/components/table/QTr.js +2 -2
  396. package/src/components/table/table-column-selection.js +1 -1
  397. package/src/components/table/table-sort.js +2 -2
  398. package/src/components/tabs/QRouteTab.js +2 -2
  399. package/src/components/tabs/QRouteTab.json +1 -1
  400. package/src/components/tabs/QTab.js +1 -1
  401. package/src/components/tabs/QTabs.js +6 -6
  402. package/src/components/tabs/use-tab.js +6 -6
  403. package/src/components/time/QTime.js +8 -8
  404. package/src/components/time/QTime.json +5 -3
  405. package/src/components/timeline/QTimeline.js +4 -4
  406. package/src/components/timeline/QTimelineEntry.js +3 -3
  407. package/src/components/toggle/QToggle.js +1 -1
  408. package/src/components/toolbar/QToolbar.js +2 -2
  409. package/src/components/toolbar/QToolbarTitle.js +2 -2
  410. package/src/components/tooltip/QTooltip.js +15 -15
  411. package/src/components/tooltip/QTooltip.json +6 -5
  412. package/src/components/tree/QTree.js +5 -5
  413. package/src/components/tree/QTree.json +12 -4
  414. package/src/components/uploader/QUploader.js +1 -1
  415. package/src/components/uploader/QUploader.json +25 -10
  416. package/src/components/uploader/QUploaderAddTrigger.js +2 -2
  417. package/src/components/uploader/uploader-core.js +8 -8
  418. package/src/components/uploader/xhr-uploader-plugin.js +3 -1
  419. package/src/components/uploader/xhr-uploader-plugin.json +9 -9
  420. package/src/components/video/QVideo.js +2 -2
  421. package/src/components/video/QVideo.json +1 -1
  422. package/src/components/video/QVideo.test.js +183 -0
  423. package/src/components/virtual-scroll/QVirtualScroll.js +4 -4
  424. package/src/components/virtual-scroll/QVirtualScroll.json +1 -0
  425. package/src/components/virtual-scroll/use-virtual-scroll.js +3 -3
  426. package/src/components/virtual-scroll/use-virtual-scroll.json +7 -3
  427. package/src/composables/private.use-align/use-align.test.js +62 -0
  428. package/src/composables/{private → private.use-anchor}/use-anchor.js +3 -3
  429. package/src/composables/{private → private.use-anchor}/use-anchor.json +0 -1
  430. package/src/composables/private.use-dark/use-dark.test.js +68 -0
  431. package/src/composables/{private → private.use-field}/use-field.js +8 -8
  432. package/src/composables/{private → private.use-field}/use-field.json +7 -10
  433. package/src/composables/{private → private.use-file}/use-file.js +1 -1
  434. package/src/composables/{private → private.use-file}/use-file.json +4 -2
  435. package/src/composables/{private → private.use-fullscreen}/use-fullscreen.js +2 -2
  436. package/src/composables/{private → private.use-fullscreen}/use-fullscreen.json +9 -3
  437. package/src/composables/{private → private.use-history}/use-history.js +1 -1
  438. package/src/composables/private.use-history/use-history.test.js +116 -0
  439. package/src/composables/{private → private.use-model-toggle}/use-model-toggle.js +1 -1
  440. package/src/composables/{private → private.use-panel}/use-panel.js +3 -3
  441. package/src/composables/{private → private.use-panel}/use-panel.json +10 -5
  442. package/src/composables/{private → private.use-portal}/use-portal.js +6 -6
  443. package/src/composables/{private → private.use-prevent-scroll}/use-prevent-scroll.js +1 -1
  444. package/src/composables/private.use-ratio/use-ratio.test.js +40 -0
  445. package/src/composables/{private → private.use-router-link}/use-router-link.js +1 -1
  446. package/src/composables/{private → private.use-scroll-target}/use-scroll-target.js +2 -5
  447. package/src/composables/private.use-size/use-size.test.js +40 -0
  448. package/src/composables/private.use-transition/use-transition.test.js +118 -0
  449. package/src/composables/{private → private.use-validate}/use-validate.js +4 -4
  450. package/src/composables/{private → private.use-validate}/use-validate.json +3 -1
  451. package/src/composables/{use-dialog-plugin-component.js → use-dialog-plugin-component/use-dialog-plugin-component.js} +2 -4
  452. package/src/composables/use-form/private.use-form.test.js +107 -0
  453. package/src/composables/{use-form-child.js → use-form/use-form-child.js} +1 -1
  454. package/src/composables/{use-hydration.js → use-hydration/use-hydration.js} +1 -1
  455. package/src/composables/use-hydration/use-hydration.test.js +27 -0
  456. package/src/composables/{use-id.js → use-id/use-id.js} +2 -2
  457. package/src/composables/use-id/use-id.test.js +72 -0
  458. package/src/composables/{use-interval.js → use-interval/use-interval.js} +1 -1
  459. package/src/composables/{use-meta.js → use-meta/use-meta.js} +1 -1
  460. package/src/composables/{use-quasar.js → use-quasar/use-quasar.js} +2 -1
  461. package/src/composables/use-quasar/use-quasar.test.js +35 -0
  462. package/src/composables/{use-tick.js → use-tick/use-tick.js} +1 -1
  463. package/src/composables/{use-timeout.js → use-timeout/use-timeout.js} +1 -1
  464. package/src/composables.js +11 -11
  465. package/src/css/index.sass +1 -1
  466. package/src/directives/close-popup/ClosePopup.js +4 -4
  467. package/src/directives/intersection/Intersection.js +3 -3
  468. package/src/directives/morph/Morph.js +2 -2
  469. package/src/directives/morph/Morph.json +1 -1
  470. package/src/directives/mutation/Mutation.js +2 -2
  471. package/src/directives/ripple/Ripple.js +6 -6
  472. package/src/directives/ripple/Ripple.json +2 -2
  473. package/src/directives/ripple/Ripple.test.js +340 -0
  474. package/src/directives/scroll/Scroll.js +4 -4
  475. package/src/directives/scroll-fire/ScrollFire.js +6 -6
  476. package/src/directives/scroll-fire/ScrollFire.json +1 -1
  477. package/src/directives/touch-hold/TouchHold.js +4 -4
  478. package/src/directives/touch-pan/TouchPan.js +5 -5
  479. package/src/directives/touch-repeat/TouchRepeat.js +5 -5
  480. package/src/directives/touch-swipe/TouchSwipe.js +5 -5
  481. package/src/index.dev.js +10 -4
  482. package/src/index.prod.js +11 -4
  483. package/src/index.ssr.js +11 -4
  484. package/src/index.umd.js +12 -4
  485. package/src/install-quasar.js +14 -9
  486. package/src/plugins/addressbar/AddressbarColor.js +2 -2
  487. package/src/plugins/addressbar/AddressbarColor.json +2 -1
  488. package/src/plugins/app-fullscreen/AppFullscreen.js +3 -3
  489. package/src/plugins/app-fullscreen/AppFullscreen.json +1 -0
  490. package/src/plugins/app-visibility/AppVisibility.js +3 -3
  491. package/src/plugins/bottom-sheet/BottomSheet.js +2 -5
  492. package/src/plugins/bottom-sheet/BottomSheet.json +1 -1
  493. package/src/plugins/bottom-sheet/component/BottomSheetComponent.js +2 -2
  494. package/src/plugins/cookies/Cookies.json +5 -2
  495. package/src/plugins/dark/Dark.js +2 -2
  496. package/src/plugins/dark/Dark.json +5 -2
  497. package/src/plugins/dialog/Dialog.js +2 -5
  498. package/src/plugins/dialog/Dialog.json +3 -3
  499. package/src/plugins/dialog/component/DialogPluginComponent.js +4 -4
  500. package/src/{icon-set.js → plugins/icon-set/IconSet.js} +29 -10
  501. package/src/plugins/icon-set/IconSet.json +1417 -0
  502. package/src/plugins/icon-set/IconSet.test.js +346 -0
  503. package/src/{lang.js → plugins/lang/Lang.js} +25 -15
  504. package/src/plugins/lang/Lang.json +1100 -0
  505. package/src/plugins/lang/Lang.test.js +267 -0
  506. package/src/plugins/loading/Loading.js +5 -5
  507. package/src/plugins/loading/Loading.json +4 -2
  508. package/src/plugins/loading-bar/LoadingBar.js +5 -5
  509. package/src/plugins/loading-bar/LoadingBar.json +9 -4
  510. package/src/plugins/meta/Meta.js +1 -1
  511. package/src/plugins/notify/Notify.js +4 -4
  512. package/src/plugins/notify/Notify.json +8 -6
  513. package/src/plugins/platform/Platform.js +3 -4
  514. package/src/plugins/platform/Platform.json +6 -0
  515. package/src/plugins/platform/Platform.test.js +104 -0
  516. package/src/{body.js → plugins/private.body/Body.js} +5 -4
  517. package/src/{history.js → plugins/private.history/History.js} +2 -2
  518. package/src/plugins/screen/Screen.js +4 -4
  519. package/src/plugins/screen/Screen.json +4 -2
  520. package/src/plugins/{local-storage → storage}/LocalStorage.js +1 -1
  521. package/src/plugins/storage/LocalStorage.json +5 -0
  522. package/src/plugins/storage/LocalStorage.test.js +323 -0
  523. package/src/plugins/{session-storage → storage}/SessionStorage.js +1 -1
  524. package/src/plugins/storage/SessionStorage.json +5 -0
  525. package/src/plugins/storage/SessionStorage.test.js +323 -0
  526. package/src/{utils/private → plugins/storage/engine}/web-storage.js +21 -10
  527. package/src/{utils/private → plugins/storage/engine}/web-storage.json +22 -11
  528. package/src/plugins/storage/engine/web-storage.test.js +43 -0
  529. package/src/plugins.js +8 -4
  530. package/src/utils/EventBus/EventBus.test.js +108 -0
  531. package/src/utils/clone/clone.test.js +111 -0
  532. package/src/utils/colors/colors.test.js +459 -0
  533. package/src/utils/{copy-to-clipboard.js → copy-to-clipboard/copy-to-clipboard.js} +1 -1
  534. package/src/utils/{create-meta-mixin.js → create-meta-mixin/create-meta-mixin.js} +1 -1
  535. package/src/utils/{create-uploader-component.js → create-uploader-component/create-uploader-component.js} +4 -4
  536. package/src/utils/css-var/get-css-var.test.js +32 -0
  537. package/src/utils/css-var/set-css-var.test.js +36 -0
  538. package/src/utils/{date.js → date/date.js} +6 -6
  539. package/src/utils/debounce/debounce.test.js +188 -0
  540. package/src/utils/extend/extend.test.js +93 -0
  541. package/src/utils/{format.js → format/format.js} +2 -2
  542. package/src/utils/format/format.test.js +107 -0
  543. package/src/utils/{frame-debounce.js → frame-debounce/frame-debounce.js} +1 -1
  544. package/src/utils/frame-debounce/frame-debounce.test.js +127 -0
  545. package/src/utils/is/is.test.js +125 -0
  546. package/src/utils/{morph.js → morph/morph.js} +1 -1
  547. package/src/utils/{open-url.js → open-url/open-url.js} +3 -3
  548. package/src/utils/patterns/patterns.test.js +403 -0
  549. package/src/utils/{private → private.click-outside}/click-outside.js +2 -2
  550. package/src/utils/{private/define-reactive-plugin.js → private.create/create.js} +6 -3
  551. package/src/utils/private.create/create.test.js +58 -0
  552. package/src/utils/private.focus/focus-manager.test.js +190 -0
  553. package/src/utils/private.focus/focusout.test.js +114 -0
  554. package/src/utils/private.get-emits-object/get-emits-object.test.js +29 -0
  555. package/src/utils/private.global/global-config.test.js +54 -0
  556. package/src/utils/{private → private.global}/global-dialog.js +1 -1
  557. package/src/utils/{private → private.global}/global-dialog.json +1 -1
  558. package/src/utils/{private → private.global}/global-nodes.js +1 -1
  559. package/src/utils/private.global/global-nodes.test.js +110 -0
  560. package/src/utils/private.inject-obj-prop/inject-obj-prop.test.js +104 -0
  561. package/src/utils/{private → private.keyboard}/escape-key.js +1 -1
  562. package/src/utils/private.keyboard/escape-key.test.js +117 -0
  563. package/src/utils/private.noop-ssr-directive-transform/noop-ssr-directive-transform.test.js +14 -0
  564. package/src/utils/{private → private.portal}/portal.js +1 -1
  565. package/src/utils/{private → private.position-engine}/position-engine.js +1 -1
  566. package/src/utils/private.rtl/rtl.test.js +13 -0
  567. package/src/utils/private.sort/sort.test.js +25 -0
  568. package/src/utils/{private → private.symbols}/symbols.js +1 -1
  569. package/src/utils/private.touch/touch.test.js +102 -0
  570. package/src/utils/{prevent-scroll.js → scroll/prevent-scroll.js} +3 -3
  571. package/src/utils/{scroll.js → scroll/scroll.js} +1 -1
  572. package/src/utils/throttle/throttle.test.js +146 -0
  573. package/src/utils/uid/uid.test.js +17 -0
  574. package/src/utils.js +24 -24
  575. package/src/vue-plugin.js +12 -4
  576. package/src/Lang.json +0 -19
  577. package/src/api-file-example.json +0 -94
  578. package/src/composables/private/__tests__/use-form.cy.js +0 -11
  579. package/src/composables/private/__tests__/use-size.cy.js +0 -36
  580. package/src/composables/private/__tests__/use-transition.cy.js +0 -111
  581. package/src/composables/private/use-form.test.js +0 -93
  582. package/src/composables/private/use-ratio.test.js +0 -27
  583. package/src/composables/private/use-size.test.js +0 -22
  584. package/src/composables/use-id.test.js +0 -55
  585. package/src/plugins/local-storage/LocalStorage.json +0 -5
  586. package/src/plugins/session-storage/SessionStorage.json +0 -5
  587. package/src/utils/private/create.js +0 -4
  588. /package/src/composables/{private/__tests__ → __tests__}/FieldWrapper.vue +0 -0
  589. /package/src/composables/{private/__tests__ → __tests__}/use-anchor.cy.js +0 -0
  590. /package/src/composables/{private/__tests__ → __tests__}/use-field.cy.js +0 -0
  591. /package/src/composables/{private/__tests__ → __tests__}/use-file.cy.js +0 -0
  592. /package/src/composables/{private/__tests__ → __tests__}/use-fullscreen.cy.js +0 -0
  593. /package/src/composables/{private/__tests__ → __tests__}/use-model-toggle.cy.js +0 -0
  594. /package/src/composables/{private/__tests__ → __tests__}/use-portal.cy.js +0 -0
  595. /package/src/composables/{private/__tests__ → __tests__}/use-router-link.cy.js +0 -0
  596. /package/src/composables/{private/__tests__ → __tests__}/use-validate.cy.js +0 -0
  597. /package/src/composables/{private → private.use-align}/use-align.js +0 -0
  598. /package/src/composables/{private → private.use-dark}/use-dark.js +0 -0
  599. /package/src/composables/{private → private.use-file}/use-file-dom-props.js +0 -0
  600. /package/src/composables/{private → private.use-key-composition}/use-key-composition.js +0 -0
  601. /package/src/composables/{private → private.use-model-toggle}/use-model-toggle.json +0 -0
  602. /package/src/composables/{private → private.use-panel}/use-panel.child.json +0 -0
  603. /package/src/composables/{private → private.use-panel}/use-panel.sass +0 -0
  604. /package/src/composables/{private → private.use-portal}/use-portal.json +0 -0
  605. /package/src/composables/{private → private.use-ratio}/use-ratio.js +0 -0
  606. /package/src/composables/{private → private.use-ratio}/use-ratio.json +0 -0
  607. /package/src/composables/{private → private.use-refocus-target}/use-refocus-target.js +0 -0
  608. /package/src/composables/{private → private.use-router-link}/use-router-link.json +0 -0
  609. /package/src/composables/{private → private.use-size}/use-size.js +0 -0
  610. /package/src/composables/{private → private.use-size}/use-size.json +0 -0
  611. /package/src/composables/{private → private.use-transition}/use-transition.js +0 -0
  612. /package/src/composables/{private → private.use-transition}/use-transition.json +0 -0
  613. /package/src/composables/{private/use-form.js → use-form/private.use-form.js} +0 -0
  614. /package/src/composables/{private/use-form.json → use-form/private.use-form.json} +0 -0
  615. /package/src/composables/{use-render-cache.js → use-render-cache/use-render-cache.js} +0 -0
  616. /package/src/composables/{use-split-attrs.js → use-split-attrs/use-split-attrs.js} +0 -0
  617. /package/src/utils/{EventBus.js → EventBus/EventBus.js} +0 -0
  618. /package/src/utils/{clone.js → clone/clone.js} +0 -0
  619. /package/src/utils/{colors.js → colors/colors.js} +0 -0
  620. /package/src/utils/{get-css-var.js → css-var/get-css-var.js} +0 -0
  621. /package/src/utils/{set-css-var.js → css-var/set-css-var.js} +0 -0
  622. /package/src/utils/{private/date-persian.js → date/private.persian.js} +0 -0
  623. /package/src/utils/{debounce.js → debounce/debounce.js} +0 -0
  624. /package/src/utils/{dom.js → dom/dom.js} +0 -0
  625. /package/src/utils/{event.js → event/event.js} +0 -0
  626. /package/src/utils/{export-file.js → export-file/export-file.js} +0 -0
  627. /package/src/utils/{extend.js → extend/extend.js} +0 -0
  628. /package/src/utils/{is.js → is/is.js} +0 -0
  629. /package/src/utils/{patterns.js → patterns/patterns.js} +0 -0
  630. /package/src/utils/{private → private.focus}/focus-manager.js +0 -0
  631. /package/src/utils/{private → private.focus}/focusout.js +0 -0
  632. /package/src/utils/{private → private.get-emits-object}/get-emits-object.js +0 -0
  633. /package/src/utils/{private → private.global}/global-config.js +0 -0
  634. /package/src/utils/{private → private.inject-obj-prop}/inject-obj-prop.js +0 -0
  635. /package/src/utils/{private → private.keyboard}/key-composition.js +0 -0
  636. /package/src/utils/{private → private.noop-ssr-directive-transform}/noop-ssr-directive-transform.js +0 -0
  637. /package/src/utils/{private → private.option-sizes}/option-sizes.js +0 -0
  638. /package/src/utils/{private → private.render}/render.js +0 -0
  639. /package/src/utils/{private → private.rtl}/rtl.js +0 -0
  640. /package/src/utils/{private → private.selection}/selection.js +0 -0
  641. /package/src/utils/{private → private.sort}/sort.js +0 -0
  642. /package/src/utils/{private → private.touch}/touch.js +0 -0
  643. /package/src/utils/{private → private.vm}/vm.js +0 -0
  644. /package/src/utils/{run-sequential-promises.js → run-sequential-promises/run-sequential-promises.js} +0 -0
  645. /package/src/utils/{throttle.js → throttle/throttle.js} +0 -0
  646. /package/src/utils/{uid.js → uid/uid.js} +0 -0
@@ -1,349 +1,1528 @@
1
- import { mount } from '@vue/test-utils'
1
+ import { mount, flushPromises } from '@vue/test-utils'
2
2
  import { describe, test, expect, vi } from 'vitest'
3
3
 
4
4
  import QBtn from './QBtn.js'
5
5
 
6
- const defaultOptions = {
7
- label: 'simple Btn'
8
- }
9
-
10
- function mountQBtn (options = {}) {
11
- options.props = {
12
- ...defaultOptions,
13
- ...options.props
14
- }
15
-
16
- return mount(QBtn, options)
17
- }
6
+ import { btnPadding, defaultSizes } from './use-btn.js'
7
+ import { alignMap } from 'quasar/src/composables/private.use-align/use-align.js'
8
+ import { getRouter } from 'testing/runtime/router.js'
18
9
 
19
10
  describe('[QBtn API]', () => {
20
11
  describe('[Props]', () => {
21
- describe('[(prop)percentage]', () => {
22
- test('should render a button with a percentage when "loading" prop is set to true', () => {
23
- const percentage = 50
24
- const wrapper = mountQBtn({
12
+ describe('[(prop)size]', () => {
13
+ test('is defined correctly', () => {
14
+ expect(QBtn.props.size).toBeDefined()
15
+ })
16
+
17
+ test('type String has effect (in pixels)', async () => {
18
+ const propVal = '50px'
19
+ const wrapper = mount(QBtn)
20
+ const target = wrapper.get('.q-btn')
21
+
22
+ expect(
23
+ target.$style('font-size')
24
+ ).not.toBe(propVal)
25
+
26
+ await wrapper.setProps({ size: propVal })
27
+ await flushPromises()
28
+
29
+ expect(
30
+ target.$style('font-size')
31
+ ).toBe(propVal)
32
+ })
33
+
34
+ test('type String has effect (as "xs")', async () => {
35
+ const propVal = 'xs'
36
+ const wrapper = mount(QBtn)
37
+ const target = wrapper.get('.q-btn')
38
+
39
+ expect(
40
+ target.$style('font-size')
41
+ ).not.toBe(`${ defaultSizes.xs }px`)
42
+
43
+ await wrapper.setProps({ size: propVal })
44
+ await flushPromises()
45
+
46
+ expect(
47
+ target.$style('font-size')
48
+ ).toBe(`${ defaultSizes.xs }px`)
49
+ })
50
+ })
51
+
52
+ describe('[(prop)type]', () => {
53
+ test('is defined correctly', () => {
54
+ expect(QBtn.props.type).toBeDefined()
55
+ })
56
+
57
+ test.each([
58
+ [ 'button' ],
59
+ [ 'a' ]
60
+ ])('type "%s" has effect', (propVal) => {
61
+ const wrapper = mount(QBtn, {
25
62
  props: {
26
- percentage,
27
- loading: true
63
+ type: propVal
28
64
  }
29
65
  })
30
66
 
31
67
  expect(
32
- wrapper.get('.q-btn')
33
- .attributes('aria-valuenow')
34
- ).toBe(percentage.toString())
68
+ wrapper.get('.q-btn').element.tagName.toLowerCase()
69
+ ).toBe(propVal)
35
70
  })
36
- })
37
71
 
38
- describe('[(prop)dark-percentage]', () => {
39
- test('should render a button with a dark percentage when "loading" prop is set to true', () => {
40
- const percentage = 50
41
- const wrapper = mountQBtn({
72
+ test.each([
73
+ [ 'submit' ],
74
+ [ 'reset' ]
75
+ ])('type "%s" has effect', (propVal) => {
76
+ const wrapper = mount(QBtn, {
42
77
  props: {
43
- percentage,
44
- loading: true,
45
- darkPercentage: true
78
+ type: propVal
46
79
  }
47
80
  })
48
81
 
49
82
  expect(
50
- wrapper.get('.q-btn')
51
- .attributes('aria-valuenow')
52
- ).toBe(percentage.toString())
83
+ wrapper.get('.q-btn').element.tagName.toLowerCase()
84
+ ).toBe('button')
85
+ })
86
+
87
+ // accessibility
88
+ test.each([
89
+ [ 'media/html' ],
90
+ [ 'image/png' ]
91
+ ])('type "%s" has effect', (propVal) => {
92
+ const wrapper = mount(QBtn, {
93
+ props: {
94
+ type: propVal,
95
+ href: 'https://quasar.dev'
96
+ }
97
+ })
98
+
99
+ const target = wrapper.get('.q-btn')
53
100
 
54
101
  expect(
55
- wrapper.get('.q-btn__progress')
56
- .classes()
57
- ).toContain('q-btn__progress--dark')
102
+ target.element.tagName.toLowerCase()
103
+ ).toBe('a')
104
+
105
+ expect(
106
+ target.attributes('type')
107
+ ).toBe(propVal)
58
108
  })
59
109
  })
60
110
 
61
- describe.todo('(prop): loading', () => {
62
- test(' ', () => {
63
- //
111
+ describe('[(prop)to]', () => {
112
+ test('is defined correctly', () => {
113
+ expect(QBtn.props.to).toBeDefined()
64
114
  })
65
- })
66
115
 
67
- describe.todo('(prop): disable', () => {
68
- test(' ', () => {
69
- //
116
+ test('type String has effect', async () => {
117
+ const testRoute = '/home/dashboard'
118
+ const router = await getRouter(testRoute)
119
+
120
+ const wrapper = mount(QBtn, {
121
+ global: {
122
+ plugins: [ router ]
123
+ }
124
+ })
125
+
126
+ expect(
127
+ wrapper.find('a').exists()
128
+ ).toBe(false)
129
+
130
+ await wrapper.setProps({ to: testRoute })
131
+ await flushPromises()
132
+
133
+ expect(
134
+ wrapper.get('a').attributes('href')
135
+ ).toBe(testRoute)
136
+
137
+ const routerFn = vi.spyOn(router, 'push')
138
+
139
+ await wrapper.trigger('click')
140
+ await flushPromises()
141
+
142
+ expect(
143
+ router.currentRoute.value.path
144
+ ).toBe(testRoute)
145
+
146
+ expect(routerFn).toHaveBeenCalledTimes(1)
147
+ expect(routerFn).toHaveBeenCalledWith(testRoute)
148
+ })
149
+
150
+ test('type Object has effect', async () => {
151
+ const testRoute = '/my-route-name'
152
+ const propVal = { path: testRoute }
153
+ const router = await getRouter(testRoute)
154
+
155
+ const wrapper = mount(QBtn, {
156
+ global: {
157
+ plugins: [ router ]
158
+ }
159
+ })
160
+
161
+ expect(
162
+ wrapper.find('a').exists()
163
+ ).toBe(false)
164
+
165
+ await wrapper.setProps({ to: propVal })
166
+ await flushPromises()
167
+
168
+ expect(
169
+ wrapper.get('a').attributes('href')
170
+ ).toBe(testRoute)
171
+
172
+ const routerFn = vi.spyOn(router, 'push')
173
+
174
+ await wrapper.trigger('click')
175
+ await flushPromises()
176
+
177
+ expect(
178
+ router.currentRoute.value.path
179
+ ).toBe(testRoute)
180
+
181
+ expect(routerFn).toHaveBeenCalledTimes(1)
182
+ expect(routerFn).toHaveBeenCalledWith(propVal)
70
183
  })
71
184
  })
72
185
 
73
- describe('[(prop)round]', () => {
74
- test('should render a circle shaped button when "round" prop is set to true', () => {
75
- const wrapper = mountQBtn({
186
+ describe('[(prop)replace]', () => {
187
+ test('is defined correctly', () => {
188
+ expect(QBtn.props.replace).toBeDefined()
189
+ })
190
+
191
+ test('type Boolean has effect', async () => {
192
+ const testRoute = '/test-route'
193
+ const router = await getRouter(testRoute)
194
+
195
+ const wrapper = mount(QBtn, {
76
196
  props: {
77
- round: true
197
+ replace: true,
198
+ to: testRoute
199
+ },
200
+ global: {
201
+ plugins: [ router ]
78
202
  }
79
203
  })
80
204
 
81
205
  expect(
82
- wrapper.get('.q-btn')
83
- .classes()
84
- ).toContain('q-btn--round')
206
+ wrapper.get('a').attributes('href')
207
+ ).toBe(testRoute)
208
+
209
+ const routerFn = vi.spyOn(router, 'replace')
210
+
211
+ await wrapper.trigger('click')
212
+ await flushPromises()
213
+
214
+ expect(
215
+ router.currentRoute.value.path
216
+ ).toBe(testRoute)
217
+
218
+ expect(routerFn).toHaveBeenCalledTimes(1)
219
+ expect(routerFn).toHaveBeenCalledWith(testRoute)
85
220
  })
86
221
  })
87
222
 
88
- describe.todo('(prop): size', () => {
89
- test(' ', () => {
90
- //
223
+ describe('[(prop)href]', () => {
224
+ test('is defined correctly', () => {
225
+ expect(QBtn.props.href).toBeDefined()
91
226
  })
92
- })
93
227
 
94
- describe.todo('(prop): outline', () => {
95
- test(' ', () => {
96
- //
228
+ test('type String has effect', async () => {
229
+ const propVal = 'https://quasar.dev'
230
+ const wrapper = mount(QBtn)
231
+
232
+ expect(
233
+ wrapper.find('a').exists()
234
+ ).toBe(false)
235
+
236
+ await wrapper.setProps({ href: propVal })
237
+ await flushPromises()
238
+
239
+ expect(
240
+ wrapper.get('a').attributes('href')
241
+ ).toBe(propVal)
97
242
  })
98
243
  })
99
244
 
100
- describe.todo('(prop): flat', () => {
101
- test(' ', () => {
102
- //
245
+ describe('[(prop)target]', () => {
246
+ test('is defined correctly', () => {
247
+ expect(QBtn.props.target).toBeDefined()
103
248
  })
104
- })
105
249
 
106
- describe.todo('(prop): unelevated', () => {
107
- test(' ', () => {
108
- //
250
+ test('type String has effect', () => {
251
+ const propVal = '_blank'
252
+ const href = 'https://quasar.dev'
253
+ const wrapper = mount(QBtn, {
254
+ props: {
255
+ href,
256
+ target: propVal
257
+ }
258
+ })
259
+
260
+ const link = wrapper.get('a')
261
+
262
+ expect(
263
+ link.attributes('href')
264
+ ).toBe(href)
265
+
266
+ expect(
267
+ link.attributes('target')
268
+ ).toBe(propVal)
109
269
  })
110
270
  })
111
271
 
112
- describe.todo('(prop): rounded', () => {
113
- test(' ', () => {
114
- //
272
+ describe('[(prop)label]', () => {
273
+ test('is defined correctly', () => {
274
+ expect(QBtn.props.label).toBeDefined()
115
275
  })
116
- })
117
276
 
118
- describe.todo('(prop): push', () => {
119
- test(' ', () => {
120
- //
277
+ test('type String has effect', async () => {
278
+ const propVal = 'Button Label'
279
+ const wrapper = mount(QBtn)
280
+
281
+ expect(wrapper.text()).not.toContain(propVal)
282
+
283
+ await wrapper.setProps({ label: propVal })
284
+ await flushPromises()
285
+
286
+ expect(wrapper.text()).toContain(propVal)
121
287
  })
122
- })
123
288
 
124
- describe.todo('(prop): square', () => {
125
- test(' ', () => {
126
- //
289
+ test('type Number has effect', async () => {
290
+ const propVal = 10
291
+ const wrapper = mount(QBtn)
292
+
293
+ expect(wrapper.text()).not.toContain('' + propVal)
294
+
295
+ await wrapper.setProps({ label: propVal })
296
+ await flushPromises()
297
+
298
+ expect(wrapper.text()).toContain('' + propVal)
127
299
  })
128
300
  })
129
301
 
130
- describe.todo('(prop): glossy', () => {
131
- test(' ', () => {
132
- //
302
+ describe('[(prop)icon]', () => {
303
+ test('is defined correctly', () => {
304
+ expect(QBtn.props.icon).toBeDefined()
133
305
  })
134
- })
135
306
 
136
- describe.todo('(prop): fab', () => {
137
- test(' ', () => {
138
- //
307
+ test('type String has effect', async () => {
308
+ const propVal = 'map'
309
+ const wrapper = mount(QBtn)
310
+
311
+ expect(
312
+ wrapper.find('.q-icon').exists()
313
+ ).toBe(false)
314
+
315
+ await wrapper.setProps({ icon: propVal })
316
+ await flushPromises()
317
+
318
+ expect(
319
+ wrapper.get('.q-icon').text()
320
+ ).toContain(propVal)
139
321
  })
140
322
  })
141
323
 
142
- describe.todo('(prop): fab-mini', () => {
143
- test(' ', () => {
144
- //
324
+ describe('[(prop)icon-right]', () => {
325
+ test('is defined correctly', () => {
326
+ expect(QBtn.props.iconRight).toBeDefined()
145
327
  })
146
- })
147
328
 
148
- describe.todo('(prop): padding', () => {
149
- test(' ', () => {
150
- //
329
+ test('type String has effect', async () => {
330
+ const propVal = 'map'
331
+ const wrapper = mount(QBtn)
332
+
333
+ expect(
334
+ wrapper.find('.q-icon').exists()
335
+ ).toBe(false)
336
+
337
+ await wrapper.setProps({ iconRight: propVal })
338
+ await flushPromises()
339
+
340
+ expect(
341
+ wrapper.get('.q-icon').text()
342
+ ).toContain(propVal)
151
343
  })
152
344
  })
153
345
 
154
- describe.todo('(prop): color', () => {
155
- test(' ', () => {
156
- //
346
+ describe('[(prop)outline]', () => {
347
+ test('is defined correctly', () => {
348
+ expect(QBtn.props.outline).toBeDefined()
157
349
  })
158
- })
159
350
 
160
- describe.todo('(prop): text-color', () => {
161
- test(' ', () => {
162
- //
351
+ test('type Boolean has effect', async () => {
352
+ const wrapper = mount(QBtn)
353
+ const target = wrapper.get('.q-btn')
354
+
355
+ expect(
356
+ target.classes()
357
+ ).not.toContain('q-btn--outline')
358
+
359
+ await wrapper.setProps({ outline: true })
360
+ await flushPromises()
361
+
362
+ expect(
363
+ target.classes()
364
+ ).toContain('q-btn--outline')
365
+
366
+ expect(
367
+ target.$computedStyle('background')
368
+ ).toBe('transparent')
163
369
  })
164
370
  })
165
371
 
166
- describe.todo('(prop): dense', () => {
167
- test(' ', () => {
168
- //
372
+ describe('[(prop)flat]', () => {
373
+ test('is defined correctly', () => {
374
+ expect(QBtn.props.flat).toBeDefined()
169
375
  })
170
- })
171
376
 
172
- describe.todo('(prop): ripple', () => {
173
- test(' ', () => {
174
- //
377
+ test('type Boolean has effect', async () => {
378
+ const wrapper = mount(QBtn)
379
+ const target = wrapper.get('.q-btn')
380
+
381
+ expect(
382
+ target.classes()
383
+ ).not.toContain('q-btn--flat')
384
+
385
+ await wrapper.setProps({ flat: true })
386
+ await flushPromises()
387
+
388
+ expect(
389
+ target.classes()
390
+ ).toContain('q-btn--flat')
175
391
  })
176
392
  })
177
393
 
178
- describe.todo('(prop): type', () => {
179
- test(' ', () => {
180
- //
394
+ describe('[(prop)unelevated]', () => {
395
+ test('is defined correctly', () => {
396
+ expect(QBtn.props.unelevated).toBeDefined()
181
397
  })
182
- })
183
398
 
184
- describe.todo('(prop): tabindex', () => {
185
- test(' ', () => {
186
- //
399
+ test('type Boolean has effect', async () => {
400
+ const wrapper = mount(QBtn)
401
+ const target = wrapper.get('.q-btn')
402
+
403
+ expect(
404
+ target.classes()
405
+ ).not.toContain('q-btn--unelevated')
406
+
407
+ await wrapper.setProps({ unelevated: true })
408
+ await flushPromises()
409
+
410
+ expect(
411
+ target.classes()
412
+ ).toContain('q-btn--unelevated')
187
413
  })
188
414
  })
189
415
 
190
- describe.todo('(prop): to', () => {
191
- test(' ', () => {
192
- //
416
+ describe('[(prop)rounded]', () => {
417
+ test('is defined correctly', () => {
418
+ expect(QBtn.props.rounded).toBeDefined()
193
419
  })
194
- })
195
420
 
196
- describe.todo('(prop): exact', () => {
197
- test(' ', () => {
198
- //
421
+ test('type Boolean has effect', async () => {
422
+ const wrapper = mount(QBtn)
423
+ const target = wrapper.get('.q-btn')
424
+
425
+ expect(
426
+ target.classes()
427
+ ).not.toContain('q-btn--rounded')
428
+
429
+ await wrapper.setProps({ rounded: true })
430
+ await flushPromises()
431
+
432
+ expect(
433
+ target.classes()
434
+ ).toContain('q-btn--rounded')
435
+
436
+ expect(
437
+ target.$computedStyle('border-radius')
438
+ ).toBe('28px')
199
439
  })
200
440
  })
201
441
 
202
- describe.todo('(prop): replace', () => {
203
- test(' ', () => {
204
- //
442
+ describe('[(prop)push]', () => {
443
+ test('is defined correctly', () => {
444
+ expect(QBtn.props.push).toBeDefined()
205
445
  })
206
- })
207
446
 
208
- describe.todo('(prop): active-class', () => {
209
- test(' ', () => {
210
- //
447
+ test('type Boolean has effect', async () => {
448
+ const wrapper = mount(QBtn)
449
+ const target = wrapper.get('.q-btn')
450
+
451
+ expect(
452
+ target.classes()
453
+ ).not.toContain('q-btn--push')
454
+
455
+ await wrapper.setProps({ push: true })
456
+ await flushPromises()
457
+
458
+ expect(
459
+ target.classes()
460
+ ).toContain('q-btn--push')
461
+
462
+ expect(
463
+ target.$computedStyle('border-radius')
464
+ ).toBe('7px')
465
+
466
+ expect(
467
+ target.$computedStyle('transition')
468
+ ).toBeDefined()
211
469
  })
212
470
  })
213
471
 
214
- describe.todo('(prop): exact-active-class', () => {
215
- test(' ', () => {
216
- //
472
+ describe('[(prop)square]', () => {
473
+ test('is defined correctly', () => {
474
+ expect(QBtn.props.square).toBeDefined()
217
475
  })
218
- })
219
476
 
220
- describe.todo('(prop): href', () => {
221
- test(' ', () => {
222
- //
477
+ test('type Boolean has effect', async () => {
478
+ const wrapper = mount(QBtn)
479
+ const target = wrapper.get('.q-btn')
480
+
481
+ expect(
482
+ target.classes()
483
+ ).not.toContain('q-btn--square')
484
+
485
+ await wrapper.setProps({ square: true })
486
+ await flushPromises()
487
+
488
+ expect(
489
+ target.classes()
490
+ ).toContain('q-btn--square')
491
+
492
+ expect(
493
+ target.$computedStyle('border-radius')
494
+ ).toBe('0')
223
495
  })
224
496
  })
225
497
 
226
- describe.todo('(prop): target', () => {
227
- test(' ', () => {
228
- //
498
+ describe('[(prop)glossy]', () => {
499
+ test('is defined correctly', () => {
500
+ expect(QBtn.props.glossy).toBeDefined()
229
501
  })
230
- })
231
502
 
232
- describe.todo('(prop): label', () => {
233
- test(' ', () => {
234
- //
503
+ test('type Boolean has effect', async () => {
504
+ const wrapper = mount(QBtn)
505
+ const target = wrapper.get('.q-btn')
506
+
507
+ expect(
508
+ target.classes()
509
+ ).not.toContain('glossy')
510
+
511
+ await wrapper.setProps({ glossy: true })
512
+ await flushPromises()
513
+
514
+ expect(
515
+ target.classes()
516
+ ).toContain('glossy')
235
517
  })
236
518
  })
237
519
 
238
- describe.todo('(prop): icon', () => {
239
- test(' ', () => {
240
- //
520
+ describe('[(prop)fab]', () => {
521
+ test('is defined correctly', () => {
522
+ expect(QBtn.props.fab).toBeDefined()
241
523
  })
242
- })
243
524
 
244
- describe.todo('(prop): icon-right', () => {
245
- test(' ', () => {
246
- //
525
+ test('type Boolean has effect', async () => {
526
+ const wrapper = mount(QBtn)
527
+ const target = wrapper.get('.q-btn')
528
+
529
+ expect(
530
+ target.classes()
531
+ ).not.toContain('q-btn--fab')
532
+
533
+ await wrapper.setProps({ fab: true })
534
+ await flushPromises()
535
+
536
+ expect(
537
+ target.classes()
538
+ ).toContain('q-btn--fab')
247
539
  })
248
540
  })
249
541
 
250
- describe.todo('(prop): no-caps', () => {
251
- test(' ', () => {
252
- //
542
+ describe('[(prop)fab-mini]', () => {
543
+ test('is defined correctly', () => {
544
+ expect(QBtn.props.fabMini).toBeDefined()
253
545
  })
254
- })
255
546
 
256
- describe.todo('(prop): no-wrap', () => {
257
- test(' ', () => {
258
- //
547
+ test('type Boolean has effect', async () => {
548
+ const wrapper = mount(QBtn)
549
+ const target = wrapper.get('.q-btn')
550
+
551
+ expect(
552
+ target.classes()
553
+ ).not.toContain('q-btn--fab-mini')
554
+
555
+ await wrapper.setProps({ fabMini: true })
556
+ await flushPromises()
557
+
558
+ expect(
559
+ target.classes()
560
+ ).toContain('q-btn--fab-mini')
259
561
  })
260
562
  })
261
563
 
262
- describe.todo('(prop): align', () => {
263
- test(' ', () => {
264
- //
564
+ describe('[(prop)padding]', () => {
565
+ test('is defined correctly', () => {
566
+ expect(QBtn.props.padding).toBeDefined()
265
567
  })
266
- })
267
568
 
268
- describe.todo('(prop): stack', () => {
269
- test(' ', () => {
270
- //
569
+ test.each([
570
+ [ 'pixels; single value', '50px' ],
571
+ [ 'pixels; multiple values', '50px 100px' ]
572
+ ])('type String has effect (%s)', async (_, propVal) => {
573
+ const wrapper = mount(QBtn)
574
+ const target = wrapper.get('.q-btn')
575
+
576
+ expect(
577
+ target.$style('padding')
578
+ ).not.toBe(propVal)
579
+
580
+ await wrapper.setProps({ padding: propVal })
581
+ await flushPromises()
582
+
583
+ expect(
584
+ target.$style('padding')
585
+ ).toBe(propVal)
271
586
  })
272
- })
273
587
 
274
- describe.todo('(prop): stretch', () => {
275
- test(' ', () => {
276
- //
588
+ test('type String has effect (as "xs")', async () => {
589
+ const wrapper = mount(QBtn)
590
+ const target = wrapper.get('.q-btn')
591
+
592
+ expect(
593
+ target.$style('padding')
594
+ ).not.toBe(`${ btnPadding.xs }px`)
595
+
596
+ await wrapper.setProps({ padding: 'xs' })
597
+ await flushPromises()
598
+
599
+ expect(
600
+ target.$style('padding')
601
+ ).toBe(`${ btnPadding.xs }px`)
277
602
  })
278
- })
279
- })
280
603
 
281
- describe('[Slots]', () => {
282
- describe('[(slot)default]', () => {
283
- test('should render a button with a label', () => {
284
- const wrapper = mountQBtn()
604
+ test('type String has effect (as "xs xl")', async () => {
605
+ const wrapper = mount(QBtn)
606
+ const target = wrapper.get('.q-btn')
285
607
 
286
608
  expect(
287
- wrapper.get('.q-btn')
288
- .text()
289
- ).toContain(defaultOptions.label)
609
+ target.$style('padding')
610
+ ).not.toBe(`${ btnPadding.xs }px ${ btnPadding.xl }px`)
611
+
612
+ await wrapper.setProps({ padding: 'xs xl' })
613
+ await flushPromises()
614
+
615
+ expect(
616
+ target.$style('padding')
617
+ ).toBe(`${ btnPadding.xs }px ${ btnPadding.xl }px`)
290
618
  })
291
- })
292
619
 
293
- describe('[(slot)loading]', () => {
294
- test('should render a button with a loading slot', () => {
295
- const loadingSlot = 'loading slot'
296
- const wrapper = mountQBtn({
297
- props: {
298
- loading: true
299
- },
300
- slots: {
301
- loading: loadingSlot
302
- }
303
- })
620
+ test('padding "0" is applied correctly', async () => {
621
+ const wrapper = mount(QBtn)
622
+ const target = wrapper.get('.q-btn')
304
623
 
305
- const text = wrapper.get('.q-btn').text()
306
- expect(text).toContain(loadingSlot)
307
- expect(text).toContain(defaultOptions.label)
624
+ expect(
625
+ target.$style('min-width')
626
+ ).not.toBe('0')
308
627
 
309
628
  expect(
310
- wrapper.get('.q-btn__content')
311
- .isVisible()
312
- ).not.toBe(true)
629
+ target.$style('min-height')
630
+ ).not.toBe('0')
631
+
632
+ await wrapper.setProps({ padding: 'xs xl' })
633
+ await flushPromises()
634
+
635
+ expect(
636
+ target.$style('min-width')
637
+ ).toBe('0')
638
+
639
+ expect(
640
+ target.$style('min-height')
641
+ ).toBe('0')
313
642
  })
314
643
  })
315
- })
316
644
 
317
- describe('[Events]', () => {
318
- describe('[(event)click]', () => {
319
- test('should emit a click event when the button is clicked', () => {
320
- const fn = vi.fn()
321
- const wrapper = mountQBtn({
322
- props: {
323
- onClick: fn
324
- }
645
+ describe('[(prop)color]', () => {
646
+ test('is defined correctly', () => {
647
+ expect(QBtn.props.color).toBeDefined()
648
+ })
649
+
650
+ test('(default design) is applied correctly', async () => {
651
+ const propVal = 'red'
652
+ const wrapper = mount(QBtn)
653
+ const target = wrapper.get('.q-btn')
654
+
655
+ let cls = target.classes()
656
+ expect(cls).not.toContain('bg-red')
657
+ expect(cls).not.toContain('text-white')
658
+
659
+ await wrapper.setProps({ color: propVal })
660
+ await flushPromises()
661
+
662
+ cls = target.classes()
663
+ expect(cls).toContain('bg-red')
664
+ expect(cls).toContain('text-white')
665
+ })
666
+
667
+ test.each([
668
+ [ 'push' ],
669
+ [ 'unelevated' ]
670
+ ])('(design "%s") is applied correctly', async designProp => {
671
+ const wrapper = mount(QBtn)
672
+ const target = wrapper.get('.q-btn')
673
+
674
+ let cls = target.classes()
675
+ expect(cls).not.toContain('bg-red')
676
+ expect(cls).not.toContain('text-white')
677
+
678
+ await wrapper.setProps({
679
+ color: 'red',
680
+ [ designProp ]: true
325
681
  })
682
+ await flushPromises()
683
+
684
+ cls = target.classes()
685
+ expect(cls).toContain('bg-red')
686
+ expect(cls).toContain('text-white')
687
+ })
688
+
689
+ test.each([
690
+ [ 'flat' ],
691
+ [ 'outline' ]
692
+ ])('(design "%s") is applied correctly', async designProp => {
693
+ const wrapper = mount(QBtn)
694
+ const target = wrapper.get('.q-btn')
326
695
 
327
- wrapper.get('.q-btn').trigger('click')
696
+ let cls = target.classes()
697
+ expect(cls).not.toContain('text-red')
698
+ expect(cls).not.toContain('bg-red')
699
+
700
+ await wrapper.setProps({
701
+ color: 'red',
702
+ [ designProp ]: true
703
+ })
704
+ await flushPromises()
328
705
 
329
- expect(fn).toHaveBeenCalledTimes(1)
706
+ cls = target.classes()
707
+ expect(cls).toContain('text-red')
708
+ expect(cls).not.toContain('bg-red')
330
709
  })
331
710
  })
332
- })
333
711
 
334
- describe('[Methods]', () => {
335
- describe('[(method)click]', () => {
336
- test('should click the button', () => {
337
- const fn = vi.fn()
338
- const wrapper = mountQBtn({
339
- props: {
340
- onClick: fn
341
- }
712
+ describe('[(prop)text-color]', () => {
713
+ test('is defined correctly', () => {
714
+ expect(QBtn.props.textColor).toBeDefined()
715
+ })
716
+
717
+ test('is applied correctly with no "color" prop', async () => {
718
+ const wrapper = mount(QBtn)
719
+ const target = wrapper.get('.q-btn')
720
+
721
+ let cls = target.classes()
722
+ expect(cls).not.toContain('text-red')
723
+ expect(cls).not.toContain('bg-red')
724
+
725
+ await wrapper.setProps({ textColor: 'red' })
726
+ await flushPromises()
727
+
728
+ cls = target.classes()
729
+ expect(cls).toContain('text-red')
730
+ expect(cls).not.toContain('bg-red')
731
+ })
732
+
733
+ test('(default design + color) is applied correctly', async () => {
734
+ const wrapper = mount(QBtn)
735
+ const target = wrapper.get('.q-btn')
736
+
737
+ let cls = target.classes()
738
+
739
+ expect(cls).not.toContain('bg-red')
740
+ expect(cls).not.toContain('text-red')
741
+ expect(cls).not.toContain('bg-blue')
742
+ expect(cls).not.toContain('text-blue')
743
+
744
+ await wrapper.setProps({
745
+ color: 'red',
746
+ textColor: 'blue'
342
747
  })
748
+ await flushPromises()
749
+
750
+ cls = target.classes()
751
+
752
+ expect(cls).toContain('bg-red')
753
+ expect(cls).toContain('text-blue')
754
+
755
+ expect(cls).not.toContain('text-red')
756
+ expect(cls).not.toContain('bg-blue')
757
+ })
758
+
759
+ test.each([
760
+ [ 'push' ],
761
+ [ 'unelevated' ]
762
+ ])('(design "%s" + color) is applied correctly', async designProp => {
763
+ const wrapper = mount(QBtn)
764
+ const target = wrapper.get('.q-btn')
343
765
 
344
- wrapper.trigger('click')
766
+ let cls = target.classes()
767
+
768
+ expect(cls).not.toContain('bg-red')
769
+ expect(cls).not.toContain('text-red')
770
+ expect(cls).not.toContain('bg-blue')
771
+ expect(cls).not.toContain('text-blue')
772
+
773
+ await wrapper.setProps({
774
+ color: 'red',
775
+ textColor: 'blue',
776
+ [ designProp ]: true
777
+ })
778
+ await flushPromises()
779
+
780
+ cls = target.classes()
781
+
782
+ expect(cls).toContain('bg-red')
783
+ expect(cls).toContain('text-blue')
784
+
785
+ expect(cls).not.toContain('text-red')
786
+ expect(cls).not.toContain('bg-blue')
787
+ })
788
+
789
+ test.each([
790
+ [ 'flat' ],
791
+ [ 'outline' ]
792
+ ])('(design "%s" + color) is applied correctly', async designProp => {
793
+ const wrapper = mount(QBtn)
794
+ const target = wrapper.get('.q-btn')
795
+
796
+ let cls = target.classes()
797
+
798
+ expect(cls).not.toContain('text-blue')
799
+ expect(cls).not.toContain('text-red')
800
+ expect(cls).not.toContain('bg-red')
801
+ expect(cls).not.toContain('bg-blue')
802
+
803
+ await wrapper.setProps({
804
+ color: 'red',
805
+ textColor: 'blue',
806
+ [ designProp ]: true
807
+ })
808
+ await flushPromises()
809
+
810
+ cls = target.classes()
811
+
812
+ expect(cls).toContain('text-blue')
813
+
814
+ expect(cls).not.toContain('text-red')
815
+ expect(cls).not.toContain('bg-red')
816
+ expect(cls).not.toContain('bg-blue')
817
+ })
818
+ })
819
+
820
+ describe('[(prop)no-caps]', () => {
821
+ test('is defined correctly', () => {
822
+ expect(QBtn.props.noCaps).toBeDefined()
823
+ })
824
+
825
+ test('type Boolean has effect', async () => {
826
+ const wrapper = mount(QBtn)
827
+ const target = wrapper.get('.q-btn')
828
+
829
+ expect(
830
+ target.classes()
831
+ ).not.toContain('q-btn--no-uppercase')
832
+
833
+ await wrapper.setProps({ noCaps: true })
834
+ await flushPromises()
835
+
836
+ expect(
837
+ target.classes()
838
+ ).toContain('q-btn--no-uppercase')
839
+
840
+ expect(
841
+ target.$computedStyle('text-transform')
842
+ ).toBe('none')
843
+ })
844
+ })
845
+
846
+ describe('[(prop)no-wrap]', () => {
847
+ test('is defined correctly', () => {
848
+ expect(QBtn.props.noWrap).toBeDefined()
849
+ })
850
+
851
+ test('type Boolean has effect', async () => {
852
+ const wrapper = mount(QBtn)
853
+
854
+ let cls = wrapper.get('.q-btn__content').classes()
855
+ expect(cls).not.toContain('no-wrap')
856
+ expect(cls).not.toContain('text-no-wrap')
857
+
858
+ await wrapper.setProps({ noWrap: true })
859
+ await flushPromises()
860
+
861
+ cls = wrapper.get('.q-btn__content').classes()
862
+ expect(cls).toContain('no-wrap')
863
+ expect(cls).toContain('text-no-wrap')
864
+ })
865
+ })
866
+
867
+ describe('[(prop)dense]', () => {
868
+ test('is defined correctly', () => {
869
+ expect(QBtn.props.dense).toBeDefined()
870
+ })
871
+
872
+ test('type Boolean has effect', async () => {
873
+ const wrapper = mount(QBtn)
874
+ const target = wrapper.get('.q-btn')
875
+
876
+ expect(
877
+ target.classes()
878
+ ).not.toContain('q-btn--dense')
879
+
880
+ await wrapper.setProps({ dense: true })
881
+ await flushPromises()
882
+
883
+ expect(
884
+ target.classes()
885
+ ).toContain('q-btn--dense')
886
+ })
887
+ })
888
+
889
+ describe('[(prop)ripple]', () => {
890
+ test('is defined correctly', () => {
891
+ expect(QBtn.props.ripple).toBeDefined()
892
+ })
893
+
894
+ test('type Boolean has effect', async () => {
895
+ const wrapper = mount(QBtn)
896
+
897
+ expect(
898
+ wrapper.find('.q-ripple')
899
+ .exists()
900
+ ).toBe(false)
901
+
902
+ await wrapper.setProps({ ripple: true })
903
+ await flushPromises()
904
+
905
+ await wrapper.trigger('click')
906
+
907
+ expect(
908
+ wrapper.find('.q-ripple')
909
+ .exists()
910
+ ).toBe(true)
911
+ })
912
+
913
+ test('type Object has effect', async () => {
914
+ const propVal = { center: true, color: 'teal', keyCodes: [] }
915
+ const wrapper = mount(QBtn)
916
+
917
+ expect(
918
+ wrapper.find('.q-ripple')
919
+ .exists()
920
+ ).toBe(false)
921
+
922
+ await wrapper.setProps({ ripple: propVal })
923
+ await flushPromises()
924
+
925
+ await wrapper.trigger('click')
926
+
927
+ expect(
928
+ wrapper.find('.q-ripple')
929
+ .exists()
930
+ ).toBe(true)
931
+ })
932
+ })
933
+
934
+ describe('[(prop)tabindex]', () => {
935
+ test('is defined correctly', () => {
936
+ expect(QBtn.props.tabindex).toBeDefined()
937
+ })
938
+
939
+ test.each([
940
+ [ 'Number', 100 ],
941
+ [ 'String', '100' ]
942
+ ])('type %s has effect', async (_, propVal) => {
943
+ const wrapper = mount(QBtn)
944
+
945
+ expect(
946
+ wrapper.attributes('tabindex')
947
+ ).not.toBe('' + propVal)
948
+
949
+ await wrapper.setProps({ tabindex: propVal })
950
+ await flushPromises()
951
+
952
+ expect(
953
+ wrapper.attributes('tabindex')
954
+ ).toBe('' + propVal)
955
+
956
+ // we'll test tabindex + disable
957
+ await wrapper.setProps({ disable: true })
958
+ await flushPromises()
959
+
960
+ expect(
961
+ wrapper.attributes('tabindex')
962
+ ).toBe('-1')
963
+
964
+ // we'll now test loading + disable
965
+ await wrapper.setProps({
966
+ disable: false,
967
+ loading: true
968
+ })
969
+ await flushPromises()
970
+
971
+ expect(
972
+ wrapper.attributes('tabindex')
973
+ ).toBe('-1')
974
+ })
975
+ })
976
+
977
+ describe('[(prop)align]', () => {
978
+ test('is defined correctly', () => {
979
+ expect(QBtn.props.align).toBeDefined()
980
+ })
981
+
982
+ test.each([
983
+ [ 'left' ],
984
+ [ 'center' ],
985
+ [ 'right' ],
986
+ [ 'between' ],
987
+ [ 'around' ],
988
+ [ 'evenly' ]
989
+ ])('value "%s" has effect', async propVal => {
990
+ const wrapper = mount(QBtn)
991
+ const target = wrapper.get('.q-btn__content')
992
+
993
+ if (propVal !== 'center') {
994
+ // the default value
995
+ expect(
996
+ target.classes()
997
+ ).not.toContain(`justify-${ alignMap[ propVal ] }`)
998
+ }
999
+
1000
+ await wrapper.setProps({ align: propVal })
1001
+ await flushPromises()
1002
+
1003
+ expect(
1004
+ target.classes()
1005
+ ).toContain(`justify-${ alignMap[ propVal ] }`)
1006
+ })
1007
+ })
1008
+
1009
+ describe('[(prop)stack]', () => {
1010
+ test('is defined correctly', () => {
1011
+ expect(QBtn.props.stack).toBeDefined()
1012
+ })
1013
+
1014
+ test('type Boolean has effect', async () => {
1015
+ const wrapper = mount(QBtn)
1016
+ const target = wrapper.get('.q-btn__content')
1017
+
1018
+ expect(
1019
+ target.classes()
1020
+ ).toContain('row')
1021
+
1022
+ await wrapper.setProps({ stack: true })
1023
+ await flushPromises()
1024
+
1025
+ expect(
1026
+ target.classes()
1027
+ ).toContain('column')
1028
+ })
1029
+ })
1030
+
1031
+ describe('[(prop)stretch]', () => {
1032
+ test('is defined correctly', () => {
1033
+ expect(QBtn.props.stretch).toBeDefined()
1034
+ })
1035
+
1036
+ test('type Boolean has effect', async () => {
1037
+ const wrapper = mount(QBtn)
1038
+ const target = wrapper.get('.q-btn')
1039
+
1040
+ expect(
1041
+ target.classes()
1042
+ ).not.toContain('self-stretch')
1043
+
1044
+ await wrapper.setProps({ stretch: true })
1045
+ await flushPromises()
1046
+
1047
+ expect(
1048
+ target.classes()
1049
+ ).toContain('self-stretch')
1050
+ })
1051
+ })
1052
+
1053
+ describe('[(prop)loading]', () => {
1054
+ test('is defined correctly', () => {
1055
+ expect(QBtn.props.loading).toBeDefined()
1056
+ })
1057
+
1058
+ test('type Boolean has effect', async () => {
1059
+ const wrapper = mount(QBtn)
1060
+ const target = wrapper.get('.q-btn')
1061
+
1062
+ expect(
1063
+ target.attributes('role')
1064
+ ).not.toBe('progressbar')
1065
+
1066
+ expect(
1067
+ target.attributes('aria-valuenow')
1068
+ ).toBeUndefined()
1069
+
1070
+ await wrapper.setProps({ loading: true })
1071
+ await flushPromises()
1072
+
1073
+ expect(
1074
+ target.attributes('role')
1075
+ ).not.toBe('progressbar')
1076
+
1077
+ expect(
1078
+ target.attributes('aria-valuenow')
1079
+ ).toBeUndefined()
1080
+
1081
+ expect(
1082
+ wrapper.find('.q-spinner')
1083
+ .exists()
1084
+ ).toBe(true)
1085
+
1086
+ expect(
1087
+ wrapper.get('.q-btn__content')
1088
+ .classes()
1089
+ ).toContain('q-btn__content--hidden')
1090
+
1091
+ await wrapper.setProps({ percentage: 50 })
1092
+ await flushPromises()
1093
+
1094
+ expect(
1095
+ target.attributes('role')
1096
+ ).toBe('progressbar')
1097
+
1098
+ expect(
1099
+ target.attributes('aria-valuenow')
1100
+ ).toBe('50')
1101
+ })
1102
+
1103
+ test('type null has effect', async () => {
1104
+ const wrapper = mount(QBtn)
1105
+ const target = wrapper.get('.q-btn')
1106
+
1107
+ expect(
1108
+ target.attributes('role')
1109
+ ).not.toBe('progressbar')
1110
+
1111
+ expect(
1112
+ target.attributes('aria-valuenow')
1113
+ ).toBeUndefined()
1114
+
1115
+ await wrapper.setProps({ loading: null })
1116
+ await flushPromises()
1117
+
1118
+ expect(
1119
+ target.attributes('role')
1120
+ ).not.toBe('progressbar')
1121
+
1122
+ expect(
1123
+ target.attributes('aria-valuenow')
1124
+ ).toBeUndefined()
1125
+
1126
+ expect(
1127
+ wrapper.get('.q-btn__content')
1128
+ .classes()
1129
+ ).not.toContain('q-btn__content--hidden')
1130
+
1131
+ expect(
1132
+ wrapper.find('.q-spinner')
1133
+ .exists()
1134
+ ).toBe(false)
1135
+ })
1136
+ })
1137
+
1138
+ describe('[(prop)disable]', () => {
1139
+ test('is defined correctly', () => {
1140
+ expect(QBtn.props.disable).toBeDefined()
1141
+ })
1142
+
1143
+ test('type Boolean has effect', async () => {
1144
+ const wrapper = mount(QBtn)
1145
+ const target = wrapper.get('.q-btn')
1146
+
1147
+ expect(
1148
+ target.classes()
1149
+ ).not.toContain('disabled')
1150
+
1151
+ expect(
1152
+ target.attributes('aria-disabled')
1153
+ ).not.toBe('true')
1154
+
1155
+ await wrapper.setProps({ disable: true })
1156
+ await flushPromises()
1157
+
1158
+ expect(
1159
+ target.classes()
1160
+ ).toContain('disabled')
1161
+
1162
+ expect(
1163
+ target.attributes('aria-disabled')
1164
+ ).toBe('true')
1165
+ })
1166
+
1167
+ test('link + disable', async () => {
1168
+ const testRoute = '/home'
1169
+ const router = await getRouter(testRoute)
1170
+
1171
+ const wrapper = mount(QBtn, {
1172
+ props: {
1173
+ disable: true,
1174
+ to: testRoute
1175
+ },
1176
+ global: {
1177
+ plugins: [ router ]
1178
+ }
1179
+ })
1180
+
1181
+ expect(
1182
+ wrapper.find('a').exists()
1183
+ ).toBe(false)
1184
+
1185
+ await wrapper.trigger('click')
1186
+ await flushPromises()
1187
+
1188
+ expect(
1189
+ router.currentRoute.value.path
1190
+ ).not.toBe(testRoute)
1191
+ })
1192
+
1193
+ test('loading + disable', async () => {
1194
+ const testRoute = '/home'
1195
+ const router = await getRouter(testRoute)
1196
+
1197
+ const wrapper = mount(QBtn, {
1198
+ props: {
1199
+ loading: true,
1200
+ to: testRoute
1201
+ },
1202
+ global: {
1203
+ plugins: [ router ]
1204
+ }
1205
+ })
1206
+
1207
+ await wrapper.trigger('click')
1208
+ await flushPromises()
1209
+
1210
+ expect(
1211
+ router.currentRoute.value.path
1212
+ ).not.toBe(testRoute)
1213
+ })
1214
+ })
1215
+
1216
+ describe('[(prop)round]', () => {
1217
+ test('is defined correctly', () => {
1218
+ expect(QBtn.props.round).toBeDefined()
1219
+ })
1220
+
1221
+ test('type Boolean has effect', async () => {
1222
+ const wrapper = mount(QBtn)
1223
+ const target = wrapper.get('.q-btn')
1224
+
1225
+ expect(
1226
+ target.classes()
1227
+ ).toContain('q-btn--rectangle')
1228
+
1229
+ await wrapper.setProps({ round: true })
1230
+ await flushPromises()
1231
+
1232
+ expect(
1233
+ target.classes()
1234
+ ).toContain('q-btn--round')
1235
+
1236
+ expect(
1237
+ target.$computedStyle('border-radius')
1238
+ ).toBe('50%')
1239
+ })
1240
+ })
1241
+
1242
+ describe('[(prop)percentage]', () => {
1243
+ test('is defined correctly', () => {
1244
+ expect(QBtn.props.percentage).toBeDefined()
1245
+ })
1246
+
1247
+ test('type Number has effect', async () => {
1248
+ const propVal = 58
1249
+ const wrapper = mount(QBtn)
1250
+
1251
+ expect(
1252
+ wrapper.find('.q-btn__progress')
1253
+ .exists()
1254
+ ).toBe(false)
1255
+
1256
+ expect(
1257
+ wrapper.get('.q-btn')
1258
+ .attributes('aria-valuenow')
1259
+ ).toBeUndefined()
1260
+
1261
+ await wrapper.setProps({ percentage: propVal })
1262
+ await flushPromises()
1263
+
1264
+ expect(
1265
+ wrapper.find('.q-btn__progress')
1266
+ .exists()
1267
+ ).toBe(false)
1268
+
1269
+ expect(
1270
+ wrapper.get('.q-btn')
1271
+ .attributes('aria-valuenow')
1272
+ ).toBeUndefined()
1273
+
1274
+ await wrapper.setProps({ loading: true })
1275
+ await flushPromises()
1276
+
1277
+ expect(
1278
+ wrapper.find('.q-btn__progress')
1279
+ .exists()
1280
+ ).toBe(true)
1281
+
1282
+ expect(
1283
+ wrapper.get('.q-btn__progress-indicator')
1284
+ .$computedStyle('transform')
1285
+ ).toContain(`${ 100 - propVal }%`)
1286
+
1287
+ expect(
1288
+ wrapper.find('.q-spinner')
1289
+ .exists()
1290
+ ).toBe(true)
1291
+
1292
+ expect(
1293
+ wrapper.get('.q-btn')
1294
+ .attributes('aria-valuenow')
1295
+ ).toBe('' + propVal)
1296
+ })
1297
+ })
1298
+
1299
+ describe('[(prop)dark-percentage]', () => {
1300
+ test('is defined correctly', () => {
1301
+ expect(QBtn.props.darkPercentage).toBeDefined()
1302
+ })
1303
+
1304
+ test('type Boolean has effect', async () => {
1305
+ const propVal = 58
1306
+ const wrapper = mount(QBtn)
1307
+
1308
+ expect(
1309
+ wrapper.get('.q-btn')
1310
+ .attributes('aria-valuenow')
1311
+ ).not.toBe('' + propVal)
1312
+
1313
+ expect(
1314
+ wrapper.find('.q-btn__progress')
1315
+ .exists()
1316
+ ).toBe(false)
1317
+
1318
+ await wrapper.setProps({
1319
+ percentage: propVal,
1320
+ loading: true,
1321
+ darkPercentage: true
1322
+ })
1323
+ await flushPromises()
1324
+
1325
+ expect(
1326
+ wrapper.get('.q-btn')
1327
+ .attributes('aria-valuenow')
1328
+ ).toBe('' + propVal)
1329
+
1330
+ expect(
1331
+ wrapper.get('.q-btn__progress')
1332
+ .classes()
1333
+ ).toContain('q-btn__progress--dark')
1334
+ })
1335
+ })
1336
+ })
1337
+
1338
+ describe('[Slots]', () => {
1339
+ describe('[(slot)default]', () => {
1340
+ test('renders the content', () => {
1341
+ const slotContent = 'some-slot-content'
1342
+ const wrapper = mount(QBtn, {
1343
+ slots: {
1344
+ default: () => slotContent
1345
+ }
1346
+ })
1347
+
1348
+ expect(wrapper.html()).toContain(slotContent)
1349
+ })
1350
+ })
1351
+
1352
+ describe('[(slot)loading]', () => {
1353
+ test('renders the content', async () => {
1354
+ const slotContent = 'some-slot-content'
1355
+ const wrapper = mount(QBtn, {
1356
+ slots: {
1357
+ loading: () => slotContent
1358
+ }
1359
+ })
1360
+
1361
+ expect(wrapper.html()).not.toContain(slotContent)
1362
+
1363
+ await wrapper.setProps({ loading: true })
1364
+ await flushPromises()
1365
+
1366
+ expect(wrapper.html()).toContain(slotContent)
1367
+ })
1368
+ })
1369
+ })
1370
+
1371
+ describe('[Events]', () => {
1372
+ describe('[(event)click]', () => {
1373
+ test('is defined correctly', () => {
1374
+ expect(
1375
+ QBtn.emits?.includes('click')
1376
+ ^ (QBtn.props?.onClick !== void 0)
1377
+ ).toBe(1)
1378
+ })
1379
+
1380
+ test('(with route) is emitting', async () => {
1381
+ const testRoute = '/home/dashboard'
1382
+ const router = await getRouter(testRoute)
1383
+
1384
+ const wrapper = mount(QBtn, {
1385
+ props: {
1386
+ to: testRoute
1387
+ },
1388
+ global: {
1389
+ plugins: [ router ]
1390
+ }
1391
+ })
1392
+
1393
+ await wrapper.trigger('click')
1394
+
1395
+ const eventList = wrapper.emitted()
1396
+ expect(eventList).toHaveProperty('click')
1397
+ expect(eventList.click).toHaveLength(1)
1398
+
1399
+ const [ evt, go ] = eventList.click[ 0 ]
1400
+ expect(evt).toBeInstanceOf(Event)
1401
+ expect(go).toBeTypeOf('function')
1402
+ })
1403
+
1404
+ test('(with route) does not navigates when prevented', async () => {
1405
+ const testRoute = '/home/dashboard'
1406
+ const router = await getRouter(testRoute)
1407
+
1408
+ const wrapper = mount(QBtn, {
1409
+ props: {
1410
+ to: testRoute,
1411
+ onClick: e => e.preventDefault()
1412
+ },
1413
+ global: {
1414
+ plugins: [ router ]
1415
+ }
1416
+ })
1417
+
1418
+ await wrapper.trigger('click')
1419
+ await flushPromises()
1420
+
1421
+ expect(
1422
+ router.currentRoute.value.path
1423
+ ).not.toBe(testRoute)
1424
+ })
1425
+
1426
+ test('(with route) can manually navigate by calling go()', async () => {
1427
+ const testRoute = '/home/dashboard'
1428
+ const router = await getRouter(testRoute)
1429
+
1430
+ const wrapper = mount(QBtn, {
1431
+ props: {
1432
+ to: testRoute,
1433
+ onClick: (e, go) => {
1434
+ e.preventDefault()
1435
+ go()
1436
+ }
1437
+ },
1438
+ global: {
1439
+ plugins: [ router ]
1440
+ }
1441
+ })
1442
+
1443
+ await wrapper.trigger('click')
1444
+ await flushPromises()
1445
+
1446
+ expect(
1447
+ router.currentRoute.value.path
1448
+ ).toBe(testRoute)
1449
+ })
1450
+
1451
+ test('is emitting', async () => {
1452
+ const wrapper = mount(QBtn)
1453
+
1454
+ await wrapper.trigger('click')
1455
+
1456
+ const eventList = wrapper.emitted()
1457
+ expect(eventList).toHaveProperty('click')
1458
+ expect(eventList.click).toHaveLength(1)
1459
+
1460
+ const [ evt, go ] = eventList.click[ 0 ]
1461
+ expect(evt).toBeInstanceOf(Event)
1462
+ expect(go).toBeUndefined()
1463
+ })
1464
+
1465
+ test('is NOT emitting when in loading state', async () => {
1466
+ const wrapper = mount(QBtn, {
1467
+ props: {
1468
+ loading: true
1469
+ }
1470
+ })
1471
+
1472
+ await wrapper.trigger('click')
1473
+
1474
+ const eventList = wrapper.emitted()
1475
+ expect(eventList).not.toHaveProperty('click')
1476
+ })
1477
+
1478
+ test('is NOT emitting when disabled', async () => {
1479
+ const wrapper = mount(QBtn, {
1480
+ props: {
1481
+ disable: true
1482
+ }
1483
+ })
1484
+
1485
+ await wrapper.trigger('click')
1486
+
1487
+ const eventList = wrapper.emitted()
1488
+ expect(eventList).not.toHaveProperty('click')
1489
+ })
1490
+ })
1491
+ })
1492
+
1493
+ describe('[Methods]', () => {
1494
+ describe('[(method)click]', () => {
1495
+ test('should be callable', () => {
1496
+ const event = new MouseEvent('click')
1497
+ const wrapper = mount(QBtn)
1498
+
1499
+ expect(
1500
+ wrapper.vm.click(event)
1501
+ ).toBeUndefined()
1502
+
1503
+ const eventList = wrapper.emitted()
1504
+ expect(eventList).toHaveProperty('click')
1505
+ expect(eventList.click).toHaveLength(1)
1506
+
1507
+ const [ evt, go ] = eventList.click[ 0 ]
1508
+ expect(evt).toBeInstanceOf(Event)
1509
+ expect(go).toBeUndefined()
1510
+ })
1511
+
1512
+ test('should not do anything when disabled', () => {
1513
+ const event = new MouseEvent('click')
1514
+ const wrapper = mount(QBtn, {
1515
+ props: {
1516
+ disable: true
1517
+ }
1518
+ })
1519
+
1520
+ expect(
1521
+ wrapper.vm.click(event)
1522
+ ).toBeUndefined()
345
1523
 
346
- expect(fn).toHaveBeenCalledTimes(1)
1524
+ const eventList = wrapper.emitted()
1525
+ expect(eventList).not.toHaveProperty('click')
347
1526
  })
348
1527
  })
349
1528
  })