import hbs from 'htmlbars-inline-precompile'; import wait from 'ember-test-helpers/wait'; import {describe, it} from 'mocha'; import {expect} from 'chai'; import {run} from '@ember/runloop'; import {setupComponentTest} from 'ember-mocha'; import {task, timeout} from 'ember-concurrency'; describe('Integration: Component: gh-task-button', function () { setupComponentTest('gh-task-button', { integration: true }); it('renders', function () { // sets button text using positional param this.render(hbs`{{gh-task-button "Test"}}`); expect(this.$('button')).to.exist; expect(this.$('button')).to.contain('Test'); expect(this.$('button')).to.have.prop('disabled', false); this.render(hbs`{{gh-task-button class="testing"}}`); expect(this.$('button')).to.have.class('testing'); // default button text is "Save" expect(this.$('button')).to.contain('Save'); // passes disabled attr this.render(hbs`{{gh-task-button disabled=true buttonText="Test"}}`); expect(this.$('button')).to.have.prop('disabled', true); // allows button text to be set via hash param expect(this.$('button')).to.contain('Test'); // passes type attr this.render(hbs`{{gh-task-button type="submit"}}`); expect(this.$('button')).to.have.attr('type', 'submit'); // passes tabindex attr this.render(hbs`{{gh-task-button tabindex="-1"}}`); expect(this.$('button')).to.have.attr('tabindex', '-1'); }); it('shows spinner whilst running', function () { this.set('myTask', task(function* () { yield timeout(50); })); this.render(hbs`{{gh-task-button task=myTask}}`); this.get('myTask').perform(); run.later(this, function () { expect(this.$('button')).to.have.descendants('svg'); }, 20); return wait(); }); it('shows running text when passed whilst running', function () { this.set('myTask', task(function* () { yield timeout(50); })); this.render(hbs`{{gh-task-button task=myTask runningText="Running"}}`); this.get('myTask').perform(); run.later(this, function () { expect(this.$('button')).to.have.descendants('svg'); expect(this.$('button')).to.contain('Running'); }, 20); return wait(); }); it('appears disabled whilst running', function () { this.set('myTask', task(function* () { yield timeout(50); })); this.render(hbs`{{gh-task-button task=myTask}}`); expect(this.$('button'), 'initial class').to.not.have.class('appear-disabled'); this.get('myTask').perform(); run.later(this, function () { expect(this.$('button'), 'running class').to.have.class('appear-disabled'); }, 20); run.later(this, function () { expect(this.$('button'), 'ended class').to.not.have.class('appear-disabled'); }, 100); return wait(); }); it('shows success on success', function () { this.set('myTask', task(function* () { yield timeout(50); return true; })); this.render(hbs`{{gh-task-button task=myTask}}`); this.get('myTask').perform(); run.later(this, function () { expect(this.$('button')).to.have.class('gh-btn-green'); expect(this.$('button')).to.contain('Saved'); }, 100); return wait(); }); it('assigns specified success class on success', function () { this.set('myTask', task(function* () { yield timeout(50); return true; })); this.render(hbs`{{gh-task-button task=myTask successClass="im-a-success"}}`); this.get('myTask').perform(); run.later(this, function () { expect(this.$('button')).to.not.have.class('gh-btn-green'); expect(this.$('button')).to.have.class('im-a-success'); expect(this.$('button')).to.contain('Saved'); }, 100); return wait(); }); it('shows failure when task errors', function () { this.set('myTask', task(function* () { try { yield timeout(50); throw new ReferenceError('test error'); } catch (error) { // noop, prevent mocha triggering unhandled error assert } })); this.render(hbs`{{gh-task-button task=myTask}}`); this.get('myTask').perform(); run.later(this, function () { expect(this.$('button')).to.have.class('gh-btn-red'); expect(this.$('button')).to.contain('Retry'); }, 100); return wait(); }); it('shows failure on falsy response', function () { this.set('myTask', task(function* () { yield timeout(50); return false; })); this.render(hbs`{{gh-task-button task=myTask}}`); this.get('myTask').perform(); run.later(this, function () { expect(this.$('button')).to.have.class('gh-btn-red'); expect(this.$('button')).to.contain('Retry'); }, 100); return wait(); }); it('assigns specified failure class on failure', function () { this.set('myTask', task(function* () { yield timeout(50); return false; })); this.render(hbs`{{gh-task-button task=myTask failureClass="im-a-failure"}}`); this.get('myTask').perform(); run.later(this, function () { expect(this.$('button')).to.not.have.class('gh-btn-red'); expect(this.$('button')).to.have.class('im-a-failure'); expect(this.$('button')).to.contain('Retry'); }, 100); return wait(); }); it('performs task on click', function () { let taskCount = 0; this.set('myTask', task(function* () { yield timeout(50); taskCount = taskCount + 1; })); this.render(hbs`{{gh-task-button task=myTask}}`); this.$('button').click(); return wait().then(() => { expect(taskCount, 'taskCount').to.equal(1); }); }); it.skip('keeps button size when showing spinner', function () { this.set('myTask', task(function* () { yield timeout(50); })); this.render(hbs`{{gh-task-button task=myTask}}`); let width = this.$('button').width(); let height = this.$('button').height(); expect(this.$('button')).to.not.have.attr('style'); this.get('myTask').perform(); run.later(this, function () { // we can't test exact width/height because Chrome/Firefox use different rounding methods // expect(this.$('button')).to.have.attr('style', `width: ${width}px; height: ${height}px;`); let [widthInt] = width.toString().split('.'); let [heightInt] = height.toString().split('.'); expect(this.$('button').attr('style')).to.have.string(`width: ${widthInt}`); expect(this.$('button').attr('style')).to.have.string(`height: ${heightInt}`); }, 20); run.later(this, function () { // chai-jquery test doesn't work because Firefox outputs blank string // expect(this.$('button')).to.not.have.attr('style'); expect(this.$('button').attr('style')).to.be.blank; }, 100); return wait(); }); });