describe('Core htmx AJAX Tests', function() {
beforeEach(function() {
this.server = makeServer()
clearWorkArea()
})
afterEach(function() {
this.server.restore()
clearWorkArea()
})
// bootstrap test
it('issues a GET request on click and swaps content', function() {
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('Click Me! ')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Clicked!')
})
it('processes inner content properly', function() {
this.server.respondWith('GET', '/test', 'Click Me ')
this.server.respondWith('GET', '/test2', 'Clicked!')
var div = make('
')
div.click()
this.server.respond()
div.innerHTML.should.equal('Click Me ')
var a = div.querySelector('a')
a.click()
this.server.respond()
a.innerHTML.should.equal('Clicked!')
})
it('handles swap outerHTML properly', function() {
this.server.respondWith('GET', '/test', 'Click Me ')
this.server.respondWith('GET', '/test2', 'Clicked!')
var div = make('
')
div.click()
should.equal(byId('d1'), div)
this.server.respond()
should.equal(byId('d1'), null)
byId('a1').click()
this.server.respond()
byId('a1').innerHTML.should.equal('Clicked!')
})
it('handles beforebegin properly', function() {
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i + ' ')
})
this.server.respondWith('GET', '/test2', '*')
var div = make('*
')
var parent = div.parentElement
div.click()
this.server.respond()
div.innerText.should.equal('*')
removeWhiteSpace(parent.innerText).should.equal('1*')
byId('a1').click()
this.server.respond()
removeWhiteSpace(parent.innerText).should.equal('**')
div.click()
this.server.respond()
div.innerText.should.equal('*')
removeWhiteSpace(parent.innerText).should.equal('*2*')
byId('a2').click()
this.server.respond()
removeWhiteSpace(parent.innerText).should.equal('***')
})
it('handles afterbegin properly', function() {
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('*
')
div.click()
this.server.respond()
div.innerText.should.equal('1*')
div.click()
this.server.respond()
div.innerText.should.equal('21*')
div.click()
this.server.respond()
div.innerText.should.equal('321*')
})
it('handles afterbegin properly with no initial content', function() {
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('
')
div.click()
this.server.respond()
div.innerText.should.equal('1')
div.click()
this.server.respond()
div.innerText.should.equal('21')
div.click()
this.server.respond()
div.innerText.should.equal('321')
})
it('handles afterend properly', function() {
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i + ' ')
})
this.server.respondWith('GET', '/test2', '*')
var div = make('*
')
var parent = div.parentElement
div.click()
this.server.respond()
div.innerText.should.equal('*')
removeWhiteSpace(parent.innerText).should.equal('*1')
byId('a1').click()
this.server.respond()
removeWhiteSpace(parent.innerText).should.equal('**')
div.click()
this.server.respond()
div.innerText.should.equal('*')
removeWhiteSpace(parent.innerText).should.equal('*2*')
byId('a2').click()
this.server.respond()
removeWhiteSpace(parent.innerText).should.equal('***')
})
it('handles beforeend properly', function() {
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('*
')
div.click()
this.server.respond()
div.innerText.should.equal('*1')
div.click()
this.server.respond()
div.innerText.should.equal('*12')
div.click()
this.server.respond()
div.innerText.should.equal('*123')
})
it('handles beforeend properly with no initial content', function() {
var i = 0
this.server.respondWith('GET', '/test', function(xhr) {
i++
xhr.respond(200, {}, '' + i)
})
var div = make('
')
div.click()
this.server.respond()
div.innerText.should.equal('1')
div.click()
this.server.respond()
div.innerText.should.equal('12')
div.click()
this.server.respond()
div.innerText.should.equal('123')
})
it('handles hx-target properly', function() {
this.server.respondWith('GET', '/test', 'Clicked!')
var btn = make('Click Me! ')
var target = make('Initial ')
btn.click()
target.innerHTML.should.equal('Initial')
this.server.respond()
target.innerHTML.should.equal('Clicked!')
})
it('handles 204 NO CONTENT responses properly', function() {
this.server.respondWith('GET', '/test', [204, {}, 'No Content!'])
var btn = make('Click Me! ')
btn.click()
btn.innerHTML.should.equal('Click Me!')
this.server.respond()
btn.innerHTML.should.equal('Click Me!')
})
it('handles 304 NOT MODIFIED responses properly', function() {
this.server.respondWith('GET', '/test-1', [200, {}, 'Content for Tab 1'])
this.server.respondWith('GET', '/test-2', [200, {}, 'Content for Tab 2'])
var target = make('
')
var btn1 = make('Tab 1 ')
var btn2 = make('Tab 2 ')
btn1.click()
target.innerHTML.should.equal('')
this.server.respond()
target.innerHTML.should.equal('Content for Tab 1')
btn2.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 2')
this.server.respondWith('GET', '/test-1', [304, {}, 'Content for Tab 1'])
this.server.respondWith('GET', '/test-2', [304, {}, 'Content for Tab 2'])
btn1.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 1')
btn2.click()
this.server.respond()
target.innerHTML.should.equal('Content for Tab 2')
})
it('handles hx-trigger with non-default value', function() {
this.server.respondWith('GET', '/test', 'Clicked!')
var form = make('')
form.click()
form.innerHTML.should.equal('Click Me!')
this.server.respond()
form.innerHTML.should.equal('Clicked!')
})
it('handles hx-trigger with load event', function() {
this.server.respondWith('GET', '/test', 'Loaded!')
var div = make('Load Me!
')
div.innerHTML.should.equal('Load Me!')
this.server.respond()
div.innerHTML.should.equal('Loaded!')
})
it('sets the content type of the request properly', function(done) {
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'done')
xhr.overriddenMimeType.should.equal('text/html')
done()
})
var div = make('Click Me!
')
div.click()
this.server.respond()
})
it('issues two requests when clicked twice before response', function() {
var i = 1
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'click ' + i)
i++
})
var div = make('
')
div.click()
div.click()
this.server.respond()
div.innerHTML.should.equal('click 1')
this.server.respond()
div.innerHTML.should.equal('click 2')
})
it('issues two requests when clicked three times before response', function() {
var i = 1
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, 'click ' + i)
i++
})
var div = make('
')
div.click()
div.click()
div.click()
this.server.respondAll()
div.innerHTML.should.equal('click 2')
})
it('properly handles hx-select for basic situation', function() {
var i = 1
this.server.respondWith('GET', '/test', "foo
bar
")
var div = make('
')
div.click()
this.server.respond()
div.innerHTML.should.equal('foo
')
})
it('properly handles hx-select for full html document situation', function() {
this.server.respondWith('GET', '/test', "foo
bar
")
var div = make('
')
div.click()
this.server.respond()
div.innerHTML.should.equal('foo
')
})
it('properly settles attributes on interior elements', function(done) {
this.server.respondWith('GET', '/test', "")
var div = make("")
div.click()
this.server.respond()
should.equal(byId('d1').getAttribute('width'), null)
setTimeout(function() {
should.equal(byId('d1').getAttribute('width'), 'bar')
done()
}, 20)
})
it('properly settles attributes elements with single quotes in id', function(done) {
this.server.respondWith('GET', '/test', "")
var div = make("")
div.click()
this.server.respond()
should.equal(byId("d1'").getAttribute('width'), null)
setTimeout(function() {
should.equal(byId("d1'").getAttribute('width'), 'bar')
done()
}, 20)
})
it('properly settles attributes elements with double quotes in id', function(done) {
this.server.respondWith('GET', '/test', "")
var div = make("")
div.click()
this.server.respond()
should.equal(byId('d1"').getAttribute('width'), null)
setTimeout(function() {
should.equal(byId('d1"').getAttribute('width'), 'bar')
done()
}, 20)
})
it('properly handles multiple select input', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3'] })
})
it('properly handles multiple select input when "multiple" attribute is empty string', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3'] })
})
it('properly handles two multiple select inputs w/ same name', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('m1').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: 'm1' })
byId('m1').selected = true
byId('m3').selected = true
byId('m7').selected = true
byId('m8').selected = true
form.click()
this.server.respond()
values.should.deep.equal({ multiSelect: ['m1', 'm3', 'm7', 'm8'] })
})
it('properly handles multiple email input', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('')
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: '' })
byId('multiEmail').value = 'foo@example.com'
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: 'foo@example.com' })
byId('multiEmail').value = 'foo@example.com,bar@example.com'
form.click()
this.server.respond()
values.should.deep.equal({ multiEmail: 'foo@example.com,bar@example.com' })
})
it('properly handles checkbox inputs', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('cb1').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: 'cb1' })
byId('cb1').checked = true
byId('cb2').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: 'cb4' })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
byId('cb5').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: ['cb4', 'cb5'] })
byId('cb1').checked = true
byId('cb2').checked = true
byId('cb3').checked = true
byId('cb4').checked = true
byId('cb5').checked = true
byId('cb6').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb2', 'cb3'], c2: ['cb4', 'cb5'], c3: 'cb6' })
byId('cb1').checked = true
byId('cb2').checked = false
byId('cb3').checked = true
byId('cb4').checked = false
byId('cb5').checked = true
byId('cb6').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ c1: ['cb1', 'cb3'], c2: 'cb5', c3: 'cb6' })
})
it('properly handles radio inputs', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
var form = make('')
form.click()
this.server.respond()
values.should.deep.equal({})
byId('rb1').checked = true
form.click()
this.server.respond()
values.should.deep.equal({ r1: 'rb1' })
})
it('text nodes dont screw up settling via variable capture', function() {
this.server.respondWith('GET', '/test', "
fooo")
this.server.respondWith('GET', '/test2', 'clicked')
var div = make("
")
div.click()
this.server.respond()
byId('d1').click()
this.server.respond()
byId('d1').innerHTML.should.equal('clicked')
})
it('script nodes evaluate', function() {
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "
")
var div = make("
")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
})
it('stand alone script nodes evaluate', function() {
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "")
var div = make("
")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
})
it('script nodes can define global functions', function() {
try {
window.foo = {}
this.server.respondWith('GET', '/test', "")
var div = make("
")
div.click()
this.server.respond()
foo.bar().should.equal(42)
} finally {
delete window.foo
}
})
it('child script nodes evaluate when children', function() {
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "
")
var div = make("
")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
})
it('child script nodes evaluate when first child', function() {
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "
")
var div = make("
")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
})
it('child script nodes evaluate when not explicitly marked javascript', function() {
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', '
')
var div = make("
")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
} finally {
delete window.callGlobal
}
})
it('script nodes do not evaluate when explicitly marked as something other than javascript', function() {
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
try {
this.server.respondWith('GET', '/test', "
")
var div = make("
")
div.click()
this.server.respond()
globalWasCalled.should.equal(false)
} finally {
delete window.callGlobal
}
})
it('script nodes evaluate after swap', function() {
window.callGlobal = function() {
console.log('Here...')
window.tempVal = byId('d1').innerText
}
try {
this.server.respondWith('GET', '/test', "")
var div = make("
")
div.click()
this.server.respond()
window.tempVal.should.equal('After settle...')
} finally {
delete window.callGlobal
delete window.tempVal
}
})
it('script node exceptions do not break rendering', function() {
this.skip('Rendering does not break, but the exception bubbles up and mocha reports it')
this.server.respondWith('GET', '/test', "clicked")
var div = make("
")
div.click()
this.server.respond()
div.innerText.should.equal('clicked')
console.log(div.innerText)
console.log('here')
})
it('allows empty verb values', function() {
var path = null
var div = make("
")
htmx.on(div, 'htmx:configRequest', function(evt) {
path = evt.detail.path
return false
})
div.click()
this.server.respond()
path.should.not.be.null
})
it('allows blank verb values', function() {
var path = null
var div = make('
')
htmx.on(div, 'htmx:configRequest', function(evt) {
path = evt.detail.path
return false
})
div.click()
this.server.respond()
path.should.not.be.null
})
it('input values are not settle swapped (causes flicker)', function() {
this.server.respondWith('GET', '/test', " ")
var input = make(" ")
input.click()
this.server.respond()
input = byId('i1')
input.value.should.equal('bar')
})
it('autofocus attribute works properly', function() {
this.server.respondWith('GET', '/test', " ")
var input = make(" ")
input.focus()
input.click()
document.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
document.activeElement.should.equal(input2)
})
it('autofocus attribute works properly w/ child', function() {
this.server.respondWith('GET', '/test', "
")
var input = make(" ")
input.focus()
input.click()
document.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
document.activeElement.should.equal(input2)
})
it('autofocus attribute works properly w/ true value', function() {
this.server.respondWith('GET', '/test', "
")
var input = make(" ")
input.focus()
input.click()
document.activeElement.should.equal(input)
this.server.respond()
var input2 = byId('i2')
document.activeElement.should.equal(input2)
})
it('multipart/form-data encoding works', function() {
this.server.respondWith('POST', '/test', function(xhr) {
should.equal(xhr.requestHeaders['Content-Type'], undefined)
if (xhr.requestBody.get) { // IE 11 does not support
xhr.requestBody.get('i1').should.equal('foo')
}
xhr.respond(200, {}, 'body: ' + xhr.requestBody)
})
var form = make("')
form.focus()
form.click()
this.server.respond()
})
it('removed elements do not issue requests', function() {
var count = 0
this.server.respondWith('GET', '/test', function(xhr) {
count++
xhr.respond(200, {}, '')
})
var btn = make('Click Me! ')
htmx.remove(btn)
btn.click()
this.server.respond()
count.should.equal(0)
})
it('title tags update title', function() {
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "htmx rocks! Clicked!")
})
var btn = make('Click Me! ')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal('htmx rocks!')
})
it('svg title tags do not update title', function() {
var originalTitle = window.document.title
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "" + originalTitle + 'UPDATE' + ' Clicked!')
})
var btn = make('Click Me! ')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal(originalTitle)
})
it('first title tag outside svg title tags updates title', function() {
var originalTitle = window.document.title
var newTitle = originalTitle + '!!!'
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, "" + newTitle + " foo Clicked!x ")
})
var btn = make('Click Me! ')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal(newTitle)
})
it('title update does not URL escape', function() {
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(200, {}, '</> htmx rocks! Clicked!')
})
var btn = make('Click Me! ')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
window.document.title.should.equal('> htmx rocks!')
})
it('by default 400 content is not swapped', function() {
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('Click Me! ')
btn.click()
this.server.respond()
btn.innerText.should.equal('Click Me!')
})
it('400 content can be swapped if configured to do so', function() {
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('Click Me! ')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!')
htmx.off('htmx:beforeSwap', handler)
})
it('400 content can be retargeted if configured to do so', function() {
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
event.detail.target = byId('d1')
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('Click Me! ')
var div = make('
')
btn.click()
this.server.respond()
div.innerText.should.equal('Clicked!')
htmx.off('htmx:beforeSwap', handler)
})
it('errors are triggered only on 400+', function() {
var errors = 0
var handler = htmx.on('htmx:responseError', function() {
errors++
})
this.server.respondWith('GET', '/test1', function(xhr) {
xhr.respond(204, {}, 'Clicked!')
})
this.server.respondWith('GET', '/test2', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn1 = make('Click Me! ')
var btn2 = make('Click Me! ')
btn1.click()
btn2.click()
this.server.respond()
this.server.respond()
errors.should.equal(1)
htmx.off('htmx:responseError', handler)
})
it('content can be modified if configured to do so', function() {
var handler = htmx.on('htmx:beforeSwap', function(event) {
if (event.detail.xhr.status === 400) {
event.detail.shouldSwap = true
event.detail.serverResponse = event.detail.serverResponse + '!!'
}
})
this.server.respondWith('GET', '/test', function(xhr) {
xhr.respond(400, {}, 'Clicked!')
})
var btn = make('Click Me! ')
btn.click()
this.server.respond()
btn.innerText.should.equal('Clicked!!!')
htmx.off('htmx:beforeSwap', handler)
})
it('scripts w/ src attribute are properly loaded', function(done) {
try {
if (byId('mocha')) {
this.server.respondWith('GET', '/test', "")
} else {
this.server.respondWith('GET', '/test', "")
}
var div = make("
")
div.click()
this.server.respond()
byId('setGlobalScript').addEventListener('load', function() {
window.globalWasCalled.should.equal(true)
delete window.globalWasCalled
done()
})
} finally {
delete window.globalWasCalled
}
})
it('should load tags with colon in their names', function() {
this.server.respondWith('GET', '/test', 'Foobar ')
var btn = make('Give me colons! ')
btn.click()
this.server.respond()
btn.innerHTML.should.equal('Foobar ')
})
it('properly handles clicked submit button with a value inside a htmx form', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
})
it('properly handles clicked submit input with a value inside a htmx form', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
})
it('properly handles clicked submit button with a value inside a non-htmx form', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
})
it('properly handles clicked submit input with a value inside a non-htmx form', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
})
it('properly handles clicked submit button with a value outside a htmx form', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('' +
'button ')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
})
it('properly handles clicked submit input with a value outside a htmx form', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('' +
' ')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: 'buttonValue' })
})
it('properly handles clicked submit button with a value stacking with regular input', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('')
byId('btnA').click()
this.server.respond()
values.should.deep.equal({ action: 'A' })
byId('btnB').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'B'] })
byId('btnC').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'C'] })
})
it('properly handles clicked submit input with a value stacking with regular input', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('')
byId('btnA').click()
this.server.respond()
values.should.deep.equal({ action: 'A' })
byId('btnB').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'B'] })
byId('btnC').click()
this.server.respond()
values.should.deep.equal({ action: ['A', 'C'] })
})
it('properly handles clicked submit button with a value inside a form, referencing another form', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('' +
'')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
})
it('properly handles clicked submit input with a value inside a form, referencing another form', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('' +
'')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
})
it('sends referenced form values when a button referencing another form is clicked', function() {
var values
this.server.respondWith('POST', '/test3', function(xhr) {
values = getParameters(xhr)
xhr.respond(205, {}, '')
})
make('' +
'')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
})
it('sends referenced form values when a submit input referencing another form is clicked', function() {
var values
this.server.respondWith('POST', '/test3', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('' +
'')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'] })
})
it('properly handles inputs external to form', function() {
var values
this.server.respondWith('Post', '/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('' +
' ' +
'' +
' ' +
' ' +
' ' +
'button ')
byId('submit').click()
this.server.respond()
values.should.deep.equal({ t1: 'textValue', b1: ['inputValue', 'buttonValue'], s1: 'selectValue' })
})
it('properly handles buttons with formmethod=dialog', function() {
var request = false
this.server.respondWith('POST', '/test', function(xhr) {
request = true
xhr.respond(200, {}, 'Bar ')
})
make(' ')
byId('submit').click()
this.server.respond()
request.should.equal(false)
})
it('can associate submit buttons from outside a form with the current version of the form after swap', function() {
const template = '\n' +
'Outside '
var values
this.server.respondWith('/test', function(xhr) {
values = getParameters(xhr)
xhr.respond(200, {}, template)
})
make(template)
const button = byId('outside')
button.focus()
button.click()
this.server.respond()
values.should.deep.equal({ name: '', outside: '' })
button.focus()
button.click()
this.server.respond()
values.should.deep.equal({ name: '', outside: '' })
})
it('properly handles form reset behaviour with a htmx enabled reset button inside a form', function() {
var values
this.server.respondWith('POST', '/reset', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('')
byId('t1').value = 'otherValue'
byId('reset').click()
this.server.respond()
values.should.deep.equal({ b1: 'buttonValue', t1: 'otherValue' })
byId('t1').value.should.equal('defaultValue')
})
it('properly handles form reset behaviour with a htmx enabled reset button outside a form', function() {
var values
this.server.respondWith('POST', '/reset', function(xhr) {
values = getParameters(xhr)
xhr.respond(204, {}, '')
})
make('' +
'reset ')
byId('t1').value = 'otherValue'
byId('reset').click()
this.server.respond()
values.should.deep.equal({ b1: 'buttonValue', t1: 'otherValue' })
byId('t1').value.should.equal('defaultValue')
})
it('script tags get swapped in with nonce applied from inlineScriptNonce', function() {
var globalWasCalled = false
window.callGlobal = function() {
globalWasCalled = true
}
htmx.config.inlineScriptNonce = 'testnonce'
try {
this.server.respondWith('GET', '/test', "")
var div = make("
")
div.click()
this.server.respond()
globalWasCalled.should.equal(true)
byId('noncescript').nonce.should.equal('testnonce')
} finally {
delete window.callGlobal
htmx.config.inlineScriptNonce = ''
}
})
it('normalizeScriptTags logs error when insertBefore fails', function() {
htmx.div = make('
')
htmx.div.insertBefore = undefined
htmx._('normalizeScriptTags(htmx.div)')
delete htmx.div
})
})