e2eUtils.ts 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { type Locator, page, userEvent } from 'vitest/browser'
  2. export const css = (css: string) => page.getByCSS(css)
  3. export const html = (selector: string) => css(selector).element().innerHTML
  4. export const E2E_TIMEOUT: number = 10 * 1000
  5. const duration = 50
  6. export function timeout(time: number) {
  7. return new Promise(r => {
  8. setTimeout(r, time)
  9. })
  10. }
  11. export const transitionFinish = (time = duration) => timeout(time)
  12. export function waitForInnerHTML(
  13. selector: string,
  14. expected: string,
  15. timeoutMs = 1000,
  16. ) {
  17. const container = css(selector).element()
  18. const getHTML = () => container.innerHTML
  19. if (getHTML().includes(expected)) {
  20. return Promise.resolve()
  21. }
  22. return new Promise<void>((resolve, reject) => {
  23. const cleanup = () => {
  24. clearTimeout(timer)
  25. observer.disconnect()
  26. }
  27. const check = () => {
  28. if (getHTML().includes(expected)) {
  29. cleanup()
  30. resolve()
  31. }
  32. }
  33. const observer = new MutationObserver(check)
  34. const timer = setTimeout(() => {
  35. const actual = getHTML()
  36. cleanup()
  37. reject(
  38. new Error(
  39. `Timed out waiting for innerHTML to contain ${expected} in ${selector}.\nReceived: ${actual}`,
  40. ),
  41. )
  42. }, timeoutMs)
  43. observer.observe(container, {
  44. subtree: true,
  45. childList: true,
  46. characterData: true,
  47. attributes: true,
  48. })
  49. })
  50. }
  51. export const nextFrame = () =>
  52. new Promise(resolve => {
  53. requestAnimationFrame(resolve)
  54. })
  55. export const click = (selector: string) => {
  56. ;(css(selector).element() as HTMLButtonElement).click()
  57. }
  58. export async function enterValue(locator: Locator, text: string) {
  59. await locator.fill(text)
  60. await userEvent.type(locator, '{enter}')
  61. }