vitest.setup.ts 4.3 KB

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