input.spec.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. import { createVue, destroyVM, triggerEvent, wait, waitImmediate } from '../util';
  2. describe('Input', () => {
  3. let vm;
  4. afterEach(() => {
  5. destroyVM(vm);
  6. });
  7. it('create', async() => {
  8. vm = createVue({
  9. template: `
  10. <el-input
  11. :minlength="3"
  12. :maxlength="5"
  13. placeholder="请输入内容"
  14. @focus="handleFocus"
  15. :value="input">
  16. </el-input>
  17. `,
  18. data() {
  19. return {
  20. input: 'input',
  21. inputFocus: false
  22. };
  23. },
  24. methods: {
  25. handleFocus() {
  26. this.inputFocus = true;
  27. }
  28. }
  29. }, true);
  30. let inputElm = vm.$el.querySelector('input');
  31. inputElm.focus();
  32. expect(vm.inputFocus).to.be.true;
  33. expect(inputElm.getAttribute('placeholder')).to.equal('请输入内容');
  34. expect(inputElm.value).to.equal('input');
  35. expect(inputElm.getAttribute('minlength')).to.equal('3');
  36. expect(inputElm.getAttribute('maxlength')).to.equal('5');
  37. vm.input = 'text';
  38. await waitImmediate();
  39. expect(inputElm.value).to.equal('text');
  40. });
  41. it('default to empty', () => {
  42. vm = createVue({
  43. template: '<el-input/>'
  44. }, true);
  45. let inputElm = vm.$el.querySelector('input');
  46. expect(inputElm.value).to.equal('');
  47. });
  48. it('disabled', () => {
  49. vm = createVue({
  50. template: `
  51. <el-input disabled>
  52. </el-input>
  53. `
  54. }, true);
  55. expect(vm.$el.querySelector('input').getAttribute('disabled')).to.ok;
  56. });
  57. it('suffixIcon', () => {
  58. vm = createVue({
  59. template: `
  60. <el-input suffix-icon="time"></el-input>
  61. `
  62. }, true);
  63. var icon = vm.$el.querySelector('.el-input__icon');
  64. expect(icon).to.be.exist;
  65. });
  66. it('prefixIcon', () => {
  67. vm = createVue({
  68. template: `
  69. <el-input prefix-icon="time"></el-input>
  70. `
  71. }, true);
  72. var icon = vm.$el.querySelector('.el-input__icon');
  73. expect(icon).to.be.exist;
  74. });
  75. it('size', () => {
  76. vm = createVue({
  77. template: `
  78. <el-input size="large">
  79. </el-input>
  80. `
  81. }, true);
  82. expect(vm.$el.classList.contains('el-input--large')).to.true;
  83. });
  84. it('type', () => {
  85. vm = createVue({
  86. template: `
  87. <el-input type="textarea">
  88. </el-input>
  89. `
  90. }, true);
  91. expect(vm.$el.classList.contains('el-textarea')).to.true;
  92. });
  93. it('rows', () => {
  94. vm = createVue({
  95. template: `
  96. <el-input type="textarea" :rows="3">
  97. </el-input>
  98. `
  99. }, true);
  100. expect(vm.$el.querySelector('.el-textarea__inner').getAttribute('rows')).to.be.equal('3');
  101. });
  102. // Github issue #2836
  103. it('resize', async() => {
  104. vm = createVue({
  105. template: `
  106. <div>
  107. <el-input type="textarea" :resize="resize"></el-input>
  108. </div>
  109. `,
  110. data: {
  111. resize: 'none'
  112. }
  113. }, true);
  114. await waitImmediate();
  115. expect(vm.$el.querySelector('.el-textarea__inner').style.resize).to.be.equal(vm.resize);
  116. vm.resize = 'horizontal';
  117. await waitImmediate();
  118. expect(vm.$el.querySelector('.el-textarea__inner').style.resize).to.be.equal(vm.resize);
  119. });
  120. it('autosize', async() => {
  121. vm = createVue({
  122. template: `
  123. <div>
  124. <el-input
  125. ref="limitSize"
  126. type="textarea"
  127. :autosize="{minRows: 3, maxRows: 5}"
  128. v-model="textareaValue"
  129. >
  130. </el-input>
  131. <el-input
  132. ref="limitlessSize"
  133. type="textarea"
  134. autosize
  135. v-model="textareaValue"
  136. >
  137. </el-input>
  138. </div>
  139. `,
  140. data() {
  141. return {
  142. textareaValue: 'sda\ndasd\nddasdsda\ndasd\nddasdsda\ndasd\nddasdsda\ndasd\nddasd'
  143. };
  144. }
  145. }, true);
  146. var limitSizeInput = vm.$refs.limitSize;
  147. var limitlessSizeInput = vm.$refs.limitlessSize;
  148. expect(limitSizeInput.textareaStyle.height).to.be.equal('117px');
  149. expect(limitlessSizeInput.textareaStyle.height).to.be.equal('201px');
  150. vm.textareaValue = '';
  151. await wait();
  152. expect(limitSizeInput.textareaStyle.height).to.be.equal('75px');
  153. expect(limitlessSizeInput.textareaStyle.height).to.be.equal('33px');
  154. });
  155. it('focus', async() => {
  156. vm = createVue({
  157. template: `
  158. <el-input ref="input">
  159. </el-input>
  160. `
  161. }, true);
  162. const spy = sinon.spy();
  163. vm.$refs.input.$on('focus', spy);
  164. vm.$refs.input.focus();
  165. await waitImmediate();
  166. expect(spy.calledOnce).to.be.true;
  167. });
  168. it('Input contains Select and append slot', async() => {
  169. vm = createVue({
  170. template: `
  171. <el-input v-model="value" clearable class="input-with-select" ref="input">
  172. <el-select v-model="select" slot="prepend" placeholder="请选择">
  173. <el-option label="餐厅名" value="1"></el-option>
  174. <el-option label="订单号" value="2"></el-option>
  175. <el-option label="用户电话" value="3"></el-option>
  176. </el-select>
  177. <el-button slot="append" icon="el-icon-search"></el-button>
  178. </el-input>
  179. `,
  180. data() {
  181. return {
  182. value: '1234',
  183. select: '1'
  184. };
  185. }
  186. }, true);
  187. vm.$refs.input.hovering = true;
  188. await wait();
  189. const suffixEl = document.querySelector('.input-with-select > .el-input__suffix');
  190. expect(suffixEl).to.not.be.null;
  191. expect(suffixEl.style.transform).to.not.be.empty;
  192. });
  193. it('validateEvent', async() => {
  194. const spy = sinon.spy();
  195. vm = createVue({
  196. template: `
  197. <el-form :model="model" :rules="rules">
  198. <el-form-item prop="input">
  199. <el-input v-model="model.input" :validate-event="false">
  200. </el-input>
  201. </el-form-item>
  202. </el-form>
  203. `,
  204. data() {
  205. const validator = (rule, value, callback) => {
  206. spy();
  207. callback();
  208. };
  209. return {
  210. model: {
  211. input: ''
  212. },
  213. rules: {
  214. input: [
  215. { validator }
  216. ]
  217. }
  218. };
  219. }
  220. }, true);
  221. vm.model.input = '123';
  222. await waitImmediate();
  223. expect(spy.called).to.be.false;
  224. });
  225. describe('Input Events', () => {
  226. it('event:focus & blur', async() => {
  227. vm = createVue({
  228. template: `
  229. <el-input
  230. ref="input"
  231. placeholder="请输入内容"
  232. value="input">
  233. </el-input>
  234. `
  235. }, true);
  236. const spyFocus = sinon.spy();
  237. const spyBlur = sinon.spy();
  238. vm.$refs.input.$on('focus', spyFocus);
  239. vm.$refs.input.$on('blur', spyBlur);
  240. vm.$el.querySelector('input').focus();
  241. vm.$el.querySelector('input').blur();
  242. await waitImmediate();
  243. expect(spyFocus.calledOnce).to.be.true;
  244. expect(spyBlur.calledOnce).to.be.true;
  245. });
  246. it('event:change', async() => {
  247. // NOTE: should be same as native's change behavior
  248. vm = createVue({
  249. template: `
  250. <el-input
  251. ref="input"
  252. placeholder="请输入内容"
  253. :value="input">
  254. </el-input>
  255. `,
  256. data() {
  257. return {
  258. input: 'a'
  259. };
  260. }
  261. }, true);
  262. const inputElm = vm.$el.querySelector('input');
  263. const simulateEvent = (text, event) => {
  264. inputElm.value = text;
  265. inputElm.dispatchEvent(new Event(event));
  266. };
  267. const spy = sinon.spy();
  268. vm.$refs.input.$on('change', spy);
  269. // simplified test, component should emit change when native does
  270. simulateEvent('1', 'input');
  271. simulateEvent('2', 'change');
  272. await waitImmediate();
  273. expect(spy.calledWith('2')).to.be.true;
  274. expect(spy.calledOnce).to.be.true;
  275. });
  276. it('event:clear', async() => {
  277. vm = createVue({
  278. template: `
  279. <el-input
  280. ref="input"
  281. placeholder="请输入内容"
  282. clearable
  283. :value="input">
  284. </el-input>
  285. `,
  286. data() {
  287. return {
  288. input: 'a'
  289. };
  290. }
  291. }, true);
  292. const spyClear = sinon.spy();
  293. const inputElm = vm.$el.querySelector('input');
  294. // focus to show clear button
  295. inputElm.focus();
  296. vm.$refs.input.$on('clear', spyClear);
  297. await waitImmediate();
  298. vm.$el.querySelector('.el-input__clear').click();
  299. await waitImmediate();
  300. expect(spyClear.calledOnce).to.be.true;
  301. });
  302. it('event:input', async() => {
  303. vm = createVue({
  304. template: `
  305. <el-input
  306. ref="input"
  307. placeholder="请输入内容"
  308. clearable
  309. :value="input">
  310. </el-input>
  311. `,
  312. data() {
  313. return {
  314. input: 'a'
  315. };
  316. }
  317. }, true);
  318. const spy = sinon.spy();
  319. vm.$refs.input.$on('input', spy);
  320. const nativeInput = vm.$refs.input.$el.querySelector('input');
  321. nativeInput.value = '1';
  322. triggerEvent(nativeInput, 'compositionstart');
  323. triggerEvent(nativeInput, 'input');
  324. await waitImmediate();
  325. nativeInput.value = '2';
  326. triggerEvent(nativeInput, 'compositionupdate');
  327. triggerEvent(nativeInput, 'input');
  328. await waitImmediate();
  329. triggerEvent(nativeInput, 'compositionend');
  330. await waitImmediate();
  331. // input event does not fire during composition
  332. expect(spy.calledOnce).to.be.true;
  333. // native input value is controlled
  334. expect(vm.input).to.equal('a');
  335. expect(nativeInput.value).to.equal('a');
  336. });
  337. });
  338. describe('Input Methods', () => {
  339. it('method:select', async() => {
  340. const testContent = 'test';
  341. vm = createVue({
  342. template: `
  343. <el-input
  344. ref="inputComp"
  345. value="${testContent}"
  346. />
  347. `
  348. }, true);
  349. expect(vm.$refs.inputComp.$refs.input.selectionStart).to.equal(testContent.length);
  350. expect(vm.$refs.inputComp.$refs.input.selectionEnd).to.equal(testContent.length);
  351. vm.$refs.inputComp.select();
  352. await waitImmediate();
  353. expect(vm.$refs.inputComp.$refs.input.selectionStart).to.equal(0);
  354. expect(vm.$refs.inputComp.$refs.input.selectionEnd).to.equal(testContent.length);
  355. });
  356. });
  357. it('sets value on textarea / input type change', async() => {
  358. vm = createVue({
  359. template: `
  360. <el-input :type="type" v-model="val" />
  361. `,
  362. data() {
  363. return {
  364. type: 'text',
  365. val: '123'
  366. };
  367. }
  368. }, true);
  369. expect(vm.$el.querySelector('input').value).to.equal('123');
  370. vm.type = 'textarea';
  371. await waitImmediate();
  372. expect(vm.$el.querySelector('textarea').value).to.equal('123');
  373. vm.type = 'password';
  374. await waitImmediate();
  375. expect(vm.$el.querySelector('input').value).to.equal('123');
  376. });
  377. });