describe('hx-trigger attribute', function() {
    beforeEach(function() {
        setupTest(this.currentTest)
    })
    afterEach(function() {
        cleanupTest()
    })

    it('non-default triggers work', async function () {
        mockResponse('GET', '/test', 'Clicked!')
        createProcessedHTML('<form hx-get="/test" hx-trigger="click">Click Me!</form>')
        find("form").click()
        await forRequest()
        playground().innerText.should.equal('Clicked!')
    })

    it('works with multiple events', async function () {
        mockResponse('GET', '/test', 'Clicked!')
        let div = createProcessedHTML('<div hx-trigger="foo, bar" hx-get="/test" hx-swap="innerHTML">Requests: 0</div>');
        htmx.trigger(div, 'foo');
        await forRequest()
        htmx.trigger(div, 'bar');
        await forRequest()
        fetchMock.calls.length.should.equal(2)
    })

    it('filters properly with false expression filter spec', function() {
        mockResponse('GET', '/test', 'Called!')
        let form = createProcessedHTML('<form hx-get="/test" hx-trigger="evt[false]">Not Called</form>')
        let event = new CustomEvent("evt");
        event.foo = false
        form.dispatchEvent(event)
        fetchMock.calls.length.should.equal(0)
    })

    it('filters properly with false filter spec', function() {
        mockResponse('GET', '/test', 'Called!')
        let form = createProcessedHTML('<form hx-get="/test" hx-trigger="evt[foo]">Not Called</form>')
        let event = new CustomEvent("evt");
        event.foo = false
        form.dispatchEvent(event)
        fetchMock.calls.length.should.equal(0)
    })

    it('filters properly with true filter spec', async function() {
        mockResponse('GET', '/test', 'Called!')
        let form = createProcessedHTML('<form hx-get="/test" hx-trigger="evt[foo]">Not Called</form>')
        let event = new CustomEvent("evt");
        event.foo = true
        form.dispatchEvent(event)
        fetchMock.calls.length.should.equal(1)
        await forRequest()
    })

    it('filters properly with true expression filter spec', async function() {
        mockResponse('GET', '/test', 'Called!')
        let form = createProcessedHTML('<form hx-get="/test" hx-trigger="evt[true]">Not Called</form>')
        let event = new CustomEvent("evt");
        event.foo = true
        form.dispatchEvent(event)
        fetchMock.calls.length.should.equal(1)
        await forRequest()
    })

    it('once modifier works', function () {
        mockResponse('GET', '/test', "Response")
        createProcessedHTML('<button hx-trigger="click once" hx-get="/test"/></button>')
        find('button').click()
        fetchMock.calls.length.should.equal(1)
        find('button').click()
        fetchMock.calls.length.should.equal(1)
    })

    it('event listeners can filter on target', function() {
        mockResponse('GET', '/test', "foo")
        createProcessedHTML('<div>' +
            '<div id="d1" hx-trigger="click from:body target:#d3" hx-get="/test">Requests: 0</div>' +
            '<div id="d2"></div>' +
            '<div id="d3"></div>' +
            '</div>')

        document.body.click()
        fetchMock.calls.length.should.equal(0)

        find('#d1').click()
        fetchMock.calls.length.should.equal(0)

        find('#d2').click()
        fetchMock.calls.length.should.equal(0)

        find('#d3').click()
        fetchMock.calls.length.should.equal(1)
    })


    it('consume prevents event propagation', async function () {
        mockResponse('GET', '/foo', 'foo')
        mockResponse('GET', '/bar', 'bar')
        createProcessedHTML(
            "<div hx-trigger='click' hx-get='/foo' hx-target='#d3' hx-swap='innerHTML'>" +
            "   <div id='d1' hx-trigger='click consume' hx-get='/bar'></div>" +
            "</div><div id='d3'>bar</div>")
        find('#d1').click()
        await forRequest()
        await htmx.timeout(100)
        // should not have been replaced by click
        find('#d3').innerText.should.equal('bar')
    })

    it('load event triggers on element creation', async function () {
        debug(this)
        mockResponse('GET', '/test', 'Loaded!')
        createProcessedHTML('<div hx-get="/test" hx-trigger="load">Not Loaded</div>')
        await forRequest()
        playground().innerText.should.equal('Loaded!')
    })

    // TODO figure out how to test throttling
    // it('throttle prevents multiple requests from happening', async function () {
    //     mockResponse('GET', '/test', "Success!")


    //     var div = initHTML("<div hx-trigger='click throttle:20ms' hx-get='/test'></div>")
    //
    //     // First click fires immediately
    //     div.click()
    //     await htmx.waitATick();
    //     fetchMock.calls.length.should.equal(1);
    //
    //     // Second click during throttle window - gets queued
    //     div.click()
    //     await htmx.waitATick();
    //     fetchMock.calls.length.should.equal(1); // Still just 1
    //
    //     // Wait for throttle to expire + trailing call (100ms + margin)
    //     await htmx.timeout(150);
    //     fetchMock.calls.length.should.equal(2); // Queued click now fired
    // })
    //


    // // This test and the next one should be kept in sync.
    // it('changed modifier works along from clause with two inputs', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var input1 = make('<input type="text"/>')
    //     var input2 = make('<input type="text"/>')
    //     make('<div hx-trigger="click changed from:input" hx-target="#d1" hx-get="/test"></div>')
    //     var div = make('<div id="d1"></div>')
    //
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('')
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('')
    //
    //     input1.value = 'bar'
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('')
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //
    //     input2.value = 'foo'
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    // })
    //
    // // This test and the previous one should be kept in sync.
    // it('changed modifier counts each triggerspec separately', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var input1 = make('<input type="text"/>')
    //     var input2 = make('<input type="text"/>')
    //     make('<div hx-trigger="click changed from:input" hx-target="#d1" hx-get="/test"></div>')
    //     make('<div hx-trigger="click changed from:input" hx-target="#d1" hx-get="/test"></div>')
    //     var div = make('<div id="d1"></div>')
    //
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('')
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('')
    //
    //     input1.value = 'bar'
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('')
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    //
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    //
    //     input2.value = 'foo'
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 4')
    // })
    //
    // it('separate changed modifier works along from clause with two inputs', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var input1 = make('<input type="text"/>')
    //     var input2 = make('<input type="text"/>')
    //     make('<div hx-trigger="click changed from:input:nth-child(1), click changed from:input:nth-child(2)" hx-target="#d1" hx-get="/test"></div>')
    //     var div = make('<div id="d1"></div>')
    //
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('')
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('')
    //
    //     input1.value = 'bar'
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('')
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //
    //     input2.value = 'foo'
    //     input1.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     input2.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    // })
    //

    //
    // it('once modifier works with multiple triggers', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var input = make('<input hx-trigger="click once, foo" hx-target="#d1" hx-get="/test" value="foo"/>')
    //     var div = make('<div id="d1"></div>')
    //     input.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     input.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     input.value = 'bar'
    //     input.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     input.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     htmx.trigger(input, 'foo')
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    // })
    //

    //
    // it('non-default value works w/ data-* prefix', function() {
    //     this.server.respondWith('GET', '/test', 'Clicked!')
    //     var form = make('<form data-hx-get="/test" data-hx-trigger="click">Click Me!</form>')
    //     form.click()
    //     form.innerHTML.should.equal('Click Me!')
    //     this.server.respond()
    //     form.innerHTML.should.equal('Clicked!')
    // })
    //
    // it('works with multiple events', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div = make('<div hx-trigger="load,click" hx-get="/test">Requests: 0</div>')
    //     div.innerHTML.should.equal('Requests: 0')
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     div.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    // })
    //
    // it('parses spec strings', function() {
    //     var specExamples = {
    //         '': [{ trigger: 'click' }],
    //         'every 1s': [{ trigger: 'every', pollInterval: 1000 }],
    //         'every 0s': [{ trigger: 'every', pollInterval: 0 }],
    //         'every 0ms': [{ trigger: 'every', pollInterval: 0 }],
    //         click: [{ trigger: 'click' }],
    //         customEvent: [{ trigger: 'customEvent' }],
    //         'event changed': [{ trigger: 'event', changed: true }],
    //         'event once': [{ trigger: 'event', once: true }],
    //         'event throttle:1s': [{ trigger: 'event', throttle: 1000 }],
    //         'event throttle:0s': [{ trigger: 'event', throttle: 0 }],
    //         'event throttle:0ms': [{ trigger: 'event', throttle: 0 }],
    //         'event throttle:1s, foo': [{ trigger: 'event', throttle: 1000 }, { trigger: 'foo' }],
    //         'event delay:1s': [{ trigger: 'event', delay: 1000 }],
    //         'event delay:1s, foo': [{ trigger: 'event', delay: 1000 }, { trigger: 'foo' }],
    //         'event delay:0s, foo': [{ trigger: 'event', delay: 0 }, { trigger: 'foo' }],
    //         'event delay:0ms, foo': [{ trigger: 'event', delay: 0 }, { trigger: 'foo' }],
    //         'event changed once delay:1s': [{ trigger: 'event', changed: true, once: true, delay: 1000 }],
    //         'event1,event2': [{ trigger: 'event1' }, { trigger: 'event2' }],
    //         'event1, event2': [{ trigger: 'event1' }, { trigger: 'event2' }],
    //         'event1 once, event2 changed': [{ trigger: 'event1', once: true }, { trigger: 'event2', changed: true }],
    //         'event1,': [{ trigger: 'event1' }],
    //         '  ': [{ trigger: 'click' }]
    //     }
    //
    //     for (var specString in specExamples) {
    //         var div = make("<div hx-trigger='" + specString + "'></div>")
    //         var spec = htmx._('getTriggerSpecs')(div)
    //         spec.should.deep.equal(specExamples[specString], 'Found : ' + JSON.stringify(spec) + ', expected : ' + JSON.stringify(specExamples[specString]) + ' for spec: ' + specString)
    //     }
    // })
    //
    // it('sets default trigger for forms', function() {
    //     var form = make('<form></form>')
    //     var spec = htmx._('getTriggerSpecs')(form)
    //     spec.should.deep.equal([{ trigger: 'submit' }])
    // })
    //
    // it('sets default trigger for form elements', function() {
    //     var form = make('<input></input>')
    //     var spec = htmx._('getTriggerSpecs')(form)
    //     spec.should.deep.equal([{ trigger: 'change' }])
    // })
    //
    // it('filters properly with false filter spec', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var form = make('<form hx-get="/test" hx-trigger="evt[foo]">Not Called</form>')
    //     form.click()
    //     form.innerHTML.should.equal('Not Called')
    //     var event = htmx._('makeEvent')('evt')
    //     form.dispatchEvent(event)
    //     this.server.respond()
    //     form.innerHTML.should.equal('Not Called')
    // })
    //
    // it('filters properly with true filter spec', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var form = make('<form hx-get="/test" hx-trigger="evt[foo]">Not Called</form>')
    //     form.click()
    //     form.innerHTML.should.equal('Not Called')
    //     var event = htmx._('makeEvent')('evt')
    //     event.foo = true
    //     form.dispatchEvent(event)
    //     this.server.respond()
    //     form.innerHTML.should.equal('Called!')
    // })
    //
    // it('filters properly compound filter spec', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var div = make('<div hx-get="/test" hx-trigger="evt[foo&&bar]">Not Called</div>')
    //     var event = htmx._('makeEvent')('evt')
    //     event.foo = true
    //     div.dispatchEvent(event)
    //     this.server.respond()
    //     div.innerHTML.should.equal('Not Called')
    //     event.bar = true
    //     div.dispatchEvent(event)
    //     this.server.respond()
    //     div.innerHTML.should.equal('Called!')
    // })
    //
    // it('can refer to target element in condition', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var div = make('<div hx-get="/test" hx-trigger="evt[target.classList.contains(\'doIt\')]">Not Called</div>')
    //     var event = htmx._('makeEvent')('evt')
    //     div.dispatchEvent(event)
    //     this.server.respond()
    //     div.innerHTML.should.equal('Not Called')
    //     div.classList.add('doIt')
    //     div.dispatchEvent(event)
    //     this.server.respond()
    //     div.innerHTML.should.equal('Called!')
    // })
    //
    // it('can refer to target element in condition w/ equality', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var div = make('<div hx-get="/test" hx-trigger="evt[target.id==\'foo\']">Not Called</div>')
    //     var event = htmx._('makeEvent')('evt')
    //     div.dispatchEvent(event)
    //     this.server.respond()
    //     div.innerHTML.should.equal('Not Called')
    //     div.id = 'foo'
    //     div.dispatchEvent(event)
    //     this.server.respond()
    //     div.innerHTML.should.equal('Called!')
    // })
    //
    // it('negative condition', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var div = make('<div hx-get="/test" hx-trigger="evt[!target.classList.contains(\'disabled\')]">Not Called</div>')
    //     div.classList.add('disabled')
    //     var event = htmx._('makeEvent')('evt')
    //     div.dispatchEvent(event)
    //     this.server.respond()
    //     div.innerHTML.should.equal('Not Called')
    //     div.classList.remove('disabled')
    //     div.dispatchEvent(event)
    //     this.server.respond()
    //     div.innerHTML.should.equal('Called!')
    // })
    //
    // it('global function call works', function() {
    //     window.globalFun = function(evt) {
    //         return evt.bar
    //     }
    //     try {
    //         this.server.respondWith('GET', '/test', 'Called!')
    //         var div = make('<div hx-get="/test" hx-trigger="evt[globalFun(event)]">Not Called</div>')
    //         var event = htmx._('makeEvent')('evt')
    //         event.bar = false
    //         div.dispatchEvent(event)
    //         this.server.respond()
    //         div.innerHTML.should.equal('Not Called')
    //         event.bar = true
    //         div.dispatchEvent(event)
    //         this.server.respond()
    //         div.innerHTML.should.equal('Called!')
    //     } finally {
    //         delete window.globalFun
    //     }
    // })
    //
    // it('global property event filter works', function() {
    //     window.foo = {
    //         bar: false
    //     }
    //     try {
    //         this.server.respondWith('GET', '/test', 'Called!')
    //         var div = make('<div hx-get="/test" hx-trigger="evt[foo.bar]">Not Called</div>')
    //         var event = htmx._('makeEvent')('evt')
    //         div.dispatchEvent(event)
    //         this.server.respond()
    //         div.innerHTML.should.equal('Not Called')
    //         foo.bar = true
    //         div.dispatchEvent(event)
    //         this.server.respond()
    //         div.innerHTML.should.equal('Called!')
    //     } finally {
    //         delete window.foo
    //     }
    // })
    //
    // it('global variable filter works', function() {
    //     try {
    //         this.server.respondWith('GET', '/test', 'Called!')
    //         var div = make('<div hx-get="/test" hx-trigger="evt[foo]">Not Called</div>')
    //         var event = htmx._('makeEvent')('evt')
    //         div.dispatchEvent(event)
    //         this.server.respond()
    //         div.innerHTML.should.equal('Not Called')
    //         window.foo = true
    //         div.dispatchEvent(event)
    //         this.server.respond()
    //         div.innerHTML.should.equal('Called!')
    //     } finally {
    //         delete window.foo
    //     }
    // })
    //
    // it('can filter polling', function(complete) {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     window.foo = false
    //     var div = make('<div hx-get="/test" hx-trigger="every 5ms[foo]">Not Called</div>')
    //     var div2 = make('<div hx-get="/test" hx-trigger="every 5ms">Not Called</div>')
    //     this.server.autoRespond = true
    //     this.server.autoRespondAfter = 0
    //     setTimeout(function() {
    //         div.innerHTML.should.equal('Not Called')
    //         div2.innerHTML.should.equal('Called!')
    //         delete window.foo
    //         complete()
    //     }, 100)
    // })
    //
    // it('bad condition issues error', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var div = make('<div hx-get="/test" hx-trigger="evt[a.b]">Not Called</div>')
    //     var errorEvent = null
    //     var handler = htmx.on('htmx:eventFilter:error', function(event) {
    //         errorEvent = event
    //     })
    //     try {
    //         var event = htmx._('makeEvent')('evt')
    //         div.dispatchEvent(event)
    //         should.not.equal(null, errorEvent)
    //         should.not.equal(null, errorEvent.detail.source)
    //         console.log(errorEvent.detail.source)
    //     } finally {
    //         htmx.off('htmx:eventFilter:error', handler)
    //     }
    // })
    //
    // it('filters properly with true for empty condition', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var form = make('<form hx-get="/test" hx-trigger="evt[]">Not Called</form>')
    //     form.click()
    //     form.innerHTML.should.equal('Not Called')
    //     var event = htmx._('makeEvent')('evt')
    //     form.dispatchEvent(event)
    //     this.server.respond()
    //     form.innerHTML.should.equal('Called!')
    // })
    //
    // it('syntax error in condition issues error', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var errorEvent = null
    //     var handler = htmx.on('htmx:syntax:error', function(event) {
    //         errorEvent = event
    //     })
    //     var form = make('<form hx-get="/test" hx-trigger="evt[{]">Not Called</form>')
    //     try {
    //         var event = htmx._('makeEvent')('evt')
    //         form.dispatchEvent(event)
    //         should.not.equal(null, errorEvent)
    //         should.not.equal(null, errorEvent.detail.source)
    //         console.log(errorEvent.detail.source)
    //     } finally {
    //         htmx.off('htmx:syntax:error', handler)
    //     }
    // })
    //
    // it('filters properly with condition containing square backets', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var form = make('<form hx-get="/test" hx-trigger="evt[foo[0]]">Not Called</form>')
    //     form.click()
    //     form.innerHTML.should.equal('Not Called')
    //     var event = htmx._('makeEvent')('evt')
    //     event.foo = [true]
    //     form.dispatchEvent(event)
    //     this.server.respond()
    //     form.innerHTML.should.equal('Called!')
    // })
    //
    // it('from clause works', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div2 = make('<div id="d2"></div>')
    //     var div1 = make('<div hx-trigger="click from:#d2" hx-get="/test">Requests: 0</div>')
    //     div1.innerHTML.should.equal('Requests: 0')
    //     div1.click()
    //     this.server.respond()
    //     div1.innerHTML.should.equal('Requests: 0')
    //     div2.click()
    //     this.server.respond()
    //     div1.innerHTML.should.equal('Requests: 1')
    // })
    //
    // it('from clause works with body selector', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div1 = make('<div hx-trigger="click from:body" hx-get="/test">Requests: 0</div>')
    //     div1.innerHTML.should.equal('Requests: 0')
    //     document.body.click()
    //     this.server.respond()
    //     div1.innerHTML.should.equal('Requests: 1')
    // })
    //
    // it('from clause works with document selector', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div1 = make('<div hx-trigger="foo from:document" hx-get="/test">Requests: 0</div>')
    //     div1.innerHTML.should.equal('Requests: 0')
    //     htmx.trigger(document, 'foo')
    //     this.server.respond()
    //     div1.innerHTML.should.equal('Requests: 1')
    // })
    //
    // it('from clause works with window selector', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div1 = make('<div hx-trigger="foo from:window" hx-get="/test">Requests: 0</div>')
    //     div1.innerHTML.should.equal('Requests: 0')
    //     htmx.trigger(window, 'foo')
    //     this.server.respond()
    //     div1.innerHTML.should.equal('Requests: 1')
    // })
    //
    // it('from clause works with closest clause', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div1 = make('<div><a id="a1" hx-trigger="click from:closest div" hx-get="/test">Requests: 0</a></div>')
    //     var a1 = byId('a1')
    //     a1.innerHTML.should.equal('Requests: 0')
    //     div1.click()
    //     this.server.respond()
    //     a1.innerHTML.should.equal('Requests: 1')
    // })
    //
    // it('from clause works with find clause', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div1 = make('<div hx-trigger="click from:find a" hx-target="#a1" hx-get="/test"><a id="a1">Requests: 0</a></div>')
    //     var a1 = byId('a1')
    //     a1.innerHTML.should.equal('Requests: 0')
    //     a1.click()
    //     this.server.respond()
    //     a1.innerHTML.should.equal('Requests: 1')
    // })
    //
    // it('from clause works with next', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     make('<div hx-trigger="click from:next" hx-target="#a1" hx-get="/test"></div><a id="a1">Requests: 0</a>')
    //     var a1 = byId('a1')
    //     a1.innerHTML.should.equal('Requests: 0')
    //     a1.click()
    //     this.server.respond()
    //     a1.innerHTML.should.equal('Requests: 1')
    // })
    //
    // it('from clause works with previous', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     make('<a id="a1">Requests: 0</a><div hx-trigger="click from:previous" hx-target="#a1" hx-get="/test"></div>')
    //     var a1 = byId('a1')
    //     a1.innerHTML.should.equal('Requests: 0')
    //     a1.click()
    //     this.server.respond()
    //     a1.innerHTML.should.equal('Requests: 1')
    // })
    //
    // it('event listeners on other elements are removed when an element is swapped out', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     this.server.respondWith('GET', '/test2', 'Clicked')
    //
    //     var div1 = make('<div hx-get="/test2">' +
    //         '<div id="d2" hx-trigger="click from:body" hx-get="/test">Requests: 0</div>' +
    //         '</div>')
    //     var div2 = byId('d2')
    //
    //     div2.innerHTML.should.equal('Requests: 0')
    //     document.body.click()
    //     this.server.respond()
    //     requests.should.equal(1)
    //
    //     requests.should.equal(1)
    //
    //     div1.click()
    //     this.server.respond()
    //     div1.innerHTML.should.equal('Clicked')
    //
    //     requests.should.equal(2)
    //
    //     document.body.click()
    //     this.server.respond()
    //
    //     requests.should.equal(2)
    // })
    //
    // it('multiple triggers with from clauses mixed in work', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div2 = make('<div id="d2"></div>')
    //     var div1 = make('<div hx-trigger="click from:#d2, click" hx-get="/test">Requests: 0</div>')
    //     div1.innerHTML.should.equal('Requests: 0')
    //     div1.click()
    //     this.server.respond()
    //     div1.innerHTML.should.equal('Requests: 1')
    //     div2.click()
    //     this.server.respond()
    //     div1.innerHTML.should.equal('Requests: 2')
    // })
    //
    // it('from clause works with multiple extended selectors', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     make('<button id="btn" type="button">Click me</button>' +
    //         '<div hx-trigger="click from:(previous button, next a)" hx-target="#a1" hx-get="/test"></div>' +
    //         '<a id="a1">Requests: 0</a>')
    //     var btn = byId('btn')
    //     var a1 = byId('a1')
    //     a1.innerHTML.should.equal('Requests: 0')
    //     btn.click()
    //     this.server.respond()
    //     a1.innerHTML.should.equal('Requests: 1')
    //     a1.click()
    //     this.server.respond()
    //     a1.innerHTML.should.equal('Requests: 2')
    // })
    //
    // it('event listeners can filter on target', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //
    //     var div1 = make('<div>' +
    //         '<div id="d1" hx-trigger="click from:body target:#d3" hx-get="/test">Requests: 0</div>' +
    //         '<div id="d2"></div>' +
    //         '<div id="d3"></div>' +
    //         '</div>')
    //     var div1 = byId('d1')
    //     var div2 = byId('d2')
    //     var div3 = byId('d3')
    //
    //     div1.innerHTML.should.equal('Requests: 0')
    //     document.body.click()
    //     this.server.respond()
    //     requests.should.equal(0)
    //
    //     div1.click()
    //     this.server.respond()
    //     requests.should.equal(0)
    //
    //     div2.click()
    //     this.server.respond()
    //     requests.should.equal(0)
    //
    //     div3.click()
    //     this.server.respond()
    //     requests.should.equal(1)
    // })
    //
    // it('throttle prevents multiple requests from happening', function(done) {
    //     var requests = 0
    //     var server = this.server
    //     server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     server.respondWith('GET', '/bar', 'bar')
    //     var div = make("<div hx-trigger='click throttle:10ms' hx-get='/test'></div>")
    //
    //     div.click()
    //     server.respond()
    //
    //     div.click()
    //     server.respond()
    //
    //     div.click()
    //     server.respond()
    //
    //     div.click()
    //     server.respond()
    //
    //     // should not have been replaced by click
    //     div.innerText.should.equal('Requests: 1')
    //
    //     setTimeout(function() {
    //         div.click()
    //         server.respond()
    //         div.innerText.should.equal('Requests: 2')
    //
    //         div.click()
    //         server.respond()
    //         div.innerText.should.equal('Requests: 2')
    //
    //         done()
    //     }, 50)
    // })
    //
    // it('A throttle of 0 does not prevent multiple requests from happening', function(done) {
    //     var requests = 0
    //     var server = this.server
    //     server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     server.respondWith('GET', '/bar', 'bar')
    //     var div = make(
    //         "<div hx-trigger='click throttle:0ms' hx-get='/test'></div>"
    //     )
    //
    //     div.click()
    //     server.respond()
    //     div.innerText.should.equal('Requests: 1')
    //
    //     div.click()
    //     server.respond()
    //     div.innerText.should.equal('Requests: 2')
    //
    //     div.click()
    //     server.respond()
    //     div.innerText.should.equal('Requests: 3')
    //
    //     div.click()
    //     server.respond()
    //     div.innerText.should.equal('Requests: 4')
    //
    //     done()
    // })
    //
    // it('delay delays the request', function(done) {
    //     var requests = 0
    //     var server = this.server
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     this.server.respondWith('GET', '/bar', 'bar')
    //     var div = make("<div hx-trigger='click delay:10ms' hx-get='/test'></div>")
    //
    //     div.click()
    //     this.server.respond()
    //
    //     div.click()
    //     this.server.respond()
    //
    //     div.click()
    //     this.server.respond()
    //
    //     div.click()
    //     this.server.respond()
    //     div.innerText.should.equal('')
    //
    //     setTimeout(function() {
    //         server.respond()
    //         div.innerText.should.equal('Requests: 1')
    //
    //         div.click()
    //         server.respond()
    //         div.innerText.should.equal('Requests: 1')
    //
    //         done()
    //     }, 50)
    // })
    //
    // it('A 0 delay does not delay the request', function(done) {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     this.server.respondWith('GET', '/bar', 'bar')
    //     var div = make(
    //         "<div hx-trigger='click delay:0ms' hx-get='/test'></div>"
    //     )
    //
    //     div.click()
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 1')
    //
    //     div.click()
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 2')
    //
    //     div.click()
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 3')
    //
    //     div.click()
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 4')
    //
    //     done()
    // })
    //
    // it('requests are queued with last one winning by default', function() {
    //     var requests = 0
    //     var server = this.server
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     this.server.respondWith('GET', '/bar', 'bar')
    //     var div = make("<div hx-trigger='click' hx-get='/test'></div>")
    //
    //     div.click()
    //     div.click()
    //     div.click()
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 1')
    //
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 2')
    //
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 2')
    // })
    //
    // it('queue:all queues all requests', function() {
    //     var requests = 0
    //     var server = this.server
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     this.server.respondWith('GET', '/bar', 'bar')
    //     var div = make("<div hx-trigger='click queue:all' hx-get='/test'></div>")
    //
    //     div.click()
    //     div.click()
    //     div.click()
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 1')
    //
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 2')
    //
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 3')
    // })
    //
    // it('queue:first queues first request', function() {
    //     var requests = 0
    //     var server = this.server
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     this.server.respondWith('GET', '/bar', 'bar')
    //     var div = make("<div hx-trigger='click queue:first' hx-get='/test'></div>")
    //
    //     div.click()
    //     div.click()
    //     div.click()
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 1')
    //
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 2')
    //
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 2')
    // })
    //
    // it('queue:none queues no requests', function() {
    //     var requests = 0
    //     var server = this.server
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     this.server.respondWith('GET', '/bar', 'bar')
    //     var div = make("<div hx-trigger='click queue:none' hx-get='/test'></div>")
    //
    //     div.click()
    //     div.click()
    //     div.click()
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 1')
    //
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 1')
    //
    //     this.server.respond()
    //     div.innerText.should.equal('Requests: 1')
    // })
    //
    // it('load event works w/ positive filters', function() {
    //     this.server.respondWith('GET', '/test', 'Loaded!')
    //     var div = make('<div hx-get="/test" hx-trigger="load[true]">Load Me!</div>')
    //     div.innerHTML.should.equal('Load Me!')
    //     this.server.respond()
    //     div.innerHTML.should.equal('Loaded!')
    // })
    //
    // it('load event works w/ negative filters', function() {
    //     this.server.respondWith('GET', '/test', 'Loaded!')
    //     var div = make('<div hx-get="/test" hx-trigger="load[false]">Load Me!</div>')
    //     div.innerHTML.should.equal('Load Me!')
    //     this.server.respond()
    //     div.innerHTML.should.equal('Load Me!')
    // })
    //
    // it('reveal event works on two elements', function() {
    //     this.server.respondWith('GET', '/test1', 'test 1')
    //     this.server.respondWith('GET', '/test2', 'test 2')
    //     var div = make('<div hx-get="/test1" hx-trigger="revealed"></div>')
    //     var div2 = make('<div hx-get="/test2" hx-trigger="revealed"></div>')
    //     div.innerHTML.should.equal('')
    //     div2.innerHTML.should.equal('')
    //     htmx.trigger(div, 'revealed')
    //     htmx.trigger(div2, 'revealed')
    //     this.server.respondAll()
    //     div.innerHTML.should.equal('test 1')
    //     div2.innerHTML.should.equal('test 2')
    // })
    //
    // it('scrolling triggers revealed event', function(done) {
    //     this.server.respondWith('GET', '/test', 'test')
    //     this.server.autoRespond = true
    //     this.server.autoRespondAfter = 0
    //     var div = make('<div hx-get="/test" hx-trigger="revealed"></div>')
    //     div.innerHTML.should.equal('')
    //     div.scrollIntoView({ block: 'end', behavior: htmx.config.scrollBehavior })
    //     htmx.trigger(document.body, 'scroll')
    //
    //     setTimeout(function() {
    //         div.innerHTML.should.equal('test')
    //         done()
    //     }, 250)
    // })
    //
    // if (/headlesschrome/i.test(navigator.userAgent)) {
    //     it('scrolling triggers intersect event', function(done) {
    //         // test only works reliably with playwright
    //         this.server.respondWith('GET', '/test', 'test')
    //         this.server.autoRespond = true
    //         this.server.autoRespondAfter = 0
    //         var div = make('<div hx-get="/test" hx-trigger="intersect"></div>')
    //         div.innerHTML.should.equal('')
    //         div.scrollIntoView({ block: 'end', behavior: htmx.config.scrollBehavior })
    //         htmx.trigger(document.body, 'scroll')
    //
    //         setTimeout(function() {
    //             div.innerHTML.should.equal('test')
    //             done()
    //         }, 250)
    //     })
    // }
    //
    // it('triggering revealed while component not yet inited still works', function(done) {
    //     this.server.respondWith('GET', '/test', 'test')
    //     var div = make('<div hx-get="/test" hx-trigger="revealed"></div>')
    //     var data = div['htmx-internal-data']
    //     delete data.initHash // simulate not inited or revealed yet
    //     div.removeAttribute('data-hx-revealed')
    //     var server1 = this.server
    //     div.innerHTML.should.equal('')
    //     div.scrollIntoView({ block: 'end', behavior: htmx.config.scrollBehavior })
    //     htmx.trigger(document.body, 'scroll')
    //     setTimeout(function() {
    //         server1.autoRespond = true
    //         server1.autoRespondAfter = 0
    //         htmx.process(div) // processing the div should also trigger revealed event now
    //         setTimeout(function() {
    //             div.innerHTML.should.equal('test')
    //             done()
    //         }, 10)
    //     }, 250)
    // })
    //
    // it('reveal event works when triggered by window', function() {
    //     this.server.respondWith('GET', '/test1', 'test 1')
    //     var div = make('<div hx-get="/test1" hx-trigger="revealed" style="position: fixed; top: 1px; left: 1px; border: 3px solid red">foo</div>')
    //     div.innerHTML.should.equal('foo')
    //     this.server.respondAll()
    //     div.innerHTML.should.equal('test 1')
    // })
    //
    // it('revealed can be paired w/ other events', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div = make('<div hx-get="/test" hx-trigger="revealed, click" style="position: fixed; top: 1px; left: 1px; border: 3px solid red">foo</div>')
    //     div.innerHTML.should.equal('foo')
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     div.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    // })
    //
    // it('revealed doesnt cause other events to trigger', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div = make('<div hx-get="/test" hx-trigger="revealedToTheWorld" style="position: fixed; top: 1px; left: 1px; border: 3px solid red">foo</div>')
    //     div.innerHTML.should.equal('foo')
    //     this.server.respondAll()
    //     div.innerHTML.should.equal('foo')
    // })
    //
    // it('fires the htmx:trigger event when an AJAX attribute is specified', function() {
    //     var param = 'foo'
    //     var handler = htmx.on('htmx:trigger', function(evt) {
    //         param = 'bar'
    //     })
    //     try {
    //         this.server.respondWith('GET', '/test1', 'test 1')
    //         var div = make('<button hx-get="/test1">Submit</button>')
    //         div.click()
    //         should.equal(param, 'bar')
    //     } finally {
    //         htmx.off('htmx:trigger', handler)
    //     }
    // })
    //
    // it('fires the htmx:trigger event when no AJAX attribute is specified', function() {
    //     var param = 'foo'
    //     var handler = htmx.on('htmx:trigger', function(evt) {
    //         param = 'bar'
    //     })
    //     try {
    //         var div = make('<button hx-trigger="click">Submit</button>')
    //         div.click()
    //         should.equal(param, 'bar')
    //     } finally {
    //         htmx.off('htmx:trigger', handler)
    //     }
    // })
    //
    // it('fires the htmx:trigger event for delayed triggers', function(done) {
    //     var param = 'foo'
    //     var handler = htmx.on('htmx:trigger', function(evt) {
    //         param = 'bar'
    //     })
    //     var div = make('<button hx-trigger="click delay:10ms">Submit</button>')
    //     div.click()
    //     setTimeout(function() {
    //         try {
    //             should.equal(param, 'bar')
    //             done()
    //         } finally {
    //             htmx.off('htmx:trigger', handler)
    //         }
    //     }, 50)
    // })
    //
    // it('fires the htmx:trigger event when the trigger is a load', function(done) {
    //     this.server.respondWith(
    //         'GET',
    //         '/test',
    //         '<div hx-trigger="load delay:50ms" hx-on::trigger="this.innerText = \'Done\'">Response</div>'
    //     )
    //
    //     var div = make('<div hx-get="/test">Submit</div>')
    //     div.click()
    //     this.server.respond()
    //     var response = div.children[0]
    //     response.innerText.should.equal('Response')
    //
    //     setTimeout(function() {
    //         try {
    //             response.innerText.should.equal('Done')
    //             done()
    //         } finally {
    //         }
    //     }, 100)
    // })
    //
    // it('filters support "this" reference to the current element', function() {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var form = make('<form hx-get="/test" hx-trigger="click[this.classList.contains(\'bar\')]">Not Called</form>')
    //     form.click()
    //     this.server.respond()
    //     form.innerHTML.should.equal('Not Called')
    //
    //     form.classList.add('bar')
    //     form.click()
    //     this.server.respond()
    //     form.innerHTML.should.equal('Called!')
    // })
    //
    // it('correctly handles CSS descendant combinators', function() {
    //     this.server.respondWith('GET', '/test', 'Clicked!')
    //
    //     var outer = make(`
    //     <div>
    //         <div id='outer'>
    //             <div id='first'>
    //                 <div id='inner'></div>
    //             </div>
    //             <div id='second' hx-get='/test' hx-trigger='click from:previous (#outer div)'>Unclicked.</div>
    //         </div>
    //         <div id='other' hx-get='/test' hx-trigger='click from:(div #inner)'>Unclicked.</div>
    //     </div>
    //     `)
    //
    //     var inner = byId('inner')
    //     var second = byId('second')
    //     var other = byId('other')
    //
    //     second.innerHTML.should.equal('Unclicked.')
    //     other.innerHTML.should.equal('Unclicked.')
    //
    //     inner.click()
    //     this.server.respond()
    //
    //     second.innerHTML.should.equal('Clicked!')
    //     other.innerHTML.should.equal('Clicked!')
    // })
    //
    // it('correctly handles CSS descendant combinators in modifier target', function() {
    //     this.server.respondWith('GET', '/test', 'Called')
    //
    //     make('<div class="d1"><a id="a1" class="a1">Click me</a><a id="a2" class="a2">Click me</a></div>')
    //     var div = make('<div hx-trigger="click from:body target:(.d1 .a2)" hx-get="/test">Not Called</div>')
    //
    //     byId('a1').click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Not Called')
    //
    //     byId('a2').click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Called')
    // })
    //
    // it('correctly handles CSS descendant combinators in modifier root', function() {
    //     this.server.respondWith('GET', '/test', 'Called')
    //     var errorEvent = null
    //     var handler = htmx.on('htmx:syntax:error', function(event) {
    //         errorEvent = event
    //     })
    //     var form = make('<div hx-trigger="intersect root:{form input}" hx-get="/test">Not Called</div>')
    //     try {
    //         var event = htmx._('makeEvent')('evt')
    //         form.dispatchEvent(event)
    //         should.equal(null, errorEvent)
    //     } finally {
    //         htmx.off('htmx:syntax:error', handler)
    //     }
    // })
    //
    // it('correctly handles intersect with modifier threshold', function() {
    //     this.server.respondWith('GET', '/test', 'Called')
    //     var errorEvent = null
    //     var handler = htmx.on('htmx:syntax:error', function(event) {
    //         errorEvent = event
    //     })
    //     var form = make('<div hx-trigger="intersect threshold:0.5" hx-get="/test">Not Called</div>')
    //     try {
    //         var event = htmx._('makeEvent')('evt')
    //         form.dispatchEvent(event)
    //         should.equal(null, errorEvent)
    //     } finally {
    //         htmx.off('htmx:syntax:error', handler)
    //     }
    // })
    //
    // it('issues error with invalid trigger spec', function() {
    //     this.server.respondWith('GET', '/test', 'Called')
    //     var errorEvent = null
    //     var handler = htmx.on('htmx:syntax:error', function(event) {
    //         errorEvent = event
    //     })
    //     var form = make('<div hx-trigger="intersect invalid:0.5" hx-get="/test">Not Called</div>')
    //     try {
    //         var event = htmx._('makeEvent')('evt')
    //         form.dispatchEvent(event)
    //         should.not.equal(null, errorEvent)
    //         should.not.equal(null, errorEvent.detail.source)
    //         console.log(errorEvent.detail.source)
    //     } finally {
    //         htmx.off('htmx:syntax:error', handler)
    //     }
    // })
    //
    // it('uses trigger specs cache if defined', function() {
    //     var initialCacheConfig = htmx.config.triggerSpecsCache
    //     htmx.config.triggerSpecsCache = {}
    //
    //     var specExamples = {
    //         'every 1s': [{ trigger: 'every', pollInterval: 1000 }],
    //         click: [{ trigger: 'click' }],
    //         customEvent: [{ trigger: 'customEvent' }],
    //         'event changed': [{ trigger: 'event', changed: true }],
    //         'event once': [{ trigger: 'event', once: true }],
    //         'event delay:1s': [{ trigger: 'event', delay: 1000 }],
    //         'event throttle:1s': [{ trigger: 'event', throttle: 1000 }],
    //         'event delay:1s, foo': [{ trigger: 'event', delay: 1000 }, { trigger: 'foo' }],
    //         'event throttle:1s, foo': [{ trigger: 'event', throttle: 1000 }, { trigger: 'foo' }],
    //         'event changed once delay:1s': [{ trigger: 'event', changed: true, once: true, delay: 1000 }],
    //         'event1,event2': [{ trigger: 'event1' }, { trigger: 'event2' }],
    //         'event1, event2': [{ trigger: 'event1' }, { trigger: 'event2' }],
    //         'event1 once, event2 changed': [{ trigger: 'event1', once: true }, { trigger: 'event2', changed: true }]
    //     }
    //
    //     for (var specString in specExamples) {
    //         var div = make("<div hx-trigger='" + specString + "'></div>")
    //         var spec = htmx._('getTriggerSpecs')(div)
    //         spec.should.deep.equal(specExamples[specString], 'Found : ' + JSON.stringify(spec) + ', expected : ' + JSON.stringify(specExamples[specString]) + ' for spec: ' + specString)
    //     }
    //
    //     Object.keys(htmx.config.triggerSpecsCache).length.should.greaterThan(0)
    //     Object.keys(htmx.config.triggerSpecsCache).length.should.equal(Object.keys(specExamples).length)
    //
    //     htmx.config.triggerSpecsCache = initialCacheConfig
    // })
    //
    // it('correctly reuses trigger specs from the cache if defined', function() {
    //     var initialCacheConfig = htmx.config.triggerSpecsCache
    //     htmx.config.triggerSpecsCache = {}
    //
    //     var triggerStr = 'event changed once delay:1s'
    //     var expectedSpec = [{ trigger: 'event', changed: true, once: true, delay: 1000 }]
    //
    //     var div = make("<div hx-trigger='event changed once delay:1s'></div>")
    //     var spec = htmx._('getTriggerSpecs')(div)
    //     spec.should.deep.equal(expectedSpec, 'Found : ' + JSON.stringify(spec) + ', expected : ' + JSON.stringify(expectedSpec) + ' for spec: ' + triggerStr)
    //     spec.push('This should be carried to further identical specs thanks to the cache')
    //
    //     var div2 = make("<div hx-trigger='event changed once delay:1s'></div>")
    //     var spec2 = htmx._('getTriggerSpecs')(div2)
    //     spec2.should.deep.equal(spec, 'Found : ' + JSON.stringify(spec) + ', expected : ' + JSON.stringify(spec2) + ' for cached spec: ' + triggerStr)
    //
    //     Object.keys(htmx.config.triggerSpecsCache).length.should.equal(1)
    //
    //     htmx.config.triggerSpecsCache = initialCacheConfig
    // })
    //
    // it('handles spaces at the end of trigger specs', function() {
    //     var requests = 0
    //     this.server.respondWith('GET', '/test', function(xhr) {
    //         requests++
    //         xhr.respond(200, {}, 'Requests: ' + requests)
    //     })
    //     var div = make('<div hx-trigger="load , click consume " hx-get="/test">Requests: 0</div>')
    //     div.innerHTML.should.equal('Requests: 0')
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 1')
    //     div.click()
    //     this.server.respond()
    //     div.innerHTML.should.equal('Requests: 2')
    // })
    //
    // it('Removing polling trigger and processing node removes timeout', function(complete) {
    //     this.server.respondWith('GET', '/test', 'Called!')
    //     var div = make('<div hx-get="/test" hx-trigger="every 5ms">Not Called</div>')
    //     div.removeAttribute('hx-trigger')
    //     should.not.equal(div['htmx-internal-data'].timeout, undefined)
    //     htmx.process(div)
    //     should.equal(div['htmx-internal-data'].timeout, undefined)
    //     this.server.autoRespond = true
    //     this.server.autoRespondAfter = 0
    //     setTimeout(function() {
    //         div.innerHTML.should.equal('Not Called')
    //         delete window.foo
    //         complete()
    //     }, 30)
    // })
})
