cascader.spec.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. import {
  2. createTest,
  3. createVue,
  4. destroyVM,
  5. waitImmediate,
  6. wait,
  7. triggerEvent
  8. } from '../util';
  9. import Cascader from 'packages/cascader';
  10. const options = [{
  11. value: 'zhejiang',
  12. label: 'Zhejiang',
  13. children: [{
  14. value: 'hangzhou',
  15. label: 'Hangzhou',
  16. children: [{
  17. value: 'xihu',
  18. label: 'West Lake'
  19. }, {
  20. value: 'binjiang',
  21. label: 'Bin Jiang'
  22. }]
  23. }, {
  24. value: 'ningbo',
  25. label: 'NingBo',
  26. children: [{
  27. value: 'jiangbei',
  28. label: 'Jiang Bei'
  29. }, {
  30. value: 'jiangdong',
  31. label: 'Jiang Dong',
  32. disabled: true
  33. }]
  34. }]
  35. }, {
  36. value: 'jiangsu',
  37. label: 'Jiangsu',
  38. disabled: true,
  39. children: [{
  40. value: 'nanjing',
  41. label: 'Nanjing',
  42. children: [{
  43. value: 'zhonghuamen',
  44. label: 'Zhong Hua Men'
  45. }]
  46. }]
  47. }];
  48. const getMenus = el => el.querySelectorAll('.el-cascader-menu');
  49. const getOptions = (el, menuIndex) => getMenus(el)[menuIndex].querySelectorAll('.el-cascader-node');
  50. const selectedValue = ['zhejiang', 'hangzhou', 'xihu'];
  51. const getCloseButton = el => el.querySelectorAll('i.el-tag__close');
  52. describe('Cascader', () => {
  53. let vm;
  54. afterEach(() => {
  55. destroyVM(vm);
  56. });
  57. it('create', () => {
  58. vm = createTest(Cascader, true);
  59. expect(vm.$el).to.exist;
  60. });
  61. it('toggle dropdown visible', async() => {
  62. vm = createTest(Cascader, true);
  63. expect(vm.$refs.popper.style.display).to.equal('none');
  64. vm.$el.click();
  65. await waitImmediate();
  66. expect(vm.$refs.popper.style.display).to.includes('');
  67. vm.$el.click();
  68. await wait(500);
  69. expect(vm.$refs.popper.style.display).to.includes('none');
  70. });
  71. it('expand and check', async() => {
  72. vm = createTest({
  73. template: `
  74. <el-cascader
  75. ref="cascader"
  76. v-model="value"
  77. :options="options"></el-cascader>
  78. `,
  79. data() {
  80. return {
  81. value: [],
  82. options
  83. };
  84. }
  85. }, true);
  86. const { body } = document;
  87. const expandHandler = sinon.spy();
  88. const changeHandler = sinon.spy();
  89. vm.$refs.cascader.$on('expand-change', expandHandler);
  90. vm.$refs.cascader.$on('change', changeHandler);
  91. getOptions(body, 0)[0].click();
  92. await waitImmediate();
  93. expect(expandHandler.calledOnceWith(['zhejiang'])).to.be.true;
  94. getOptions(body, 1)[0].click();
  95. await waitImmediate();
  96. const checkedOption = getOptions(body, 2)[0];
  97. checkedOption.click();
  98. await waitImmediate();
  99. expect(changeHandler.calledOnceWith(selectedValue)).to.be.true;
  100. expect(vm.value).to.deep.equal(selectedValue);
  101. expect(checkedOption.querySelector('i.el-icon-check')).to.exist;
  102. expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake');
  103. });
  104. it('disabled', async() => {
  105. vm = createTest(Cascader, {
  106. disabled: true
  107. }, true);
  108. expect(vm.$el.className).to.includes('is-disabled');
  109. vm.$el.click();
  110. await waitImmediate();
  111. expect(vm.$refs.popper.style.display).to.includes('none');
  112. });
  113. it('with default value', async() => {
  114. vm = createVue({
  115. template: `
  116. <el-cascader
  117. v-model="value"
  118. :options="options"></el-cascader>
  119. `,
  120. data() {
  121. return {
  122. value: selectedValue,
  123. options
  124. };
  125. }
  126. }, true);
  127. const el = vm.$el;
  128. await waitImmediate();
  129. expect(getMenus(el).length).to.equal(3);
  130. expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check');
  131. expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake');
  132. });
  133. it('async set selected value', async() => {
  134. vm = createVue({
  135. template: `
  136. <el-cascader
  137. v-model="value"
  138. :options="options"></el-cascader>
  139. `,
  140. data() {
  141. return {
  142. value: [],
  143. options
  144. };
  145. }
  146. }, true);
  147. const el = vm.$el;
  148. vm.value = selectedValue;
  149. await waitImmediate();
  150. expect(getMenus(el).length).to.equal(3);
  151. expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check');
  152. expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake');
  153. });
  154. it('default value with async options', async() => {
  155. vm = createVue({
  156. template: `
  157. <el-cascader
  158. v-model="value"
  159. :options="options"></el-cascader>
  160. `,
  161. data() {
  162. return {
  163. value: selectedValue,
  164. options: []
  165. };
  166. }
  167. }, true);
  168. const el = vm.$el;
  169. vm.options = options;
  170. await waitImmediate();
  171. expect(getMenus(el).length).to.equal(3);
  172. expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check');
  173. expect(vm.$el.querySelector('input').value).to.equal('Zhejiang / Hangzhou / West Lake');
  174. });
  175. it('clearable', async() => {
  176. vm = createVue({
  177. template: `
  178. <el-cascader
  179. v-model="value"
  180. :options="options"
  181. clearable></el-cascader>
  182. `,
  183. data() {
  184. return {
  185. value: selectedValue,
  186. options
  187. };
  188. }
  189. }, true);
  190. triggerEvent(vm.$el, 'mouseenter');
  191. await waitImmediate();
  192. const closeBtn = vm.$el.querySelector('i.el-input__icon');
  193. expect(closeBtn).to.exist;
  194. closeBtn.click();
  195. await waitImmediate();
  196. expect(vm.value).to.deep.equal([]);
  197. });
  198. it('show last level label', async() => {
  199. vm = createVue({
  200. template: `
  201. <el-cascader
  202. v-model="value"
  203. :options="options"
  204. :show-all-levels="false"></el-cascader>
  205. `,
  206. data() {
  207. return {
  208. value: selectedValue,
  209. options
  210. };
  211. }
  212. }, true);
  213. const el = vm.$el;
  214. await waitImmediate();
  215. expect(getMenus(el).length).to.equal(3);
  216. expect(getOptions(el, 2)[0].querySelector('i').className).to.includes('el-icon-check');
  217. expect(vm.$el.querySelector('input').value).to.equal('West Lake');
  218. });
  219. it('multiple mode', async() => {
  220. vm = createVue({
  221. template: `
  222. <el-cascader
  223. v-model="value"
  224. :options="options"
  225. :disabled="disabled"
  226. :props="props"></el-cascader>
  227. `,
  228. data() {
  229. return {
  230. value: [],
  231. options,
  232. disabled: false,
  233. props: {
  234. multiple: true
  235. }
  236. };
  237. }
  238. }, true);
  239. getOptions(document.body, 0)[0].querySelector('.el-checkbox input').click();
  240. await waitImmediate();
  241. expect(vm.value.length).to.equal(3);
  242. expect(getCloseButton(vm.$el).length).to.equal(3);
  243. const tags = vm.$el.querySelectorAll('.el-tag');
  244. const closeBtn = tags[0].querySelector('.el-tag__close');
  245. expect(tags.length).to.equal(3);
  246. expect(closeBtn).to.exist;
  247. closeBtn.click();
  248. await waitImmediate();
  249. expect(vm.value.length).to.equal(2);
  250. expect(vm.$el.querySelectorAll('.el-tag').length).to.equal(2);
  251. vm.disabled = true;
  252. await waitImmediate();
  253. expect(getCloseButton(vm.$el).length).to.equal(0);
  254. });
  255. it('clearable in multiple mode', async() => {
  256. vm = createVue({
  257. template: `
  258. <el-cascader
  259. v-model="value"
  260. :options="options"
  261. :props="props"
  262. clearable></el-cascader>
  263. `,
  264. data() {
  265. return {
  266. value: [],
  267. options,
  268. props: {
  269. multiple: true,
  270. emitPath: false
  271. }
  272. };
  273. }
  274. }, true);
  275. vm.value = ['xihu', 'binjiang', 'jiangbei', 'jiangdong'];
  276. await waitImmediate();
  277. expect(getOptions(document.body, 0)[0].querySelector('.el-checkbox.is-checked')).to.exist;
  278. triggerEvent(vm.$el, 'mouseenter');
  279. await waitImmediate();
  280. const closeBtn = vm.$el.querySelector('i.el-input__icon');
  281. expect(closeBtn).to.exist;
  282. closeBtn.click();
  283. await waitImmediate();
  284. expect(vm.value.length).to.equal(1);
  285. });
  286. it('collapse tags', async() => {
  287. vm = createVue({
  288. template: `
  289. <el-cascader
  290. v-model="value"
  291. :options="options"
  292. :props="props"
  293. collapse-tags></el-cascader>
  294. `,
  295. data() {
  296. return {
  297. value: ['xihu', 'binjiang', 'jiangbei', 'jiangdong'],
  298. options,
  299. props: {
  300. multiple: true,
  301. emitPath: false
  302. }
  303. };
  304. }
  305. }, true);
  306. await waitImmediate();
  307. const tags = vm.$el.querySelectorAll('.el-tag');
  308. expect(tags.length).to.equal(2);
  309. expect(tags[0].querySelector('.el-tag__close')).to.exist;
  310. expect(tags[1].querySelector('.el-tag__close')).to.be.null;
  311. tags[0].querySelector('.el-tag__close').click();
  312. expect(tags[1].textContent).to.equal('+ 3');
  313. await waitImmediate();
  314. expect(vm.value.length).to.equal(3);
  315. vm.$el.querySelector('.el-tag .el-tag__close').click();
  316. await waitImmediate();
  317. vm.$el.querySelector('.el-tag .el-tag__close').click();
  318. await waitImmediate();
  319. expect(vm.$el.querySelector('.el-tag')).to.exist;
  320. // disabled tag can not be closed
  321. expect(vm.$el.querySelector('.el-tag .el-tag__close')).to.be.null;
  322. });
  323. it('filterable', async() => {
  324. vm = createVue({
  325. template: `
  326. <el-cascader
  327. v-model="value"
  328. :options="options"
  329. filterable></el-cascader>
  330. `,
  331. data() {
  332. return {
  333. value: [],
  334. options
  335. };
  336. }
  337. }, true);
  338. const el = vm.$el;
  339. const { body } = document;
  340. const input = el.querySelector('input');
  341. el.click();
  342. await waitImmediate();
  343. input.value = 'Zhejiang';
  344. triggerEvent(input, 'input');
  345. await wait(300);
  346. expect(body.querySelector('.el-cascader__suggestion-list')).to.exist;
  347. expect(body.querySelectorAll('.el-cascader__suggestion-item').length).to.equal(3);
  348. body.querySelectorAll('.el-cascader__suggestion-item')[0].click();
  349. await waitImmediate();
  350. expect(vm.value).to.deep.equal(selectedValue);
  351. });
  352. it('filter method', async() => {
  353. vm = createVue({
  354. template: `
  355. <el-cascader
  356. v-model="value"
  357. :options="options"
  358. :filter-method="filterMethod"
  359. filterable></el-cascader>
  360. `,
  361. data() {
  362. return {
  363. value: [],
  364. options
  365. };
  366. },
  367. methods: {
  368. filterMethod(node, keyword) {
  369. const { text, path } = node;
  370. return text.includes(keyword) || path.includes(keyword);
  371. }
  372. }
  373. }, true);
  374. const el = vm.$el;
  375. const { body } = document;
  376. const input = el.querySelector('input');
  377. el.click();
  378. await waitImmediate();
  379. input.value = 'Zhejiang';
  380. triggerEvent(input, 'input');
  381. await wait(300);
  382. expect(body.querySelectorAll('.el-cascader__suggestion-item').length).to.equal(3);
  383. input.value = 'xihu';
  384. triggerEvent(input, 'input');
  385. await wait(300);
  386. expect(body.querySelector('.el-cascader__suggestion-item').textContent).to.equal('Zhejiang / Hangzhou / West Lake');
  387. });
  388. });