vitest.setup.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. import '@testing-library/jest-dom'
  3. import { configure } from '@testing-library/vue'
  4. import * as matchers from 'vitest-axe/matchers'
  5. import { expect } from 'vitest'
  6. import 'vitest-axe/extend-expect'
  7. import { ServiceWorkerHelper } from '@shared/utils/testSw'
  8. global.__ = (source) => {
  9. return source
  10. }
  11. window.sw = new ServiceWorkerHelper()
  12. configure({
  13. testIdAttribute: 'data-test-id',
  14. asyncUtilTimeout: 5000,
  15. })
  16. class DOMRectList {
  17. length = 0
  18. // eslint-disable-next-line class-methods-use-this
  19. item = () => null;
  20. // eslint-disable-next-line class-methods-use-this
  21. [Symbol.iterator] = () => {
  22. //
  23. }
  24. }
  25. Object.defineProperty(Node.prototype, 'getClientRects', {
  26. value: new DOMRectList(),
  27. })
  28. Object.defineProperty(Element.prototype, 'scroll', { value: vi.fn() })
  29. Object.defineProperty(Element.prototype, 'scrollBy', { value: vi.fn() })
  30. Object.defineProperty(Element.prototype, 'scrollIntoView', { value: vi.fn() })
  31. require.extensions['.css'] = () => ({})
  32. vi.stubGlobal('requestAnimationFrame', (cb: () => void) => {
  33. setTimeout(cb, 0)
  34. })
  35. vi.stubGlobal('scrollTo', vi.fn())
  36. vi.stubGlobal('matchMedia', (media: string) => ({
  37. matches: false,
  38. media,
  39. onchange: null,
  40. addEventListener: vi.fn(),
  41. removeEventListener: vi.fn(),
  42. }))
  43. vi.mock('@shared/components/CommonNotifications/composable', async () => {
  44. const { default: originalUseNotifications } = await vi.importActual<any>(
  45. '@shared/components/CommonNotifications/composable',
  46. )
  47. let notifications: any
  48. const useNotifications = () => {
  49. if (notifications) return notifications
  50. const result = originalUseNotifications()
  51. notifications = {
  52. notify: vi.fn(result.notify),
  53. notifications: result.notifications,
  54. removeNotification: vi.fn(result.removeNotification),
  55. clearAllNotifications: vi.fn(result.clearAllNotifications),
  56. hasErrors: vi.fn(result.hasErrors),
  57. }
  58. return notifications
  59. }
  60. return {
  61. default: useNotifications,
  62. }
  63. })
  64. // don't rely on tiptap, because it's not supported in JSDOM
  65. vi.mock(
  66. '@shared/components/Form/fields/FieldEditor/FieldEditorInput.vue',
  67. async () => {
  68. const { computed, defineComponent } = await import('vue')
  69. const component = defineComponent({
  70. name: 'FieldEditorInput',
  71. props: { context: { type: Object, required: true } },
  72. setup(props) {
  73. const value = computed({
  74. get: () => props.context._value,
  75. set: (value) => {
  76. props.context.node.input(value)
  77. },
  78. })
  79. return { value, name: props.context.name }
  80. },
  81. template: `<textarea :name="name" v-model="value" />`,
  82. })
  83. return { __esModule: true, default: component }
  84. },
  85. )
  86. // mock vueuse because of CommonDialog, it uses usePointerSwipe
  87. // that is not supported in JSDOM
  88. vi.mock('@vueuse/core', async () => {
  89. const mod = await vi.importActual<typeof import('@vueuse/core')>(
  90. '@vueuse/core',
  91. )
  92. return {
  93. ...mod,
  94. usePointerSwipe: vi
  95. .fn()
  96. .mockReturnValue({ distanceY: 0, isSwiping: false }),
  97. }
  98. })
  99. beforeEach((context) => {
  100. context.skipConsole = false
  101. if (!vi.isMockFunction(console.warn)) {
  102. vi.spyOn(console, 'warn').mockClear()
  103. } else {
  104. vi.mocked(console.warn).mockClear()
  105. }
  106. if (!vi.isMockFunction(console.error)) {
  107. vi.spyOn(console, 'error').mockClear()
  108. } else {
  109. vi.mocked(console.error).mockClear()
  110. }
  111. })
  112. afterEach((context) => {
  113. // we don't import it from `renderComponent`, because it may renderComponent may not be called
  114. // and it doesn't make sense to import everything from it
  115. if ('cleanupComponents' in globalThis) {
  116. globalThis.cleanupComponents()
  117. }
  118. if (context.skipConsole !== true) {
  119. expect(
  120. console.warn,
  121. 'there were no warning during test',
  122. ).not.toHaveBeenCalled()
  123. expect(
  124. console.error,
  125. 'there were no errors during test',
  126. ).not.toHaveBeenCalled()
  127. }
  128. })
  129. // Import the matchers for accessibility testing with aXe.
  130. expect.extend(matchers)
  131. declare module 'vitest' {
  132. interface TestContext {
  133. skipConsole: boolean
  134. }
  135. }
  136. declare global {
  137. function cleanupComponents(): void
  138. }