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