utils.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // This is an invisible template tag for enabling syntax highlighting
  2. // of any string in most editors.
  3. export function html(strings) {
  4. return strings.raw[0]
  5. }
  6. export function ensureNoConsoleWarns() {
  7. cy.window().then((win) => {
  8. let cache = win.console.warn
  9. win.console.warn = () => { throw new Error('Console warn was triggered') }
  10. cy.on('window:before:unload', () => {
  11. win.console.warn = cache
  12. });
  13. });
  14. }
  15. export let test = function (name, template, callback, handleExpectedErrors = false) {
  16. it(name, () => {
  17. injectHtmlAndBootAlpine(cy, template, callback, undefined, handleExpectedErrors)
  18. })
  19. }
  20. test.only = (name, template, callback, handleExpectedErrors = false) => {
  21. it.only(name, () => {
  22. injectHtmlAndBootAlpine(cy, template, callback, undefined, handleExpectedErrors)
  23. })
  24. }
  25. test.skip = (name, template, callback, handleExpectedErrors = false) => {
  26. it.skip(name, () => {
  27. injectHtmlAndBootAlpine(cy, template, callback, undefined, handleExpectedErrors)
  28. })
  29. }
  30. test.retry = (count) => (name, template, callback, handleExpectedErrors = false) => {
  31. it(name, {
  32. retries: {
  33. // During "cypress run"
  34. runMode: count - 1,
  35. // During "cypress open"
  36. openMode: count - 1,
  37. }
  38. }, () => {
  39. injectHtmlAndBootAlpine(cy, template, callback, undefined, handleExpectedErrors)
  40. })
  41. }
  42. test.csp = (name, template, callback, handleExpectedErrors = false) => {
  43. it(name, () => {
  44. injectHtmlAndBootAlpine(cy, template, callback, __dirname+'/spec-csp.html', handleExpectedErrors)
  45. })
  46. }
  47. function injectHtmlAndBootAlpine(cy, templateAndPotentiallyScripts, callback, page, handleExpectedErrors = false) {
  48. let [template, scripts] = Array.isArray(templateAndPotentiallyScripts)
  49. ? templateAndPotentiallyScripts
  50. : [templateAndPotentiallyScripts]
  51. cy.visit(page || __dirname+'/spec.html')
  52. if( handleExpectedErrors ) {
  53. cy.on( 'uncaught:exception', ( error ) => {
  54. if( error.el === undefined && error.expression === undefined ) {
  55. console.warn( 'Expected all errors originating from Alpine to have el and expression. Letting cypress fail the test.', error )
  56. return true
  57. }
  58. return false
  59. } );
  60. }
  61. cy.get('#root').then(([el]) => {
  62. el.innerHTML = template
  63. el.evalScripts(scripts)
  64. cy.get('[alpine-is-ready]', { timeout: 5000 }).should('be.visible');
  65. // We can't just simply reload a page from a test, because we need to
  66. // re-inject all the templates and such. This is a helper to allow
  67. // a test-subject method to perform a redirect all on their own.
  68. let reload = () => {
  69. cy.reload()
  70. cy.get('#root').then(([el]) => {
  71. el.innerHTML = template
  72. el.evalScripts(scripts)
  73. cy.get('[alpine-is-ready]', { timeout: 5000 }).should('be.visible');
  74. })
  75. }
  76. cy.window().then(window => {
  77. callback(cy, reload, window, window.document)
  78. })
  79. })
  80. }
  81. export let haveData = (key, value) => ([el]) => expect(root(el)._x_dataStack[0][key]).to.deep.equal(value);
  82. export let haveFocus = () => el => expect(el).to.have.focus
  83. export let notHaveFocus = () => el => expect(el).not.to.be.focused
  84. export let haveAttribute = (name, value) => el => expect(el).to.have.attr(name, value)
  85. export let notHaveAttribute = (name, value) => el => expect(el).not.to.have.attr(name, value)
  86. export let haveProperty = (name, value) => el => expect(el).to.have.prop(name, value)
  87. export let haveText = text => el => expect(el).to.have.text(text)
  88. export let notHaveText = text => el => expect(el).not.to.have.text(text)
  89. export let contain = text => el => expect(el).to.contain(text)
  90. export let notContain = text => el => expect(el).not.to.contain(text)
  91. export let haveHtml = html => el => expect(el).to.have.html(html)
  92. export let beChecked = () => el => expect(el).to.be.checked
  93. export let notBeChecked = () => el => expect(el).not.to.be.checked
  94. export let beVisible = () => el => expect(el).to.be.visible
  95. export let notBeVisible = () => el => expect(el).not.to.be.visible
  96. export let exist = () => el => expect(el).to.exist
  97. export let notExist = () => el => expect(el).not.to.exist
  98. export let beHidden = () => el => expect(el).to.be.hidden
  99. export let haveClasses = classes => el => classes.forEach(aClass => expect(el).to.have.class(aClass))
  100. export let notHaveClasses = classes => el => classes.forEach(aClass => expect(el).not.to.have.class(aClass))
  101. export let haveValue = value => el => expect(el).to.have.value(value)
  102. export let haveLength = length => el => expect(el).to.have.length(length)
  103. export let beEqualTo = value => el => expect(el).to.eq(value)
  104. export let notHaveComputedStyle = (name, value) => el => {
  105. const win = el[0].ownerDocument.defaultView
  106. expect(win.getComputedStyle(el[0]).getPropertyValue(name)).not.to.eq(value)
  107. }
  108. export let haveComputedStyle = (name, value) => el => {
  109. const win = el[0].ownerDocument.defaultView
  110. expect(win.getComputedStyle(el[0]).getPropertyValue(name)).to.eq(value)
  111. }
  112. export function root(el) {
  113. if (el._x_dataStack) return el
  114. if (! el.parentElement) return
  115. return closestRoot(el.parentElement)
  116. }