/* eslint-env jasmine */ import Stepper from './index' describe('Stepper', () => { let fixture beforeAll(() => { const fixureNode = document.createElement('div') fixureNode.setAttribute('id', 'fixture') document.body.appendChild(fixureNode) fixture = document.getElementById('fixture') }) afterEach(() => { fixture.innerHTML = '' }) describe('constructor', () => { it('should create a stepper', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) expect(stepperNode.classList.contains('linear')).toBe(true) expect(stepper._steps.length).toEqual(2) expect(stepperNode['bsStepper']).toEqual(stepper) expect(document.querySelector('.step').classList.contains('active')).toBe(true) expect(document.getElementById('trigger1').getAttribute('aria-selected')).toEqual('true') expect(document.getElementById('trigger2').getAttribute('aria-selected')).toEqual('false') expect(stepper.options).toEqual({ linear: true, animation: false, selectors: { steps: '.step', trigger: '.step-trigger', stepper: '.bs-stepper' } }) }) it('should do nothing if there is no step', () => { fixture.innerHTML = '
' const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) expect(stepperNode.classList.contains('linear')).toBe(true) expect(stepper._steps.length).toEqual(0) expect(stepperNode['bsStepper']).toEqual(stepper) }) it('should create a non linear stepper', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode, { linear: false }) expect(stepperNode.classList.contains('linear')).toBe(false) expect(stepper._steps.length).toEqual(2) expect(document.querySelector('.step').classList.contains('active')).toBe(true) expect(stepperNode['bsStepper']).toEqual(stepper) expect(stepper._clickStepLinearListener).toBeUndefined() expect(stepper._clickStepNonLinearListener).toBeTruthy() expect(stepper.options).toEqual({ linear: false, animation: false, selectors: { steps: '.step', trigger: '.step-trigger', stepper: '.bs-stepper' } }) }) it('should go to the next step when user click on a step for non linear stepper', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode, { linear: false }) const trigger2 = document.querySelector('#trigger2') trigger2.click() expect(document.querySelector('#test1').classList.contains('active')).toBe(false) expect(document.querySelector('#test2').classList.contains('active')).toBe(true) expect(document.getElementById('trigger1').getAttribute('aria-selected')).toEqual('false') expect(document.getElementById('trigger2').getAttribute('aria-selected')).toEqual('true') expect(stepper._currentIndex).toEqual(1) }) it('should call preventDefault when user click on a step for linear stepper', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) const trigger2 = document.querySelector('#trigger2') trigger2.removeAttribute('disabled') const clickEvent = document.createEvent('Event') clickEvent.initEvent('click', true, true) spyOn(clickEvent, 'preventDefault') trigger2.dispatchEvent(clickEvent) expect(clickEvent.preventDefault).toHaveBeenCalled() expect(stepper._currentIndex).toEqual(0) }) it('should create a stepper with fade animation', done => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode, { animation: true }) setTimeout(() => { expect(stepper.options).toEqual({ linear: true, animation: true, selectors: { steps: '.step', trigger: '.step-trigger', stepper: '.bs-stepper' } }) expect(document.querySelector('#test1').classList.contains('fade')).toBe(true) expect(document.querySelector('#test2').classList.contains('fade')).toBe(true) done() }, 10) }) it('should add event listeners on triggers', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const trigger1 = document.querySelector('#trigger1') const trigger2 = document.querySelector('#trigger2') spyOn(trigger1, 'addEventListener') spyOn(trigger2, 'addEventListener') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) expect(trigger1.addEventListener).toHaveBeenCalled() expect(trigger2.addEventListener).toHaveBeenCalled() expect(stepperNode['bsStepper']).toEqual(stepper) }) it('should allow css selector configuration', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode, { selectors: { steps: '.custom-step', trigger: '.custom-step-trigger', stepper: '.custom-bs-stepper' } }) expect(stepper.options).toEqual({ linear: true, animation: false, selectors: { steps: '.custom-step', trigger: '.custom-step-trigger', stepper: '.custom-bs-stepper' } }) }) }) describe('next', () => { it('should go to the next step', done => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) stepperNode.addEventListener('show.bs-stepper', function (event) { expect(event.detail.indexStep).toEqual(1) expect(event.detail.to).toEqual(1) expect(event.detail.from).toEqual(0) }) stepperNode.addEventListener('shown.bs-stepper', function (event) { expect(event.detail.indexStep).toEqual(1) expect(event.detail.to).toEqual(1) expect(event.detail.from).toEqual(0) expect(document.querySelector('#test1').classList.contains('active')).toBe(false) expect(document.querySelector('#test2').classList.contains('active')).toBe(true) done() }) stepper.next() }) it('should go to the next step with css selector configuration', done => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode, { selectors: { steps: '.custom-step', trigger: '.custom-step-trigger', stepper: '.custom-bs-stepper' } }) expect(stepper.options).toEqual({ linear: true, animation: false, selectors: { steps: '.custom-step', trigger: '.custom-step-trigger', stepper: '.custom-bs-stepper' } }) stepperNode.addEventListener('show.bs-stepper', function (event) { expect(event.detail.indexStep).toEqual(1) }) stepperNode.addEventListener('shown.bs-stepper', function (event) { expect(event.detail.indexStep).toEqual(1) expect(document.querySelector('#test1').classList.contains('active')).toBe(false) expect(document.querySelector('#test2').classList.contains('active')).toBe(true) done() }) stepper.next() }) it('should not go to the next step if the show event is default prevented', done => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) const listeners = { show (event) { event.preventDefault() expect(event.detail.indexStep).toEqual(1) setTimeout(() => { expect(listeners.shown).not.toHaveBeenCalled() expect(stepper._currentIndex).toEqual(0) done() }, 10) }, shown () { console.warn('shown called but it should not be the case') } } spyOn(listeners, 'shown') stepperNode.addEventListener('show.bs-stepper', listeners.show) stepperNode.addEventListener('shown.bs-stepper', listeners.shown) stepper.next() }) it('should stay at the end if we call next', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) stepper.next() stepper.next() expect(document.querySelector('#test1').classList.contains('active')).toBe(false) expect(document.querySelector('#test2').classList.contains('active')).toBe(true) }) it('should keep block class on previous steps for vertical stepper without fade', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) stepper.next() expect(document.querySelector('#test2').classList.contains('active')).toBe(true) expect(document.querySelector('#test2').classList.contains('dstepper-block')).toBe(true) }) }) describe('previous', () => { it('should return to the previous step', done => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) const test1 = document.querySelector('#test1') const test2 = document.querySelector('#test2') stepper.next() expect(test1.classList.contains('active')).toBe(false) expect(test2.classList.contains('active')).toBe(true) stepperNode.addEventListener('show.bs-stepper', function (event) { expect(event.detail.indexStep).toEqual(0) expect(event.detail.to).toEqual(0) expect(event.detail.from).toEqual(1) }) stepperNode.addEventListener('shown.bs-stepper', function (event) { expect(event.detail.indexStep).toEqual(0) expect(event.detail.to).toEqual(0) expect(event.detail.from).toEqual(1) expect(test1.classList.contains('active')).toBe(true) expect(test2.classList.contains('active')).toBe(false) done() }) stepper.previous() }) it('should stay at the first step if previous called', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const test1 = document.querySelector('#test1') const test2 = document.querySelector('#test2') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) stepper.previous() expect(test1.classList.contains('active')).toBe(true) expect(test2.classList.contains('active')).toBe(false) }) }) describe('to', () => { it('should go to the step number', done => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) const test1 = document.querySelector('#test1') const test2 = document.querySelector('#test2') stepperNode.addEventListener('show.bs-stepper', event => { expect(event.detail.indexStep).toEqual(1) expect(event.detail.to).toEqual(1) expect(event.detail.from).toEqual(0) }) stepperNode.addEventListener('shown.bs-stepper', event => { expect(event.detail.indexStep).toEqual(1) expect(event.detail.to).toEqual(1) expect(event.detail.from).toEqual(0) expect(test1.classList.contains('active')).toBe(false) expect(test2.classList.contains('active')).toBe(true) done() }) stepper.to(2) }) it('should handle wrong inputs', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) const test1 = document.querySelector('#test1') const test2 = document.querySelector('#test2') const test3 = document.querySelector('#test3') stepper.to(-5) expect(test1.classList.contains('active')).toBe(true) expect(test2.classList.contains('active')).toBe(false) expect(test3.classList.contains('active')).toBe(false) stepper.to(2) expect(test1.classList.contains('active')).toBe(false) expect(test2.classList.contains('active')).toBe(true) expect(test3.classList.contains('active')).toBe(false) stepper.to(stepper._steps.length + 1) expect(test1.classList.contains('active')).toBe(true) expect(test2.classList.contains('active')).toBe(false) expect(test3.classList.contains('active')).toBe(false) }) }) describe('reset', () => { it('should return to the first step', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) const test1 = document.querySelector('#test1') const test2 = document.querySelector('#test2') stepper.next() expect(test1.classList.contains('active')).toBe(false) expect(test2.classList.contains('active')).toBe(true) stepper.reset() expect(test1.classList.contains('active')).toBe(true) expect(test2.classList.contains('active')).toBe(false) }) }) describe('destroy', () => { it('should clear properties', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode) expect(stepperNode['bsStepper']).toEqual(stepper) expect(stepper._element).toEqual(stepperNode) expect(stepper._currentIndex).toEqual(0) expect(stepper._steps.length).toEqual(2) expect(stepper._stepsContents.length).toEqual(2) expect(stepper._clickStepLinearListener).toBeTruthy() expect(stepper._clickStepNonLinearListener).toBeUndefined() stepper.destroy() expect(stepperNode.bsStepper).toBeUndefined() expect(stepper._element).toBeUndefined() expect(stepper._currentIndex).toBeUndefined() expect(stepper._steps).toBeUndefined() expect(stepper._stepsContents).toBeUndefined() expect(stepper._clickStepLinearListener).toBeUndefined() expect(stepper._clickStepNonLinearListener).toBeUndefined() }) it('should remove event listeners on triggers', () => { fixture.innerHTML = [ '
', '
', ' ', '
', '
', ' ', '
', '
1
', '
2
', '
' ].join('') const stepperNode = document.getElementById('myStepper') const stepper = new Stepper(stepperNode, { linear: false }) const trigger1 = document.querySelector('#trigger1') const trigger2 = document.querySelector('#trigger2') spyOn(trigger1, 'removeEventListener') spyOn(trigger2, 'removeEventListener') stepper.destroy() expect(trigger1.removeEventListener).toHaveBeenCalled() expect(trigger2.removeEventListener).toHaveBeenCalled() }) }) })