cascader.spec.js 11 KB

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