LockToTicksSpec.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. /*
  2. *************************
  3. Lock To Ticks Tests
  4. *************************
  5. Verify that the when lock_to_ticks is true, the selected values will be snapped to closest tick values
  6. */
  7. describe("Slider with lock_to_ticks: true tests", function() {
  8. var testSlider;
  9. it("Should set `options.lock_to_ticks` to false when `ticks[]` is not set", function() {
  10. testSlider = $('#testSlider1').slider({
  11. lock_to_ticks: true
  12. });
  13. var lockAttr = testSlider.slider('getAttribute', 'lock_to_ticks');
  14. expect(lockAttr).toBe(false);
  15. });
  16. it("Should set the slider value when `ticks[]` is not set", function() {
  17. testSlider = $('#testSlider1').slider({
  18. min: 0,
  19. max: 10,
  20. value: 1,
  21. lock_to_ticks: true
  22. });
  23. testSlider.slider('setValue', 5);
  24. var value = testSlider.slider('getValue');
  25. expect(value).toBe(5);
  26. });
  27. it("Should return a value (after calling `setAttribute()`)", function() {
  28. testSlider = $('#testSlider1').slider({
  29. min: 0,
  30. max: 10,
  31. value: 1,
  32. lock_to_ticks: true
  33. });
  34. // Try to lock to ticks when there are no ticks[]
  35. testSlider.slider('setAttribute', 'lock_to_ticks', true);
  36. testSlider.slider('setValue', 5);
  37. // Without proper checking, getValue() is going to return NaN in this case
  38. var value = testSlider.slider('getValue');
  39. expect(isNaN(value)).toBe(false);
  40. });
  41. it("Should snap to closest tick value (single)", function() {
  42. testSlider = $('#testSlider1').slider({
  43. value: 1,
  44. ticks: [1, 10, 50, 200, 500, 1000, 5000, 10000],
  45. lock_to_ticks: true
  46. });
  47. // Set a value that is not a tick
  48. testSlider.slider('setValue', 102);
  49. var value = testSlider.slider('getValue');
  50. expect(value).toBe(50);
  51. });
  52. it("Should snap to closest tick value (single, vertical)", function() {
  53. testSlider = $('#testSlider1').slider({
  54. value: 1,
  55. ticks: [1, 10, 50, 200, 500, 1000, 5000, 10000],
  56. lock_to_ticks: true,
  57. orientation: 'vertical'
  58. });
  59. //selecting values that are not inside tickes
  60. testSlider.slider('setValue', 102);
  61. //getting the actual values. They should be the closest values from ticks (which are 1 and 50 on this case)
  62. var value = testSlider.slider('getValue');
  63. expect(value).toBe(50);
  64. });
  65. it("Should snap to closest tick value (range)", function() {
  66. testSlider = $("#testSlider1").slider({
  67. value: [1, 10000],
  68. ticks: [1, 10, 50, 200, 500, 1000, 5000, 10000],
  69. lock_to_ticks: true
  70. });
  71. //selecting values that are not inside tickes
  72. testSlider.slider("setValue", [4, 102]);
  73. //getting the actual values. They should be the closest values from ticks (which are 1 and 50 on this case)
  74. var values = testSlider.slider("getValue");
  75. expect(values[0]).toBe(1);
  76. expect(values[1]).toBe(50);
  77. });
  78. it("Should snap to closest tick value (range, vertical)", function() {
  79. testSlider = $("#testSlider1").slider({
  80. value: [1, 10000],
  81. ticks: [1, 10, 50, 200, 500, 1000, 5000, 10000],
  82. lock_to_ticks: true,
  83. orientation: 'vertical'
  84. });
  85. //selecting values that are not inside tickes
  86. testSlider.slider("setValue", [4, 102]);
  87. //getting the actual values. They should be the closest values from ticks (which are 1 and 50 on this case)
  88. var values = testSlider.slider("getValue");
  89. expect(values[0]).toBe(1);
  90. expect(values[1]).toBe(50);
  91. });
  92. afterEach(function() {
  93. if(testSlider) {
  94. testSlider.slider('destroy');
  95. testSlider = null;
  96. }
  97. });
  98. });
  99. /**
  100. * The mouse navigation tests are based on the following slider properties:
  101. *
  102. * initial value: 3 or [3, 7]
  103. * ticks: [0, 3, 5, 7, 10]
  104. * step: 0.1
  105. *
  106. * When the values are in the range from 0 to 10 and the step is 0.1, every value
  107. * can be represented as 1% of the range. For example, 5.5 is 55% and 5.6 is 56%.
  108. * This makes it easier to test the behaviour of tick locking.
  109. *
  110. * The mouse clicks are based on a percentage that represents where the user clicked
  111. * on the slider (60% = 6.0). The percentage is then used to calculate the coordinates
  112. * for the mouse events (mousedown, mousemove, and mouseup).
  113. *
  114. * These tests are setup to test for all combinations of relevant slider configurations:
  115. * single/range, horizontal/vertical orientation, LTR/RTL, and ordered/reversed.
  116. * The tests also check that the handles have the correct positioning, which should
  117. * match the ticks that the handles lock to.
  118. *
  119. * The test data was carefully chosen based on following the test logic below.
  120. *
  121. * The test logic for sliders:
  122. * - Clicking to the left of the handle should not change its value
  123. * - Clicking to the left of the handle should change its value and lock to another tick
  124. * - Ditto for clicking to the right of the handle
  125. *
  126. * For range sliders, the same logic is applied except test both handle1 and handle2.
  127. */
  128. describe("`lock_to_ticks: true` mouse navigation test cases", function() {
  129. var initialValue = 3;
  130. var initialRangeValues = [3, 7];
  131. var tickValues = [0, 3, 5, 7, 10];
  132. // Quick lookup from value to index
  133. var tickIndexes = {0: 0, 3: 1, 5: 2, 7: 3, 10: 4};
  134. var stepValue = 0.1;
  135. var orientations = ['horizontal', 'vertical'];
  136. var reversed = [false, true];
  137. var sliderTypes = ['single', 'range'];
  138. var rtl = [false, true];
  139. var testCases = [];
  140. var mouseEventArguments;
  141. function calcMouseEventCoords(sliderElem, orientation, per) {
  142. var sliderBB = sliderElem.getBoundingClientRect();
  143. if (orientation === 'horizontal') {
  144. return {
  145. clientX: sliderBB.left + (sliderElem.offsetWidth * per / 100),
  146. clientY: sliderBB.top
  147. };
  148. }
  149. else if (orientation === 'vertical') {
  150. return {
  151. clientX: sliderBB.left,
  152. clientY: sliderBB.top + (sliderElem.offsetHeight * per / 100)
  153. };
  154. }
  155. }
  156. beforeEach(function() {
  157. // Set up default set of mouse event arguments
  158. mouseEventArguments = [
  159. 'mousemove', // type
  160. true, // canBubble
  161. true, // cancelable
  162. document, // view,
  163. 0, // detail
  164. 0, // screenX
  165. 0, // screenY
  166. undefined, // clientX
  167. undefined, // clientY,
  168. false, // ctrlKey
  169. false, // altKey
  170. false, // shiftKey
  171. false, // metaKey,
  172. 0, // button
  173. null // relatedTarget
  174. ];
  175. });
  176. function createMouseEvent(type, clientX, clientY) {
  177. var mouseEvent = document.createEvent('MouseEvent');
  178. mouseEventArguments[0] = type;
  179. mouseEventArguments[7] = clientX;
  180. mouseEventArguments[8] = clientY;
  181. mouseEvent.initMouseEvent.apply(mouseEvent, mouseEventArguments);
  182. return mouseEvent;
  183. }
  184. var mouseTestData = {
  185. single: {
  186. testData: [{
  187. willChange: false,
  188. expectedValue: initialValue,
  189. percent: 20
  190. }, {
  191. willChange: true,
  192. expectedValue: 0,
  193. percent: 10
  194. }, {
  195. willChange: false,
  196. expectedValue: initialValue,
  197. percent: 40
  198. }, {
  199. willChange: true,
  200. expectedValue: 5,
  201. percent: 45
  202. }],
  203. // Modify test data for RTL and reversed situations.
  204. altTestData: [{
  205. willChange: false,
  206. expectedValue: initialValue,
  207. percent: 80
  208. }, {
  209. willChange: true,
  210. expectedValue: 0,
  211. percent: 90
  212. }, {
  213. willChange: false,
  214. expectedValue: initialValue,
  215. percent: 60
  216. }, {
  217. willChange: true,
  218. expectedValue: 5,
  219. percent: 55
  220. }],
  221. },
  222. range: {
  223. testData: [{
  224. willChange: false,
  225. expectedValue: initialRangeValues,
  226. percent: 20
  227. }, {
  228. willChange: true,
  229. expectedValue: [0, 7],
  230. percent: 10
  231. }, {
  232. willChange: false,
  233. expectedValue: initialRangeValues,
  234. percent: 40
  235. }, {
  236. willChange: true,
  237. expectedValue: [5, 7],
  238. percent: 45
  239. },
  240. // More test data that will affect handle2
  241. {
  242. willChange: true,
  243. expectedValue: [3, 5],
  244. percent: 60
  245. }, {
  246. willChange: false,
  247. expectedValue: initialRangeValues,
  248. percent: 65
  249. }, {
  250. willChange: false,
  251. expectedValue: initialRangeValues,
  252. percent: 80
  253. }, {
  254. willChange: true,
  255. expectedValue: [3, 10],
  256. percent: 90
  257. }],
  258. // Modify test data for RTL and reversed situations.
  259. // Here, the order of the ticks matter when locking a handle to a tick
  260. // when there are two ticks that are equal in distance to lock to.
  261. altTestData: [{
  262. willChange: false,
  263. expectedValue: initialRangeValues,
  264. percent: 20
  265. }, {
  266. willChange: true,
  267. expectedValue: [3, 10],
  268. percent: 10
  269. }, {
  270. willChange: true,
  271. expectedValue: [3, 5],
  272. percent: 40
  273. }, {
  274. willChange: false,
  275. expectedValue: initialRangeValues,
  276. percent: 35
  277. },
  278. // More test data that will affect handle2
  279. {
  280. willChange: false,
  281. expectedValue: initialRangeValues,
  282. percent: 60
  283. }, {
  284. willChange: true,
  285. expectedValue: [5, 7],
  286. percent: 55
  287. }, {
  288. willChange: false,
  289. expectedValue: initialRangeValues,
  290. percent: 80
  291. }, {
  292. willChange: true,
  293. expectedValue: [0, 7],
  294. percent: 90
  295. }],
  296. }
  297. };
  298. sliderTypes.forEach(function(sliderType) {
  299. orientations.forEach(function(orientation) {
  300. rtl.forEach(function(isRTL) {
  301. reversed.forEach(function(isReversed) {
  302. var isHorizontal = orientation === 'horizontal';
  303. var isVertical = orientation === 'vertical';
  304. var isRange = sliderType === 'range';
  305. var whichData;
  306. var whichStyle;
  307. whichData = mouseTestData[sliderType].testData;
  308. if (isHorizontal) {
  309. // XOR
  310. // One or the other needs to be true
  311. if ((isRTL && !isReversed) || (isReversed && !isRTL)) {
  312. whichData = mouseTestData[sliderType].altTestData;
  313. }
  314. }
  315. else if (isVertical) {
  316. if (isReversed) {
  317. whichData = mouseTestData[sliderType].altTestData;
  318. }
  319. }
  320. if (isHorizontal) {
  321. if (isRTL) {
  322. whichStyle = 'right';
  323. }
  324. else {
  325. whichStyle = 'left';
  326. }
  327. }
  328. else if (isVertical) {
  329. whichStyle = 'top';
  330. }
  331. testCases.push({
  332. value: isRange ? initialRangeValues : initialValue,
  333. step: stepValue,
  334. range: isRange,
  335. orientation: orientation,
  336. reversed: isReversed,
  337. rtl: 'auto',
  338. isRTL: isRTL,
  339. inputId: isRTL ? 'rtlSlider' : 'testSlider1',
  340. testData: whichData,
  341. stylePos: whichStyle
  342. });
  343. });
  344. });
  345. });
  346. });
  347. testCases.forEach(function(testCase) {
  348. describe("range=" + testCase.range + ", orientation=" + testCase.orientation +
  349. ", rtl=" + testCase.isRTL + ", reversed=" + testCase.reversed, function() {
  350. var $testSlider;
  351. var $handle1;
  352. var $handle2;
  353. var sliderId;
  354. var sliderOptions;
  355. var $tick1;
  356. var $tick2;
  357. var $ticks;
  358. beforeEach(function() {
  359. sliderId = testCase.range ? 'myRangeSlider' : 'mySlider';
  360. sliderOptions = {
  361. id: sliderId,
  362. step: testCase.step,
  363. orientation: testCase.orientation,
  364. value: testCase.value,
  365. range: testCase.range,
  366. lock_to_ticks: true,
  367. reversed: testCase.reversed,
  368. rtl: 'auto',
  369. ticks: tickValues,
  370. };
  371. });
  372. afterEach(function() {
  373. if ($testSlider) {
  374. $testSlider.slider('destroy');
  375. $testSlider = null;
  376. }
  377. });
  378. testCase.testData.forEach(function(testData) {
  379. it("Should snap to closest tick (percent=" + testData.percent + ", changed=" + testData.willChange + ")", function(done) {
  380. $testSlider = $('#'+testCase.inputId).slider(sliderOptions);
  381. var sliderElem = $('#'+sliderId)[0];
  382. $ticks = $('#'+sliderId).find('.slider-tick');
  383. $handle1 = $('#'+sliderId).find('.slider-handle:first');
  384. $handle2 = $('#'+sliderId).find('.slider-handle:last');
  385. var coords = calcMouseEventCoords(sliderElem, testCase.orientation, testData.percent);
  386. var checkMouseMove = function() {
  387. var value = $testSlider.slider('getValue');
  388. expect(value).toEqual(testData.expectedValue);
  389. if (testCase.range) {
  390. $tick1 = $ticks.eq(tickIndexes[testData.expectedValue[0]]);
  391. $tick2 = $ticks.eq(tickIndexes[testData.expectedValue[1]]);
  392. expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
  393. expect($handle2.css(testCase.stylePos)).toBe($tick2.css(testCase.stylePos));
  394. }
  395. else {
  396. $tick1 = $ticks.eq(tickIndexes[testData.expectedValue]);
  397. expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
  398. }
  399. };
  400. var checkMouseUp = function() {
  401. var value = $testSlider.slider('getValue');
  402. expect(value).toEqual(testData.expectedValue);
  403. if (testCase.range) {
  404. $tick1 = $ticks.eq(tickIndexes[testData.expectedValue[0]]);
  405. $tick2 = $ticks.eq(tickIndexes[testData.expectedValue[1]]);
  406. expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
  407. expect($handle2.css(testCase.stylePos)).toBe($tick2.css(testCase.stylePos));
  408. }
  409. else {
  410. $tick1 = $ticks.eq(tickIndexes[testData.expectedValue]);
  411. expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
  412. }
  413. document.removeEventListener('mousemove', checkMouseMove, false);
  414. document.removeEventListener('mouseup', checkMouseUp, false);
  415. done();
  416. };
  417. sliderElem.addEventListener('mousedown', function() {
  418. var value = $testSlider.slider('getValue');
  419. expect(value).toEqual(testData.expectedValue);
  420. // Check position of handles
  421. if (testCase.range) {
  422. $tick1 = $ticks.eq(tickIndexes[testData.expectedValue[0]]);
  423. $tick2 = $ticks.eq(tickIndexes[testData.expectedValue[1]]);
  424. expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
  425. expect($handle2.css(testCase.stylePos)).toBe($tick2.css(testCase.stylePos));
  426. }
  427. else {
  428. $tick1 = $ticks.eq(tickIndexes[testData.expectedValue]);
  429. expect($handle1.css(testCase.stylePos)).toBe($tick1.css(testCase.stylePos));
  430. }
  431. document.addEventListener('mousemove', checkMouseMove, false);
  432. document.addEventListener('mouseup', checkMouseUp, false);
  433. });
  434. sliderElem.dispatchEvent(createMouseEvent('mousedown', coords.clientX, coords.clientY));
  435. document.dispatchEvent(createMouseEvent('mousemove', coords.clientX, coords.clientY));
  436. document.dispatchEvent(createMouseEvent('mouseup', coords.clientX, coords.clientY));
  437. });
  438. });
  439. });
  440. });
  441. });
  442. /**
  443. * The keyboard navigation tests are based on the following slider properties:
  444. *
  445. * initial value: 3 or [3, 7]
  446. * ticks: [0, 3, 5, 7, 10]
  447. * step: 0.1
  448. *
  449. * See description for mouse navigation tests for explanation for test setup values.
  450. *
  451. * These tests are setup to test for all combinations of relevant slider configurations:
  452. * single/range, horizontal/vertical orientation, LTR/RTL, natural keys navigation,
  453. * ordered/reversed, and all key presses (left, up, right, down).
  454. *
  455. * The test data is fairly straightforward and passes most configurations except for
  456. * special cases when using natural key navigation. For these cases, the test data
  457. * had to be 'inverted'. For example, the test data had to be inverted when the
  458. * slider has a horizontal orientation with either RTL or reversed option set (but not both).
  459. *
  460. * The test logic for sliders:
  461. * - Key to the left should change the value and lock to the tick to the left
  462. * - Key to the right should change the value and lock to the tick to the right
  463. *
  464. * For range sliders, the same logic is applied except test both handle1 and handle2.
  465. */
  466. describe("`lock_to_ticks: true` keyboard navigation test cases", function() {
  467. var initialValue = 3;
  468. var initialRangeValues = [3, 7];
  469. var tickValues = [0, 3, 5, 7, 10];
  470. var stepValue = 0.1;
  471. var keyData = {
  472. left: 37,
  473. up: 38,
  474. right: 39,
  475. down: 40
  476. };
  477. var keys = ['left', 'up', 'right', 'down'];
  478. var orientations = ['horizontal', 'vertical'];
  479. var reversed = [false, true];
  480. var naturalKeys = [false, true];
  481. var ranged = [false, true];
  482. var rtl = [false, true];
  483. var rangeHandles = ['handle1', 'handle2'];
  484. var testCases = [];
  485. orientations.forEach(function(orientation) {
  486. ranged.forEach(function(isRange) {
  487. rtl.forEach(function(isRTL) {
  488. naturalKeys.forEach(function(isNatural) {
  489. reversed.forEach(function(isReversed) {
  490. testCases.push({
  491. value: isRange ? initialRangeValues : initialValue,
  492. step: stepValue,
  493. range: isRange,
  494. orientation: orientation,
  495. reversed: isReversed,
  496. rtl: 'auto',
  497. natural_arrow_keys: isNatural,
  498. isRTL: isRTL,
  499. inputId: isRTL ? 'rtlSlider' : 'testSlider1',
  500. });
  501. });
  502. });
  503. });
  504. });
  505. });
  506. testCases.forEach(function(testCase) {
  507. var handles = testCase.range ? rangeHandles : ['handle1'];
  508. describe("orientation=" + testCase.orientation + ", range=" + testCase.range + ", rtl=" + testCase.isRTL +
  509. ", natural_arrow_keys=" + testCase.natural_arrow_keys +
  510. ", reversed=" + testCase.reversed, function() {
  511. var $testSlider;
  512. var $handle;
  513. var keyboardEvent;
  514. var sliderId;
  515. var sliderOptions;
  516. beforeEach(function() {
  517. sliderId = testCase.range ? 'myRangeSlider' : 'mySlider';
  518. sliderOptions = {
  519. id: sliderId,
  520. step: testCase.step,
  521. orientation: testCase.orientation,
  522. value: testCase.value,
  523. range: testCase.range,
  524. lock_to_ticks: true,
  525. reversed: testCase.reversed,
  526. rtl: 'auto',
  527. natural_arrow_keys: testCase.natural_arrow_keys,
  528. ticks: tickValues,
  529. };
  530. // Create keyboard event
  531. keyboardEvent = document.createEvent('Event');
  532. keyboardEvent.initEvent('keydown', true, true);
  533. });
  534. afterEach(function() {
  535. keyboardEvent = null;
  536. if ($testSlider) {
  537. $testSlider.slider('destroy');
  538. $testSlider = null;
  539. }
  540. });
  541. handles.forEach(function(handleKey) {
  542. keys.forEach(function(key) {
  543. var isHorizontal = testCase.orientation === 'horizontal';
  544. var isVertical = testCase.orientation === 'vertical';
  545. var isRange = testCase.range;
  546. var isRTL = testCase.isRTL;
  547. var isReversed = testCase.reversed;
  548. var isNatural = testCase.natural_arrow_keys;
  549. var testData = {
  550. keyCode: keyData[key],
  551. handle1: {
  552. expectedValue: null
  553. },
  554. handle2: {
  555. expectedValue: null
  556. }
  557. };
  558. if (isRange) {
  559. // If initial value is [3, 7] Then
  560. // These expected values will pass 96/128 tests (32 failures)
  561. if (key === 'left' || key === 'down') {
  562. testData.handle1.expectedValue = [0, 7];
  563. testData.handle2.expectedValue = [3, 5];
  564. }
  565. else if (key === 'right' || key === 'up') {
  566. testData.handle1.expectedValue = [5, 7];
  567. testData.handle2.expectedValue = [3, 10];
  568. }
  569. // Special cases when using natural keys
  570. if (isNatural) {
  571. if ((isHorizontal && isReversed && !isRTL) ||
  572. (isHorizontal && isRTL && !isReversed) ||
  573. (isVertical && !isReversed))
  574. {
  575. if (key === 'left' || key === 'down') {
  576. testData.handle1.expectedValue = [5, 7];
  577. testData.handle2.expectedValue = [3, 10];
  578. }
  579. else if (key === 'right' || key === 'up') {
  580. testData.handle1.expectedValue = [0, 7];
  581. testData.handle2.expectedValue = [3, 5];
  582. }
  583. }
  584. }
  585. }
  586. else {
  587. // If initial value is 3 Then
  588. // These expected values will pass 48/64 tests (16 failures)
  589. if (key === 'left' || key === 'down') {
  590. testData.handle1.expectedValue = 0;
  591. }
  592. else if (key === 'right' || key === 'up') {
  593. testData.handle1.expectedValue = 5;
  594. }
  595. // Special cases when using natural keys
  596. if (isNatural) {
  597. // XOR
  598. // One or the other needs to be true
  599. if ((isHorizontal && isReversed && !isRTL) ||
  600. (isHorizontal && isRTL && !isReversed) ||
  601. (isVertical && !isReversed))
  602. {
  603. if (key === 'left' || key === 'down') {
  604. testData.handle1.expectedValue = 5;
  605. }
  606. else if (key === 'right' || key === 'up') {
  607. testData.handle1.expectedValue = 0;
  608. }
  609. }
  610. }
  611. }
  612. it("Should lock to tick (" + handleKey + ", key=" + key + ")", function(done) {
  613. $testSlider = $('#'+testCase.inputId).slider(sliderOptions);
  614. $handle = $('#'+sliderId).find('.slider-handle:' + (handleKey === 'handle1' ? 'first' : 'last'));
  615. $handle.on('keydown', function() {
  616. var value = $testSlider.slider('getValue');
  617. expect(value).toEqual(testData[handleKey].expectedValue);
  618. done();
  619. });
  620. keyboardEvent.keyCode = keyboardEvent.which = testData.keyCode;
  621. $handle[0].dispatchEvent(keyboardEvent);
  622. });
  623. });
  624. });
  625. });
  626. });
  627. });