utils.js 4.5 KB

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