github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/tests/integration/components/stepper-input-test.js (about) 1 import { 2 find, 3 render, 4 settled, 5 triggerEvent, 6 waitUntil, 7 } from '@ember/test-helpers'; 8 import { module, test } from 'qunit'; 9 import { setupRenderingTest } from 'ember-qunit'; 10 import hbs from 'htmlbars-inline-precompile'; 11 import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit'; 12 import sinon from 'sinon'; 13 import { create } from 'ember-cli-page-object'; 14 import stepperInput from 'nomad-ui/tests/pages/components/stepper-input'; 15 16 const StepperInput = create(stepperInput()); 17 const valueChange = () => { 18 const initial = StepperInput.input.value; 19 return () => StepperInput.input.value !== initial; 20 }; 21 22 module('Integration | Component | stepper input', function (hooks) { 23 setupRenderingTest(hooks); 24 25 const commonProperties = () => ({ 26 min: 0, 27 max: 10, 28 value: 5, 29 label: 'Stepper', 30 classVariant: 'is-primary', 31 disabled: false, 32 onChange: sinon.spy(), 33 }); 34 35 const commonTemplate = hbs` 36 <StepperInput 37 @debounce=50 38 @min={{min}} 39 @max={{max}} 40 @value={{value}} 41 @class={{classVariant}} 42 @disabled={{disabled}} 43 @onChange={{onChange}}> 44 {{label}} 45 </StepperInput> 46 `; 47 48 test('basic appearance includes a label, an input, and two buttons', async function (assert) { 49 assert.expect(7); 50 51 this.setProperties(commonProperties()); 52 53 await render(commonTemplate); 54 55 assert.equal(StepperInput.label, this.label); 56 assert.equal(StepperInput.input.value, this.value); 57 assert.ok(StepperInput.decrement.isPresent); 58 assert.ok(StepperInput.increment.isPresent); 59 assert.ok( 60 StepperInput.decrement.classNames.split(' ').includes(this.classVariant) 61 ); 62 assert.ok( 63 StepperInput.increment.classNames.split(' ').includes(this.classVariant) 64 ); 65 66 await componentA11yAudit(this.element, assert); 67 }); 68 69 test('clicking the increment and decrement buttons immediately changes the shown value in the input but debounces the onUpdate call', async function (assert) { 70 this.setProperties(commonProperties()); 71 72 const baseValue = this.value; 73 74 await render(commonTemplate); 75 76 StepperInput.increment.click(); 77 await waitUntil(valueChange()); 78 assert.equal(StepperInput.input.value, baseValue + 1); 79 assert.notOk(this.onChange.called); 80 81 StepperInput.decrement.click(); 82 await waitUntil(valueChange()); 83 assert.equal(StepperInput.input.value, baseValue); 84 assert.notOk(this.onChange.called); 85 86 StepperInput.decrement.click(); 87 await waitUntil(valueChange()); 88 assert.equal(StepperInput.input.value, baseValue - 1); 89 assert.notOk(this.onChange.called); 90 91 await settled(); 92 assert.ok(this.onChange.calledWith(baseValue - 1)); 93 }); 94 95 test('the increment button is disabled when the internal value is the max value', async function (assert) { 96 this.setProperties(commonProperties()); 97 this.set('value', this.max); 98 99 await render(commonTemplate); 100 101 assert.ok(StepperInput.increment.isDisabled); 102 }); 103 104 test('the decrement button is disabled when the internal value is the min value', async function (assert) { 105 this.setProperties(commonProperties()); 106 this.set('value', this.min); 107 108 await render(commonTemplate); 109 110 assert.ok(StepperInput.decrement.isDisabled); 111 }); 112 113 test('the text input does not call the onUpdate function on oninput', async function (assert) { 114 this.setProperties(commonProperties()); 115 const newValue = 8; 116 117 await render(commonTemplate); 118 119 const input = find('[data-test-stepper-input]'); 120 121 input.value = newValue; 122 assert.equal(StepperInput.input.value, newValue); 123 assert.notOk(this.onChange.called); 124 125 await triggerEvent(input, 'input'); 126 assert.equal(StepperInput.input.value, newValue); 127 assert.notOk(this.onChange.called); 128 129 await triggerEvent(input, 'change'); 130 assert.equal(StepperInput.input.value, newValue); 131 assert.ok(this.onChange.calledWith(newValue)); 132 }); 133 134 test('the text input does call the onUpdate function on onchange', async function (assert) { 135 this.setProperties(commonProperties()); 136 const newValue = 8; 137 138 await render(commonTemplate); 139 140 await StepperInput.input.fill(newValue); 141 142 await settled(); 143 assert.equal(StepperInput.input.value, newValue); 144 assert.ok(this.onChange.calledWith(newValue)); 145 }); 146 147 test('text input limits input to the bounds of the min/max range', async function (assert) { 148 this.setProperties(commonProperties()); 149 let newValue = this.max + 1; 150 151 await render(commonTemplate); 152 153 await StepperInput.input.fill(newValue); 154 await settled(); 155 156 assert.equal(StepperInput.input.value, this.max); 157 assert.ok(this.onChange.calledWith(this.max)); 158 159 newValue = this.min - 1; 160 161 await StepperInput.input.fill(newValue); 162 await settled(); 163 164 assert.equal(StepperInput.input.value, this.min); 165 assert.ok(this.onChange.calledWith(this.min)); 166 }); 167 168 test('pressing ESC in the text input reverts the text value back to the current value', async function (assert) { 169 this.setProperties(commonProperties()); 170 const newValue = 8; 171 172 await render(commonTemplate); 173 174 const input = find('[data-test-stepper-input]'); 175 176 input.value = newValue; 177 assert.equal(StepperInput.input.value, newValue); 178 179 await StepperInput.input.esc(); 180 assert.equal(StepperInput.input.value, this.value); 181 }); 182 183 test('clicking the label focuses in the input', async function (assert) { 184 this.setProperties(commonProperties()); 185 186 await render(commonTemplate); 187 await StepperInput.clickLabel(); 188 189 const input = find('[data-test-stepper-input]'); 190 assert.equal(document.activeElement, input); 191 }); 192 193 test('focusing the input selects the input value', async function (assert) { 194 this.setProperties(commonProperties()); 195 196 await render(commonTemplate); 197 await StepperInput.input.focus(); 198 199 assert.equal( 200 window.getSelection().toString().trim(), 201 this.value.toString() 202 ); 203 }); 204 205 test('entering a fractional value floors the value', async function (assert) { 206 this.setProperties(commonProperties()); 207 const newValue = 3.14159; 208 209 await render(commonTemplate); 210 211 await StepperInput.input.fill(newValue); 212 213 await settled(); 214 assert.equal(StepperInput.input.value, Math.floor(newValue)); 215 assert.ok(this.onChange.calledWith(Math.floor(newValue))); 216 }); 217 218 test('entering an invalid value reverts the value', async function (assert) { 219 this.setProperties(commonProperties()); 220 const newValue = 'NaN'; 221 222 await render(commonTemplate); 223 224 await StepperInput.input.fill(newValue); 225 226 await settled(); 227 assert.equal(StepperInput.input.value, this.value); 228 assert.notOk(this.onChange.called); 229 }); 230 });