cascader.spec.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. import { createVue, destroyVM, triggerEvent, triggerClick } from '../util';
  2. describe('Cascader', () => {
  3. let vm;
  4. afterEach(() => {
  5. destroyVM(vm);
  6. });
  7. it('create', done => {
  8. vm = createVue({
  9. template: `
  10. <el-cascader
  11. ref="cascader"
  12. placeholder="请选择"
  13. :options="options"
  14. clearable
  15. v-model="selectedOptions"
  16. ></el-cascader>
  17. `,
  18. data() {
  19. return {
  20. options: [{
  21. value: 'zhejiang',
  22. label: 'Zhejiang',
  23. children: [{
  24. value: 'hangzhou',
  25. label: 'Hangzhou',
  26. children: [{
  27. value: 'xihu',
  28. label: 'West Lake'
  29. }]
  30. }, {
  31. value: 'ningbo',
  32. label: 'NingBo',
  33. children: [{
  34. value: 'jiangbei',
  35. label: 'Jiang Bei'
  36. }]
  37. }]
  38. }, {
  39. value: 'jiangsu',
  40. label: 'Jiangsu',
  41. children: [{
  42. value: 'nanjing',
  43. label: 'Nanjing',
  44. children: [{
  45. value: 'zhonghuamen',
  46. label: 'Zhong Hua Men'
  47. }]
  48. }]
  49. }],
  50. selectedOptions: []
  51. };
  52. }
  53. }, true);
  54. expect(vm.$el).to.be.exist;
  55. vm.$el.click();
  56. setTimeout(_ => {
  57. expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
  58. const menu = vm.$refs.cascader.menu;
  59. const menuElm = menu.$el;
  60. const item1 = menuElm.querySelector('.el-cascader-menu__item');
  61. item1.click();
  62. menu.$nextTick(_ => {
  63. expect(menuElm.children.length).to.be.equal(3); // two menus and an arrow
  64. expect(item1.classList.contains('is-active')).to.be.true;
  65. const item2 = menuElm.children[2].querySelector('.el-cascader-menu__item');
  66. item2.click();
  67. menu.$nextTick(_ => {
  68. expect(menuElm.children.length).to.be.equal(4);
  69. expect(item2.classList.contains('is-active')).to.be.true;
  70. const item3 = menuElm.children[3].querySelector('.el-cascader-menu__item');
  71. item3.click();
  72. setTimeout(_ => {
  73. expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
  74. expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
  75. expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
  76. expect(vm.selectedOptions[2]).to.be.equal('xihu');
  77. triggerEvent(vm.$refs.cascader.$el, 'mouseenter');
  78. vm.$nextTick(_ => {
  79. vm.$refs.cascader.$el.querySelector('.el-cascader__clearIcon').click();
  80. vm.$nextTick(_ => {
  81. expect(vm.selectedOptions.length).to.be.equal(0);
  82. done();
  83. });
  84. });
  85. }, 500);
  86. });
  87. });
  88. }, 300);
  89. });
  90. // Github issue #3470
  91. it('should work with zero', done => {
  92. vm = createVue({
  93. template: `
  94. <el-cascader
  95. ref="cascader"
  96. placeholder="请选择"
  97. :options="options"
  98. clearable
  99. v-model="selectedOptions"
  100. ></el-cascader>
  101. `,
  102. data() {
  103. return {
  104. options: [{
  105. value: 'zhejiang',
  106. label: 'Zhejiang',
  107. children: [{
  108. value: 0,
  109. label: 'Hangzhou',
  110. children: [{
  111. value: 'xihu',
  112. label: 'West Lake'
  113. }]
  114. }, {
  115. value: 'ningbo',
  116. label: 'NingBo',
  117. children: [{
  118. value: 'jiangbei',
  119. label: 'Jiang Bei'
  120. }]
  121. }]
  122. }, {
  123. value: 'jiangsu',
  124. label: 'Jiangsu',
  125. children: [{
  126. value: 'nanjing',
  127. label: 'Nanjing',
  128. children: [{
  129. value: 'zhonghuamen',
  130. label: 'Zhong Hua Men'
  131. }]
  132. }]
  133. }],
  134. selectedOptions: []
  135. };
  136. }
  137. }, true);
  138. expect(vm.$el).to.be.exist;
  139. vm.$el.click();
  140. setTimeout(_ => {
  141. expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
  142. const menu = vm.$refs.cascader.menu;
  143. const menuElm = menu.$el;
  144. const item1 = menuElm.querySelector('.el-cascader-menu__item');
  145. item1.click();
  146. menu.$nextTick(_ => {
  147. expect(menuElm.children.length).to.be.equal(3);
  148. expect(item1.classList.contains('is-active')).to.be.true;
  149. const item2 = menuElm.children[2].querySelector('.el-cascader-menu__item');
  150. item2.click();
  151. menu.$nextTick(_ => {
  152. expect(menuElm.children.length).to.be.equal(4);
  153. expect(item2.classList.contains('is-active')).to.be.true;
  154. const item3 = menuElm.children[3].querySelector('.el-cascader-menu__item');
  155. item3.click();
  156. setTimeout(_ => {
  157. expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
  158. expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
  159. expect(vm.selectedOptions[1]).to.be.equal(0);
  160. expect(vm.selectedOptions[2]).to.be.equal('xihu');
  161. triggerEvent(vm.$refs.cascader.$el, 'mouseenter');
  162. vm.$nextTick(_ => {
  163. vm.$refs.cascader.$el.querySelector('.el-cascader__clearIcon').click();
  164. vm.$nextTick(_ => {
  165. expect(vm.selectedOptions.length).to.be.equal(0);
  166. done();
  167. });
  168. });
  169. }, 500);
  170. });
  171. });
  172. }, 300);
  173. });
  174. it('not allow clearable', done => {
  175. vm = createVue({
  176. template: `
  177. <el-cascader
  178. ref="cascader"
  179. placeholder="请选择"
  180. :options="options"
  181. :clearable="false"
  182. v-model="selectedOptions"
  183. ></el-cascader>
  184. `,
  185. data() {
  186. return {
  187. options: [{
  188. value: 'zhejiang',
  189. label: 'Zhejiang',
  190. children: [{
  191. value: 'hangzhou',
  192. label: 'Hangzhou',
  193. children: [{
  194. value: 'xihu',
  195. label: 'West Lake'
  196. }]
  197. }, {
  198. value: 'ningbo',
  199. label: 'NingBo',
  200. children: [{
  201. value: 'jiangbei',
  202. label: 'Jiang Bei'
  203. }]
  204. }]
  205. }, {
  206. value: 'jiangsu',
  207. label: 'Jiangsu',
  208. children: [{
  209. value: 'nanjing',
  210. label: 'Nanjing',
  211. children: [{
  212. value: 'zhonghuamen',
  213. label: 'Zhong Hua Men'
  214. }]
  215. }]
  216. }],
  217. selectedOptions: []
  218. };
  219. }
  220. }, true);
  221. expect(vm.$el).to.be.exist;
  222. triggerEvent(vm.$refs.cascader.$el, 'mouseenter');
  223. vm.$nextTick(_ => {
  224. expect(vm.$refs.cascader.$el.querySelector('.el-cascader__clearIcon')).to.not.exist;
  225. done();
  226. });
  227. });
  228. it('disabled options', done => {
  229. vm = createVue({
  230. template: `
  231. <el-cascader
  232. ref="cascader"
  233. placeholder="请选择"
  234. :options="options"
  235. v-model="selectedOptions"
  236. ></el-cascader>
  237. `,
  238. data() {
  239. return {
  240. options: [{
  241. value: 'zhejiang',
  242. label: 'Zhejiang',
  243. disabled: true,
  244. children: [{
  245. value: 'hangzhou',
  246. label: 'Hangzhou',
  247. children: [{
  248. value: 'xihu',
  249. label: 'West Lake'
  250. }]
  251. }, {
  252. value: 'ningbo',
  253. label: 'NingBo',
  254. children: [{
  255. value: 'jiangbei',
  256. label: 'Jiang Bei'
  257. }]
  258. }]
  259. }, {
  260. value: 'jiangsu',
  261. label: 'Jiangsu',
  262. children: [{
  263. value: 'nanjing',
  264. label: 'Nanjing',
  265. children: [{
  266. value: 'zhonghuamen',
  267. label: 'Zhong Hua Men'
  268. }]
  269. }]
  270. }],
  271. selectedOptions: []
  272. };
  273. }
  274. }, true);
  275. expect(vm.$el).to.be.exist;
  276. vm.$el.click();
  277. setTimeout(_ => {
  278. expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
  279. const menu = vm.$refs.cascader.menu;
  280. const menuElm = menu.$el;
  281. const item1 = menuElm.querySelector('.el-cascader-menu__item');
  282. item1.click();
  283. menu.$nextTick(_ => {
  284. expect(menuElm.children.length).to.be.equal(2);
  285. expect(item1.classList.contains('is-active')).to.be.false;
  286. done();
  287. });
  288. }, 300);
  289. });
  290. it('default value', done => {
  291. vm = createVue({
  292. template: `
  293. <el-cascader
  294. ref="cascader"
  295. placeholder="请选择"
  296. :options="options"
  297. v-model="selectedOptions"
  298. ></el-cascader>
  299. `,
  300. data() {
  301. return {
  302. options: [{
  303. value: 'zhejiang',
  304. label: 'Zhejiang',
  305. children: [{
  306. value: 'hangzhou',
  307. label: 'Hangzhou',
  308. children: [{
  309. value: 'xihu',
  310. label: 'West Lake'
  311. }]
  312. }, {
  313. value: 'ningbo',
  314. label: 'NingBo',
  315. children: [{
  316. value: 'jiangbei',
  317. label: 'Jiang Bei'
  318. }]
  319. }]
  320. }, {
  321. value: 'jiangsu',
  322. label: 'Jiangsu',
  323. children: [{
  324. value: 'nanjing',
  325. label: 'Nanjing',
  326. children: [{
  327. value: 'zhonghuamen',
  328. label: 'Zhong Hua Men'
  329. }]
  330. }]
  331. }],
  332. selectedOptions: ['zhejiang', 'hangzhou', 'xihu']
  333. };
  334. }
  335. }, true);
  336. expect(vm.$el).to.be.exist;
  337. vm.$el.click();
  338. setTimeout(_ => {
  339. expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
  340. const menu = vm.$refs.cascader.menu;
  341. const menuElm = menu.$el;
  342. const item1 = menuElm.children[1].querySelector('.el-cascader-menu__item');
  343. const item2 = menuElm.children[2].querySelector('.el-cascader-menu__item');
  344. const item3 = menuElm.children[3].querySelector('.el-cascader-menu__item');
  345. expect(menuElm.children.length).to.be.equal(4);
  346. expect(item1.classList.contains('is-active')).to.be.true;
  347. expect(item2.classList.contains('is-active')).to.be.true;
  348. expect(item3.classList.contains('is-active')).to.be.true;
  349. triggerClick(document, 'mouseup');
  350. setTimeout(_ => {
  351. expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
  352. done();
  353. }, 500);
  354. }, 300);
  355. });
  356. it('expand by hover', done => {
  357. vm = createVue({
  358. template: `
  359. <el-cascader
  360. ref="cascader"
  361. placeholder="请选择"
  362. :options="options"
  363. expand-trigger="hover"
  364. v-model="selectedOptions"
  365. ></el-cascader>
  366. `,
  367. data() {
  368. return {
  369. options: [{
  370. value: 'zhejiang',
  371. label: 'Zhejiang',
  372. children: [{
  373. value: 'hangzhou',
  374. label: 'Hangzhou',
  375. children: [{
  376. value: 'xihu',
  377. label: 'West Lake'
  378. }]
  379. }, {
  380. value: 'ningbo',
  381. label: 'NingBo',
  382. children: [{
  383. value: 'jiangbei',
  384. label: 'Jiang Bei'
  385. }]
  386. }]
  387. }, {
  388. value: 'jiangsu',
  389. label: 'Jiangsu',
  390. children: [{
  391. value: 'nanjing',
  392. label: 'Nanjing',
  393. children: [{
  394. value: 'zhonghuamen',
  395. label: 'Zhong Hua Men'
  396. }]
  397. }]
  398. }],
  399. selectedOptions: []
  400. };
  401. }
  402. }, true);
  403. expect(vm.$el).to.be.exist;
  404. vm.$el.click();
  405. setTimeout(_ => {
  406. expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
  407. const menu = vm.$refs.cascader.menu;
  408. const menuElm = menu.$el;
  409. const item1 = menuElm.querySelector('.el-cascader-menu__item');
  410. triggerEvent(item1, 'mouseenter');
  411. menu.$nextTick(_ => {
  412. expect(menuElm.children.length).to.be.equal(3);
  413. expect(item1.classList.contains('is-active')).to.be.true;
  414. const item2 = menuElm.children[2].querySelector('.el-cascader-menu__item');
  415. triggerEvent(item2, 'mouseenter');
  416. menu.$nextTick(_ => {
  417. expect(menuElm.children.length).to.be.equal(4);
  418. expect(item2.classList.contains('is-active')).to.be.true;
  419. const item3 = menuElm.children[3].querySelector('.el-cascader-menu__item');
  420. item3.click();
  421. setTimeout(_ => {
  422. expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
  423. expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
  424. expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
  425. expect(vm.selectedOptions[2]).to.be.equal('xihu');
  426. done();
  427. }, 500);
  428. });
  429. });
  430. }, 300);
  431. });
  432. it('change on select', done => {
  433. vm = createVue({
  434. template: `
  435. <el-cascader
  436. ref="cascader"
  437. placeholder="请选择"
  438. :options="options"
  439. change-on-select
  440. v-model="selectedOptions"
  441. ></el-cascader>
  442. `,
  443. data() {
  444. return {
  445. options: [{
  446. value: 'zhejiang',
  447. label: 'Zhejiang',
  448. children: [{
  449. value: 'hangzhou',
  450. label: 'Hangzhou',
  451. children: [{
  452. value: 'xihu',
  453. label: 'West Lake'
  454. }]
  455. }, {
  456. value: 'ningbo',
  457. label: 'NingBo',
  458. children: [{
  459. value: 'jiangbei',
  460. label: 'Jiang Bei'
  461. }]
  462. }]
  463. }, {
  464. value: 'jiangsu',
  465. label: 'Jiangsu',
  466. children: [{
  467. value: 'nanjing',
  468. label: 'Nanjing',
  469. children: [{
  470. value: 'zhonghuamen',
  471. label: 'Zhong Hua Men'
  472. }]
  473. }]
  474. }],
  475. selectedOptions: []
  476. };
  477. }
  478. }, true);
  479. expect(vm.$el).to.be.exist;
  480. vm.$el.click();
  481. setTimeout(_ => {
  482. expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
  483. const menu = vm.$refs.cascader.menu;
  484. const menuElm = menu.$el;
  485. const item1 = menuElm.querySelector('.el-cascader-menu__item');
  486. item1.click();
  487. menu.$nextTick(_ => {
  488. expect(menuElm.children.length).to.be.equal(3);
  489. expect(item1.classList.contains('is-active')).to.be.true;
  490. expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
  491. const item2 = menuElm.children[2].querySelector('.el-cascader-menu__item');
  492. item2.click();
  493. menu.$nextTick(_ => {
  494. expect(menuElm.children.length).to.be.equal(4);
  495. expect(item2.classList.contains('is-active')).to.be.true;
  496. expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
  497. const item3 = menuElm.children[3].querySelector('.el-cascader-menu__item');
  498. item3.click();
  499. setTimeout(_ => {
  500. expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
  501. expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
  502. expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
  503. expect(vm.selectedOptions[2]).to.be.equal('xihu');
  504. done();
  505. }, 500);
  506. });
  507. });
  508. }, 300);
  509. });
  510. it('filterable', done => {
  511. vm = createVue({
  512. template: `
  513. <el-cascader
  514. ref="cascader"
  515. placeholder="请选择"
  516. :options="options"
  517. filterable
  518. :debounce="0"
  519. v-model="selectedOptions"
  520. ></el-cascader>
  521. `,
  522. data() {
  523. return {
  524. options: [{
  525. value: 'zhejiang',
  526. label: 'Zhejiang',
  527. children: [{
  528. value: 'hangzhou',
  529. label: 'Hangzhou',
  530. children: [{
  531. value: 'xihu',
  532. label: 'West Lake'
  533. }]
  534. }, {
  535. value: 'ningbo',
  536. label: 'NingBo',
  537. children: [{
  538. value: 'jiangbei',
  539. label: 'Jiang Bei'
  540. }]
  541. }]
  542. }, {
  543. value: 'jiangsu',
  544. label: 'Jiangsu',
  545. children: [{
  546. value: 'nanjing',
  547. label: 'Nanjing',
  548. children: [{
  549. value: 'zhonghuamen',
  550. label: 'Zhong Hua Men'
  551. }]
  552. }]
  553. }],
  554. selectedOptions: []
  555. };
  556. }
  557. }, true);
  558. expect(vm.$el).to.be.exist;
  559. vm.$el.click();
  560. vm.$nextTick(_ => {
  561. vm.$refs.cascader.handleInputChange('z');
  562. setTimeout(_ => {
  563. expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
  564. const menu = vm.$refs.cascader.menu;
  565. const menuElm = menu.$el;
  566. const item1 = menuElm.querySelector('.el-cascader-menu__item');
  567. expect(menuElm.children.length).to.be.equal(2);
  568. expect(menuElm.children[1].children.length).to.be.equal(3);
  569. item1.click();
  570. setTimeout(_ => {
  571. expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
  572. expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
  573. expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
  574. expect(vm.selectedOptions[2]).to.be.equal('xihu');
  575. done();
  576. }, 500);
  577. }, 300);
  578. });
  579. });
  580. it('props', done => {
  581. vm = createVue({
  582. template: `
  583. <el-cascader
  584. ref="cascader"
  585. :options="options"
  586. :props="props"
  587. v-model="selectedOptions"
  588. ></el-cascader>
  589. `,
  590. data() {
  591. return {
  592. options: [{
  593. label: 'Zhejiang',
  594. cities: [{
  595. label: 'Hangzhou'
  596. }, {
  597. label: 'NingBo'
  598. }]
  599. }, {
  600. label: 'Jiangsu',
  601. cities: [{
  602. label: 'Nanjing'
  603. }]
  604. }],
  605. props: {
  606. value: 'label',
  607. children: 'cities'
  608. },
  609. selectedOptions: []
  610. };
  611. }
  612. }, true);
  613. vm.$el.click();
  614. setTimeout(_ => {
  615. expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
  616. const menu = vm.$refs.cascader.menu;
  617. const menuElm = menu.$el;
  618. let items = menuElm.querySelectorAll('.el-cascader-menu__item');
  619. expect(items.length).to.equal(2);
  620. items[0].click();
  621. setTimeout(_ => {
  622. items = menuElm.querySelectorAll('.el-cascader-menu__item');
  623. expect(items.length).to.equal(4);
  624. expect(items[items.length - 1].innerText).to.equal('NingBo');
  625. done();
  626. }, 100);
  627. }, 100);
  628. });
  629. it('show last level', done => {
  630. vm = createVue({
  631. template: `
  632. <el-cascader
  633. ref="cascader"
  634. :options="options"
  635. :show-all-levels="false"
  636. v-model="selectedOptions"
  637. ></el-cascader>
  638. `,
  639. data() {
  640. return {
  641. options: [{
  642. value: 'zhejiang',
  643. label: 'Zhejiang',
  644. children: [{
  645. value: 'hangzhou',
  646. label: 'Hangzhou',
  647. children: [{
  648. value: 'xihu',
  649. label: 'West Lake'
  650. }]
  651. }, {
  652. value: 'ningbo',
  653. label: 'NingBo',
  654. children: [{
  655. value: 'jiangbei',
  656. label: 'Jiang Bei'
  657. }]
  658. }]
  659. }, {
  660. value: 'jiangsu',
  661. label: 'Jiangsu',
  662. children: [{
  663. value: 'nanjing',
  664. label: 'Nanjing',
  665. children: [{
  666. value: 'zhonghuamen',
  667. label: 'Zhong Hua Men'
  668. }]
  669. }]
  670. }],
  671. selectedOptions: ['zhejiang', 'ningbo', 'jiangbei']
  672. };
  673. }
  674. }, true);
  675. setTimeout(_ => {
  676. const span = vm.$el.querySelector('.el-cascader__label');
  677. expect(span.innerText).to.equal('Jiang Bei');
  678. done();
  679. }, 100);
  680. });
  681. });