Best JavaScript code snippet using qawolf
Element.js
Source:Element.js
...388 }389 390 describe("isFocusable", function() {391 describe("absolutely non-focusable elements", function() {392 function createSuite(name, elConfig) {393 return describe(name, function() {394 beforeEach(function() {395 createElement(elConfig);396 });397 398 createFocusableSpecs("with no tabIndex", null, false);399 400 createStandardSuite(false);401 402 createVisibilitySuites();403 });404 }405 406 createSuite('hidden input', { tag: 'input', type: 'hidden' });407 });408 409 describe("naturally focusable elements", function() {410 function createSuite(name, elConfig) {411 return describe(name, function() {412 beforeEach(function() {413 createElement(elConfig);414 });415 416 describe("no special attributes", function() {417 it("is true with no tabIndex on " + name, function() {418 expect(el.isFocusable()).toBe(true);419 });420 421 it("is true for " + name + " with tabIndex = 0", function() {422 dom.tabIndex = 0;423 424 expect(el.isFocusable()).toBe(true);425 });426 427 it("is true for " + name + " with tabIndex > 0", function() {428 dom.tabIndex = 42;429 430 expect(el.isFocusable()).toBe(true);431 });432 433 it("is true for " + name + " with tabIndex < 0", function() {434 dom.tabIndex = -100;435 436 expect(el.isFocusable()).toBe(true);437 });438 439 createVisibilitySuites(true);440 });441 442 if ( disableableTags[ (elConfig.tag || 'div').toUpperCase() ] ) {443 describe("disabled=true " + name, function() {444 beforeEach(function() {445 dom.setAttribute('disabled', true);446 });447 448 it("is false with no tabIndex", function() {449 expect(el.isFocusable()).toBe(false);450 });451 452 it("is false with tabIndex < 0", function() {453 dom.tabIndex = -42;454 455 expect(el.isFocusable()).toBe(false);456 });457 458 it("is false with tabIndex = 0", function() {459 dom.setAttribute('tabIndex', 0);460 461 expect(el.isFocusable()).toBe(false);462 });463 464 it("is false with tabIndex > 0", function() {465 dom.tabIndex = 42;466 467 expect(el.isFocusable()).toBe(false);468 });469 470 // disabled and invisible should not be focusable471 // even when clipped472 createVisibilitySuites(false);473 });474 }475 476 describe("editable " + name, function() {477 beforeEach(function() {478 dom.setAttribute('contenteditable', true);479 });480 481 it("is true for " + name + " with no tabIndex", function() {482 expect(el.isFocusable()).toBeTruthy();483 });484 485 it("is true for " + name + " with tabIndex < 0", function() {486 dom.tabIndex = -1;487 488 expect(el.isFocusable()).toBeTruthy();489 });490 491 it("is true for " + name + " with tabIndex = 0", function() {492 dom.tabIndex = 0;493 494 expect(el.isFocusable()).toBeTruthy();495 });496 497 it("is true for " + name + " with tabIndex > 0", function() {498 dom.tabIndex = 1;499 500 expect(el.isFocusable()).toBeTruthy();501 });502 503 // editable but invisible should not be focusable504 // TODO This is a crude hack! Safari 7 fails to focus505 // editable buttons (can buttons be editable in Safari?)506 if (!Ext.isSafari) {507 createVisibilitySuites(true);508 }509 });510 });511 }512 513 createSuite('anchor with href', { tag: 'a', href: '#' });514 createSuite('button', { tag: 'button' });515 createSuite('iframe', { tag: 'iframe' });516 createSuite('bare input', { tag: 'input' });517 createSuite('button input', { tag: 'input', type: 'button' });518 createSuite('text input', { tag: 'input', type: 'text' });519 520 // File input consistently fails to focus programmatically in Firefox.521 // I guess that could be a lame security feature, or just a bug.522 if (!Ext.isGecko) {523 createSuite('file input', { tag: 'input', type: 'file' });524 }525 526 createSuite('image input', { tag: 'input', type: 'image' });527 createSuite('password input', { tag: 'input', type: 'password' });528 createSuite('submit input', { tag: 'input', type: 'submit' });529 createSuite('checkbox', { tag: 'input', type: 'checkbox' });530 createSuite('radio button', { tag: 'input', type: 'radio' });531 createSuite('select', { tag: 'select', cn: [{ tag: 'option', value: 'foo' }] });532 createSuite('textarea', { tag: 'textarea' });533 534 // There are various failures in IE9-11 that we don't care enough535 // to clean up because <embed> and <object> are rarely used.536 // And we don't even dare running these suites in IE8 because537 // rendering these will result in uncleanable DOM nodes that break538 // all subsequent test specs.539 if (!Ext.isIE) {540 createSuite('embed', {541 tag: 'embed',542 height: 100,543 width: 100,544 type: 'image/gif',545 src: 'resources/images/foo.gif'546 });547 createSuite('object', {548 tag: 'object',549 style: 'height: 100px; width: 100px',550 type: 'image/gif',551 data: 'resources/images/foo.gif'552 });553 }554 });555 556 if (Ext.isIE) {557 describe("documentElement", function() {558 it("should report as focusable", function() {559 var focusable = Ext.fly(document.documentElement).isFocusable();560 561 expect(focusable).toBe(true);562 });563 });564 }565 566 describe("non-naturally focusable elements", function() {567 function createSuite(name, elConfig, selector, testClipping) {568 testClipping = testClipping == null ? true : testClipping;569 570 return describe(name, function() {571 beforeEach(function() {572 createElement(elConfig, selector);573 });574 575 describe("no special attributes", function() {576 it("is false with no tabIndex", function() {577 expect(el.isFocusable()).toBe(false);578 });579 580 it("is true with tabIndex < 0", function() {581 dom.setAttribute('tabIndex', '-1');582 583 expect(el.isFocusable()).toBe(true);584 });585 586 it("is true with tabIndex = 0", function() {587 dom.tabIndex = 0;588 589 expect(el.isFocusable()).toBe(true);590 });591 592 it("is true with tabIndex > 0", function() {593 dom.setAttribute('tabIndex', 10);594 595 expect(el.isFocusable()).toBe(true);596 });597 598 // Should be focusable when clipped599 createVisibilitySuites(testClipping ? true : 'skip');600 });601 602 describe("editable " + name, function() {603 beforeEach(function() {604 dom.setAttribute('contenteditable', true);605 });606 607 it("is true with no tabIndex", function() {608 expect(el.isFocusable()).toBe(true);609 });610 611 it("is true with tabIndex < 0", function() {612 dom.tabIndex = -1;613 614 expect(el.isFocusable()).toBe(true);615 });616 617 it("is true with tabIndex = 0", function() {618 dom.tabIndex = 0;619 620 expect(el.isFocusable()).toBe(true);621 });622 623 it("is true with tabIndex > 0", function() {624 dom.tabIndex = 1;625 626 expect(el.isFocusable()).toBe(true);627 });628 629 // editable but invisible should not be focusable630 // unless clipped631 createVisibilitySuites(testClipping ? true : 'skip');632 });633 });634 }635 636 createSuite('anchor w/o href', { tag: 'a' });637 createSuite('div', { tag: 'div' });638 createSuite('span', { tag: 'span' });639 createSuite('p', { tag: 'p' });640 createSuite('ul li', { tag: 'ul', cn: [{ tag: 'li' }] }, 'li');641 createSuite('ol li', { tag: 'ol', cn: [{ tag: 'li' }] }, 'li' );642 createSuite('img', { tag: 'img' });643 createSuite('td', {644 tag: 'table',645 cn: [{646 tag: 'tr',647 cn: [{648 tag: 'td',649 html: ' '650 }]651 }]652 }, 'td', false);653 });654 });655 });656 657 describe("tabbables", function() {658 function createVisibilitySuites(clipMode) {659 function createSuite(mode, wantTabbable) {660 var realMode = Ext.Element[mode];661 662 wantTabbable = wantTabbable != null ? wantTabbable : false;663 664 return describe("hidden with mode: " + mode, function() {665 beforeEach(function() {666 el.setVisibilityMode(realMode);667 el.setVisible(false);668 });669 670 // tabindex < 0 makes an element always untabbable671 it("is false with tabIndex < 0", function() {672 el.set({ tabIndex: -1 });673 674 expect(el.isTabbable()).toBe(false);675 });676 677 it("is " + wantTabbable + " with tabIndex = 0", function() {678 el.set({ tabIndex: 0 });679 680 expect(el.isTabbable()).toBe(wantTabbable);681 });682 683 it("is " + wantTabbable + " with tabIndex > 0", function() {684 el.set({ tabIndex: 1 });685 686 expect(el.isTabbable()).toBe(wantTabbable);687 });688 });689 }690 691 createSuite('VISIBILITY');692 createSuite('DISPLAY');693 createSuite('OFFSETS');694 createSuite('CLIP', clipMode);695 }696 697 describe("isTabbable", function() {698 describe("absolutely non-tabbable elements", function() {699 function createSuite(name, elConfig) {700 return describe(name, function() {701 beforeEach(function() {702 createElement(elConfig);703 });704 705 it("should be non-tabbable naturally", function() {706 expect(el.isTabbable()).toBeFalsy();707 });708 709 it("should be non-tabbable with tabIndex < 0", function() {710 dom.setAttribute('tabIndex', -1);711 712 expect(el.isTabbable()).toBeFalsy();713 });714 715 it("should be non-tabbable with tabIndex = 0", function() {716 dom.setAttribute('tabIndex', 0);717 718 expect(el.isTabbable()).toBeFalsy();719 });720 721 it("should be non-tabbable with tabIndex > 0", function() {722 dom.setAttribute('tabIndex', 1);723 724 expect(el.isTabbable()).toBeFalsy();725 });726 727 it("should be non-tabbable with contentEditable", function() {728 dom.setAttribute('tabIndex', 0);729 dom.setAttribute('contenteditable', true);730 731 expect(el.isTabbable()).toBeFalsy();732 });733 734 // Should not be tabbable even if clipped735 createVisibilitySuites(false);736 });737 }738 739 createSuite('hidden input', { tag: 'input', type: 'hidden' });740 });741 742 describe("naturally tabbable elements", function() {743 function createSuite(name, elConfig) {744 return describe(name, function() {745 beforeEach(function() {746 createElement(elConfig);747 });748 749 describe("no special attributes", function() {750 it("is true with no tabIndex", function() {751 expect(el.isTabbable()).toBe(true);752 });753 754 it("is false with tabIndex < 0", function() {755 dom.tabIndex = -100;756 757 expect(el.isTabbable()).toBe(false);758 });759 760 it("is true with tabIndex = 0", function() {761 dom.tabIndex = 0;762 763 expect(el.isTabbable()).toBe(true);764 });765 766 it("is true with tabIndex > 0", function() {767 dom.tabIndex = 42;768 769 expect(el.isTabbable()).toBe(true);770 });771 772 // Should be tabbable when clipped773 createVisibilitySuites(true);774 });775 776 if ( disableableTags[ (elConfig.tag || 'div').toUpperCase() ] ) {777 describe("disabled=true " + name, function() {778 beforeEach(function() {779 dom.setAttribute('disabled', true);780 });781 782 it("is false with no tabIndex", function() {783 expect(el.isTabbable()).toBe(false);784 });785 786 it("is false for disabled " + name + " with tabIndex < 0", function() {787 dom.tabIndex = -42;788 789 expect(el.isTabbable()).toBe(false);790 });791 792 it("is false with tabIndex = 0", function() {793 dom.setAttribute('tabIndex', 0);794 795 expect(el.isTabbable()).toBe(false);796 });797 798 it("is false with tabIndex > 0", function() {799 dom.tabIndex = 42;800 801 expect(el.isTabbable()).toBe(false);802 });803 804 // disabled and invisible should not be tabbable805 // even when clipped806 createVisibilitySuites(false);807 });808 }809 810 describe("editable " + name, function() {811 beforeEach(function() {812 dom.setAttribute('contenteditable', true);813 });814 815 it("is true with no tabIndex", function() {816 expect(el.isTabbable()).toBeTruthy();817 });818 819 it("is false with tabIndex < 0", function() {820 dom.tabIndex = -1;821 822 expect(el.isTabbable()).toBeFalsy();823 });824 825 it("is true with tabIndex = 0", function() {826 dom.tabIndex = 0;827 828 expect(el.isTabbable()).toBeTruthy();829 });830 831 it("is true with tabIndex > 0", function() {832 dom.tabIndex = 1;833 834 expect(el.isTabbable()).toBeTruthy();835 });836 837 // editable and invisible should not be tabbable838 // unless we're clipping839 createVisibilitySuites(true);840 });841 });842 }843 844 createSuite('anchor with href', { tag: 'a', href: '#' });845 createSuite('button', { tag: 'button' });846 createSuite('iframe', { tag: 'iframe' });847 createSuite('bare input', { tag: 'input' });848 createSuite('button input', { tag: 'input', type: 'button' });849 createSuite('text input', { tag: 'input', type: 'text' });850 createSuite('file input', { tag: 'input', type: 'file' });851 createSuite('image input', { tag: 'input', type: 'image' });852 createSuite('password input', { tag: 'input', type: 'password' });853 createSuite('submit input', { tag: 'input', type: 'submit' });854 createSuite('checkbox', { tag: 'input', type: 'checkbox' });855 createSuite('radio button', { tag: 'input', type: 'radio' });856 createSuite('select', { tag: 'select', cn: [{ tag: 'option', value: 'foo' }] });857 createSuite('textarea', { tag: 'textarea' });858 859 // In IE8, <object> is naturally tabbable as well860 if (Ext.isIE8) {861 createSuite('object', {862 tag: 'object',863 style: 'height: 100px; width: 100px',864 type: 'image/gif',865 data: 'resources/images/foo.gif'866 });867 }868 });869 870 describe("non-naturally tabbable elements", function() {871 function createSuite(name, elConfig, selector) {872 return describe(name, function() {873 beforeEach(function() {874 createElement(elConfig, selector);875 });876 877 describe("no special attributes", function() {878 it("is false with no tabIndex", function() {879 expect(el.isTabbable()).toBe(false);880 });881 882 it("is false with tabIndex < 0", function() {883 dom.setAttribute('tabIndex', '-1');884 885 expect(el.isTabbable()).toBe(false);886 });887 888 it("is true with tabIndex = 0", function() {889 dom.tabIndex = 0;890 891 expect(el.isTabbable()).toBe(true);892 });893 894 it("is true with tabIndex > 0", function() {895 dom.setAttribute('tabIndex', 10);896 897 expect(el.isTabbable()).toBe(true);898 });899 900 // Should not be tabbable unless we're clippng901 createVisibilitySuites(true);902 });903 904 describe("editable " + name, function() {905 beforeEach(function() {906 dom.setAttribute('contenteditable', true);907 });908 909 it("is true with no tabIndex", function() {910 expect(el.isTabbable()).toBeTruthy();911 });912 913 it("is false with tabIndex < 0", function() {914 dom.tabIndex = -1;915 916 expect(el.isTabbable()).toBeFalsy();917 });918 919 it("is true with tabIndex = 0", function() {920 dom.tabIndex = 0;921 922 expect(el.isTabbable()).toBeTruthy();923 });924 925 it("is true with tabIndex > 0", function() {926 dom.tabIndex = 1;927 928 expect(el.isTabbable()).toBeTruthy();929 });930 931 // editable but invisible should not be tabbable932 // unless we're clipping933 createVisibilitySuites(true);934 });935 });936 }937 938 createSuite('anchor w/o href', { tag: 'a' });939 createSuite('div', { tag: 'div' });940 createSuite('span', { tag: 'span' });941 createSuite('p', { tag: 'p' });942 createSuite('ul li', { tag: 'ul', cn: [{ tag: 'li' }] }, 'li');943 createSuite('ol li', { tag: 'ol', cn: [{ tag: 'li' }] }, 'li' );944 createSuite('img', { tag: 'img' });945 createSuite('td', {946 tag: 'table',947 cn: [{948 tag: 'tr',949 cn: [{950 tag: 'td',951 html: ' '952 }]953 }]954 }, 'td');955 956 if (!Ext.isIE8) {957 createSuite('object', { tag: 'object' });958 }959 });960 });961 962 describe("finding", function() {963 beforeEach(function() {964 createElement([965 '<div tabindex="0">',966 '<a id="test7" href="#">Tabbable</a>',967 '<a id="test8" href="#" tabindex="-1">Not tabbable</a>',968 '<a id="test9" href="#" tabindex="0">Tabbable</a>',969 '<div id="test1">Not tabbable',970 '<div id="test2" tabindex="-1">Not tabbable',971 '<div id="test3" tabindex="0">Tabbable',972 '<div id="test5" tabindex="1">Tabbable</div>',973 '</div>',974 '</div>',975 '</div>',976 '<span id="test11">Not tabbable</span>',977 '<span id="test12" tabindex="-42">Not tabbable</span>',978 '<span id="test13" tabindex="0">Tabbable</span>',979 '<button id="test15">Tabbable</button>',980 '<button id="test16" tabindex="-100">Not tabbable</button>',981 '<button id="test17" tabindex="0">Tabbable</button>',982 '<button id="test18" tabindex="1" disabled="disabled">Not tabbable</button>',983 '<a id="test19">Not tabbable</a>',984 '<a id="test20" tabindex="-1">Not tabbable</a>',985 '<a id="test21" tabindex="0">Tabbable</a>',986 '<iframe id="test23">Tabbable</iframe>',987 '<iframe id="test24" tabindex="-1">Not tabbable</iframe>',988 '<iframe id="test25" tabindex="0">Tabbable</iframe>',989 '<input id="test27" name="Tabbable" />',990 '<input id="test28" name="Not tabbable 1" tabindex="-12" />',991 '<input id="test29" name="Not tabbable 2" disabled="disabled" />',992 '<select id="test30"><option>Tabbable</option></select>',993 '<select id="test31" tabindex="-1"><option>Not tabbable</option></select>',994 '<select id="test32" tabindex="1" disabled="true"><option>Not tabbable</option></select>',995 '<textarea id="test33">Tabbable</textarea>',996 '<textarea id="test34" tabindex="-1">Not tabbable</textarea>',997 '<textarea id="test35" tabindex="0" disabled="1">Not tabbable</textarea>',998 '<p id="test36">Not tabbable</p>',999 '<div>'1000 ]);1001 });1002 1003 describe("all nodes", function() {1004 it("should find all tabbable elements including self by default", function() {1005 var els = el.findTabbableElements();1006 1007 expect(els.length).toBe(14);1008 });1009 });1010 1011 describe("children", function() {1012 var els;1013 1014 beforeEach(function() {1015 els = el.findTabbableElements({1016 skipSelf: true1017 });1018 });1019 1020 it("should find all tabbable sub-elements", function() {1021 expect(els.length).toBe(13);1022 });1023 1024 it("should return correct sub-elements in correct order", function() {1025 expect(els[0].id).toBe('test7');1026 expect(els[1].id).toBe('test9');1027 expect(els[2].id).toBe('test3');1028 expect(els[3].id).toBe('test5');1029 expect(els[4].id).toBe('test13');1030 expect(els[5].id).toBe('test15');1031 expect(els[6].id).toBe('test17');1032 expect(els[7].id).toBe('test21');1033 expect(els[8].id).toBe('test23');1034 expect(els[9].id).toBe('test25');1035 expect(els[10].id).toBe('test27');1036 expect(els[11].id).toBe('test30');1037 expect(els[12].id).toBe('test33');1038 });1039 });1040 1041 describe("excludeRoot", function() {1042 var els, test1;1043 1044 beforeEach(function() {1045 test1 = Ext.get('test1');1046 els = el.findTabbableElements({1047 skipSelf: true,1048 excludeRoot: test11049 });1050 });1051 1052 it("should exclude nodes within excludeRoot", function() {1053 expect(els.length).toBe(11);1054 });1055 1056 it("should return correct children in order", function() {1057 expect(els[0].id).toBe('test7');1058 expect(els[1].id).toBe('test9');1059 expect(els[2].id).toBe('test13');1060 expect(els[3].id).toBe('test15');1061 expect(els[4].id).toBe('test17');1062 expect(els[5].id).toBe('test21');1063 expect(els[6].id).toBe('test23');1064 expect(els[7].id).toBe('test25');1065 expect(els[8].id).toBe('test27');1066 expect(els[9].id).toBe('test30');1067 expect(els[10].id).toBe('test33');1068 });1069 });1070 1071 describe("nested tabbable elements", function() {1072 beforeEach(function() {1073 createElement([1074 '<div id="window-1009" tabindex="-1">',1075 '<div id="window-1009-tabGuardBeforeEl" tabindex="0"></div>',1076 '<div id="window-1009_header" tabindex="0">',1077 '<div id="window-1009_header-innerCt">',1078 '<div id="window-1009_header-targetEl">',1079 '<div id="window-1009_header-title">',1080 '<div id="window-1009_header-title-textEl">foo</div>',1081 '</div>',1082 '<div id="tool-1015" tabindex="-1">',1083 '<div id="tool-1015-toolEl"></div>',1084 '</div>',1085 '<div id="tool-1016" tabindex="-1">',1086 '<div id="tool-1016-toolEl"></div>',1087 '</div>',1088 '</div>',1089 '</div>',1090 '</div>',1091 '<div id="window-1009-body">',1092 '<div id="window-1009-outerCt">',1093 '<div id="window-1009-innerCt">',1094 '<div id="window-1009-formWrap">',1095 '<div id="textfield-1010">',1096 '<label id="textfield-1010-labelEl" for="textfield-1010-inputEl">',1097 '<span>foo:</span>',1098 '</label>',1099 '<div id="textfield-1010-bodyEl">',1100 '<div id="textfield-1010-triggerWrap">',1101 '<div id="textfield-1010-inputWrap">',1102 '<input id="textfield-1010-inputEl" type="text" />',1103 '</div>',1104 '</div>',1105 '<div id="textfield-1010-ariaErrorEl"></div>',1106 '</div>',1107 '</div>',1108 '<div id="textfield-1011">',1109 '<label id="textfield-1011-labelEl" for="textfield-1011-inputEl">',1110 '<span>bar:</span>',1111 '</label>',1112 '<div id="textfield-1011-bodyEl">',1113 '<div id="textfield-1011-triggerWrap">',1114 '<div id="textfield-1011-inputWrap">',1115 '<input id="textfield-1011-inputEl" type="text" />',1116 '</div>',1117 '</div>',1118 '<div id="textfield-1011-ariaErrorEl"></div>',1119 '</div>',1120 '</div>',1121 '</div>',1122 '</div>',1123 '</div>',1124 '</div>',1125 '<div id="toolbar-1012" tabindex="0">',1126 '<div id="toolbar-1012-innerCt">',1127 '<div id="toolbar-1012-targetEl">',1128 '<a id="button-1013" tabindex="-1">OK</a>',1129 '<a id="button-1014" tabindex="-1">Cancel</a>',1130 '</div>',1131 '</div>',1132 '</div>',1133 '<div id="window-1009-tabGuardAfterEl" tabindex="0"></div>',1134 '</div>'1135 ]);1136 });1137 1138 it("should return elements in the right order", function() {1139 var els = topEl.findTabbableElements();1140 1141 expect(els[0].id).toBe('window-1009-tabGuardBeforeEl');1142 expect(els[1].id).toBe('window-1009_header');1143 expect(els[2].id).toBe('textfield-1010-inputEl');1144 expect(els[3].id).toBe('textfield-1011-inputEl');1145 expect(els[4].id).toBe('toolbar-1012');1146 expect(els[5].id).toBe('window-1009-tabGuardAfterEl');1147 });1148 });1149 });1150 1151 describe("state attributes", function() {1152 function createSuite(name, elConfig, selector, deep) {1153 return describe(name, function() {1154 var defaultAttr = Ext.Element.tabbableSavedValueAttribute,1155 counterAttr = Ext.Element.tabbableSavedCounterAttribute;1156 1157 beforeEach(function() {1158 createElement(elConfig, selector);1159 });1160 1161 it("should be tabbable before the test (sanity check)", function() {1162 expect(el.isTabbable()).toBeTruthy();1163 });1164 1165 describe("saving", function() {1166 beforeEach(function() {1167 el.saveTabbableState({1168 skipSelf: false,1169 skipChildren: !deep1170 });1171 });1172 1173 it("should have the tabbable state saved", function() {1174 var attr = el.getAttribute(defaultAttr);1175 1176 expect(attr).toBeTruthy();1177 });1178 1179 it("should become non-tabbable", function() {1180 expect(el.isTabbable()).toBeFalsy();1181 });1182 1183 it("should set the counter", function() {1184 var counter = +el.getAttribute(counterAttr);1185 1186 expect(counter).toBe(1);1187 });1188 1189 it("should increment the counter", function() {1190 el.saveTabbableState({1191 skipSelf: false,1192 skipChildren: !deep1193 });1194 1195 var counter = +el.getAttribute(counterAttr);1196 1197 expect(counter).toBe(2);1198 });1199 });1200 1201 describe("restoring", function() {1202 it("should be tabbable before the test (sanity check)", function() {1203 expect(el.isTabbable()).toBeTruthy();1204 });1205 1206 describe("saved", function() {1207 beforeEach(function() {1208 el.saveTabbableState({1209 skipSelf: false,1210 skipChildren: !deep1211 });1212 el.restoreTabbableState();1213 });1214 1215 it("should have the saved attribute removed", function() {1216 var hasIt = dom.hasAttribute(defaultAttr);1217 1218 expect(hasIt).toBeFalsy();1219 });1220 1221 it("should be tabbable again", function() {1222 expect(el.isTabbable()).toBe(true);1223 });1224 1225 it("should remove the counter", function() {1226 var hasIt = dom.hasAttribute(counterAttr);1227 1228 expect(hasIt).toBeFalsy();1229 });1230 });1231 1232 describe("counter", function() {1233 beforeEach(function() {1234 el.saveTabbableState({1235 skipSelf: false,1236 skipChildren: !deep1237 });1238 el.saveTabbableState({1239 skipSelf: false,1240 skipChildren: !deep1241 });1242 });1243 1244 it("should have counter set (sanity check)", function() {1245 var counter = +el.getAttribute(counterAttr);1246 1247 expect(counter).toBe(2);1248 });1249 1250 describe("> 0", function() {1251 beforeEach(function() {1252 el.restoreTabbableState();1253 });1254 1255 it("should not restore tabbability", function() {1256 expect(el.isTabbable()).toBe(false);1257 });1258 1259 it("should decrement the counter", function() {1260 var counter = +el.getAttribute(counterAttr);1261 1262 expect(counter).toBe(1);1263 });1264 });1265 });1266 });1267 });1268 }1269 1270 // Standalone elements1271 createSuite('a w/ href', { tag: 'a', href: '#' });1272 createSuite('button', { tag: 'button' });1273 createSuite('input', { tag: 'input', type: 'text' });1274 createSuite('div', { tag: 'div', tabIndex: 0 });1275 1276 // Hierarchies1277 createSuite('div w/ children', {1278 tag: 'div',1279 tabIndex: 0,1280 cn: [{1281 tag: 'div',1282 tabIndex: 1,1283 id: 'foo',1284 cn: [{1285 tag: 'div',1286 tabIndex: 21287 }]1288 }]1289 }, '#foo', true);1290 });1291 1292 describe("state", function() {1293 function createSuite(name, elConfig, selector, deep) {1294 return describe(name, function() {1295 describe(name + " saving", function() {1296 beforeEach(function() {1297 createElement(elConfig, selector);1298 });1299 1300 it("should be tabbable before the test (sanity check)", function() {1301 expect(el.isTabbable()).toBe(true);1302 });1303 1304 describe(name + " element", function() {1305 beforeEach(function() {1306 el.saveTabbableState({1307 skipSelf: false,1308 skipChildren: true1309 });1310 });1311 1312 it("should be removed from tab order", function() {1313 expect(el.isTabbable()).toBe(false);1314 });1315 1316 if (deep) {1317 it("should not disable children tabbable state", function() {1318 var cn = el.findTabbableElements({1319 skipSelf: true1320 });1321 1322 expect(cn.length).toBeTruthy();1323 });1324 }1325 });1326 1327 if (deep) {1328 describe(name + " children", function() {1329 beforeEach(function() {1330 el.saveTabbableState({1331 skipSelf: false,1332 skipChildren: !deep1333 });1334 });1335 1336 it("should remove children from tab order", function() {1337 var cn = el.findTabbableElements({1338 skipSelf: true1339 });1340 1341 expect(cn.length).toBe(0);1342 });1343 });1344 }1345 });1346 1347 describe(name + " restoring", function() {1348 var saved;1349 1350 beforeEach(function() {1351 createElement(elConfig, selector);1352 saved = undefined;1353 });1354 1355 it("should be tabbable before the test (sanity check)", function() {1356 expect(el.isTabbable()).toBe(true);1357 });1358 1359 describe(name + " element saved", function() {1360 beforeEach(function() {1361 saved = dom.getAttribute('tabIndex');1362 el.saveTabbableState();1363 });1364 1365 it("should not be tabbable when state is saved", function() {1366 expect(el.isTabbable()).toBe(false);1367 });1368 1369 describe(name + " element restored", function() {1370 beforeEach(function() {1371 el.restoreTabbableState();1372 });1373 1374 it("should have the tabIndex attribute restored", function() {1375 var idx = dom.getAttribute('tabIndex');1376 1377 expect(idx).toBe(saved);1378 });1379 1380 it("should be tabbable again", function() {1381 expect(el.isTabbable()).toBe(true);1382 });1383 });1384 });1385 1386 if (deep) {1387 describe(name + " children saved", function() {1388 beforeEach(function() {1389 saved = el.saveTabbableState({1390 skipSelf: true,1391 skipChildren: !deep1392 }) || [];1393 });1394 1395 it("should have no tabbable children when saved", function() {1396 var cn = el.findTabbableElements({1397 skipSelf: true1398 });1399 1400 expect(cn.length).toBe(0);1401 });1402 1403 describe(name + " children restored", function() {1404 beforeEach(function() {1405 el.restoreTabbableState(/* skipSelf = */ true);1406 });1407 1408 it("should have the same number of tabbable children", function() {1409 var cn = el.findTabbableElements({1410 skipSelf: true1411 });1412 1413 expect(cn.length).toBe(saved.length);1414 });1415 1416 it("should have the same tabbable children", function() {1417 var cn = el.findTabbableElements({1418 skipSelf: true1419 });1420 1421 for (var i = 0; i < saved.length; i++) {1422 var c1 = saved[i],1423 c2 = cn[i];1424 1425 expect(c1.id).toBe(c2.id);1426 }1427 });1428 });1429 });1430 }1431 });1432 });1433 }1434 1435 createSuite('anchor with href natural', { tag: 'a', href: '#' });1436 createSuite('anchor with href w/ tabIndex', { tag: 'a', href: '#', tabIndex: 0 });1437 1438 createSuite('anchor w/o href', { tag: 'a', tabIndex: 0 });1439 createSuite('anchor w/o href w/ children', {1440 tag: 'a',1441 tabIndex: 0,1442 cn: [{1443 tag: 'div',1444 tabIndex: 11445 }]1446 }, '', true);1447 1448 createSuite('button natural', { tag: 'button' });1449 createSuite('button w/ tabIndex', { tag: 'button', tabIndex: 0 });1450 1451 createSuite('iframe natural', { tag: 'iframe' });1452 createSuite('iframe w/ tabIndex', { tag: 'iframe', tabIndex: 42 });1453 1454 createSuite('input natural', { tag: 'input' });1455 createSuite('input w/ tabIndex', { tag: 'input', tabIndex: 1 });1456 1457 createSuite('select natural', {1458 tag: 'select',1459 cn: [{1460 tag: 'option',1461 value: 'foo'1462 }]1463 });1464 createSuite('select w/ tabIndex', {1465 tag: 'select',1466 tabIndex: 100,1467 cn: [{1468 tag: 'option',1469 value: 'bar'1470 }]1471 });1472 1473 createSuite('textarea natural', { tag: 'textarea' });1474 createSuite('textarea w/ tabIndex', { tag: 'textarea', tabIndex: 1 });1475 1476 createSuite('div', { tag: 'div', tabIndex: 0 });1477 createSuite('div w/ children', {1478 tag: 'div',1479 tabIndex: 0,1480 cn: [{1481 tag: 'div',1482 tabIndex: 1,1483 cn: [{1484 tag: 'div',1485 tabIndex: 21486 }]1487 }]1488 }, '', true);1489 1490 createSuite('span', { tag: 'span', tabIndex: 0 });1491 createSuite('p', { tag: 'p', tabIndex: 0 });1492 createSuite('img', { tag: 'img', tabIndex: 0 });1493 1494 createSuite('ul li', {1495 tag: 'ul',1496 tabIndex: 0,1497 cn: [{1498 tag: 'li',1499 tabIndex: 11500 }, {1501 tag: 'li',1502 tabIndex: 21503 }]1504 }, null, true);1505 1506 createSuite('ol li', {1507 tag: 'ol',1508 tabIndex: 100,1509 cn: [{1510 tag: 'li',1511 tabIndex: 1011512 }, {1513 tag: 'li',1514 tabIndex: 1021515 }]1516 }, null, true);1517 1518 createSuite('table', {1519 tag: 'table',1520 tabIndex: 0,1521 cn: [{1522 tag: 'tr',1523 cn: [{1524 tag: 'td',1525 tabIndex: 1,1526 html: ' '1527 }, {1528 tag: 'td',1529 tabIndex: 2,1530 html: ' '1531 }]1532 }]...
Element.focusability.js
Source:Element.focusability.js
...142 }143 }144 describe("isFocusable", function() {145 describe("absolutely non-focusable elements", function() {146 function createSuite(name, elConfig) {147 return describe(name, function() {148 beforeEach(function() {149 createElement(useFly, elConfig);150 });151 createFocusableSpecs("with no tabIndex", null, false);152 createStandardSuite(false);153 createVisibilitySuites();154 });155 }156 createSuite('hidden input', { tag: 'input', type: 'hidden' });157 });158 describe("naturally focusable elements", function() {159 function createSuite(name, elConfig) {160 return describe(name, function() {161 beforeEach(function() {162 createElement(useFly, elConfig);163 });164 describe("no special attributes", function() {165 it("is true with no tabIndex on " + name, function() {166 expect(el.isFocusable()).toBe(true);167 });168 it("is true for " + name + " with tabIndex = 0", function() {169 dom.tabIndex = 0;170 expect(el.isFocusable()).toBe(true);171 });172 it("is true for " + name + " with tabIndex > 0", function() {173 dom.tabIndex = 42;174 expect(el.isFocusable()).toBe(true);175 });176 it("is true for " + name + " with tabIndex < 0", function() {177 dom.tabIndex = -100;178 expect(el.isFocusable()).toBe(true);179 });180 createVisibilitySuites(true);181 });182 if (disableableTags[(elConfig.tag || 'div').toUpperCase()]) {183 describe("disabled=true " + name, function() {184 beforeEach(function() {185 dom.setAttribute('disabled', true);186 });187 it("is false with no tabIndex", function() {188 expect(el.isFocusable()).toBe(false);189 });190 it("is false with tabIndex < 0", function() {191 dom.tabIndex = -42;192 expect(el.isFocusable()).toBe(false);193 });194 it("is false with tabIndex = 0", function() {195 dom.setAttribute('tabIndex', 0);196 expect(el.isFocusable()).toBe(false);197 });198 it("is false with tabIndex > 0", function() {199 dom.tabIndex = 42;200 expect(el.isFocusable()).toBe(false);201 });202 // disabled and invisible should not be focusable203 // even when clipped204 createVisibilitySuites(false);205 });206 }207 describe("editable " + name, function() {208 beforeEach(function() {209 dom.setAttribute('contenteditable', true);210 });211 it("is true for " + name + " with no tabIndex", function() {212 expect(el.isFocusable()).toBeTruthy();213 });214 it("is true for " + name + " with tabIndex < 0", function() {215 dom.tabIndex = -1;216 expect(el.isFocusable()).toBeTruthy();217 });218 it("is true for " + name + " with tabIndex = 0", function() {219 dom.tabIndex = 0;220 expect(el.isFocusable()).toBeTruthy();221 });222 it("is true for " + name + " with tabIndex > 0", function() {223 dom.tabIndex = 1;224 expect(el.isFocusable()).toBeTruthy();225 });226 // editable but invisible should not be focusable227 // TODO This is a crude hack! Safari 7 fails to focus228 // editable buttons (can buttons be editable in Safari?)229 if (!Ext.isSafari) {230 createVisibilitySuites(true);231 }232 });233 });234 }235 createSuite('anchor with href', { tag: 'a', href: '#' });236 createSuite('button', { tag: 'button' });237 createSuite('iframe', { tag: 'iframe' });238 createSuite('bare input', { tag: 'input' });239 createSuite('button input', { tag: 'input', type: 'button' });240 createSuite('text input', { tag: 'input', type: 'text' });241 // File input consistently fails to focus programmatically in Firefox.242 // I guess that could be a lame security feature, or just a bug.243 if (!Ext.isGecko) {244 createSuite('file input', { tag: 'input', type: 'file' });245 }246 createSuite('image input', { tag: 'input', type: 'image' });247 createSuite('password input', { tag: 'input', type: 'password' });248 createSuite('submit input', { tag: 'input', type: 'submit' });249 createSuite('checkbox', { tag: 'input', type: 'checkbox' });250 createSuite('radio button', { tag: 'input', type: 'radio' });251 createSuite('select', { tag: 'select', cn: [{ tag: 'option', value: 'foo' }] });252 createSuite('textarea', { tag: 'textarea' });253 // There are various failures in IE9-11 and Edge that we don't care enough254 // to clean up because <embed> and <object> are rarely used.255 if (!Ext.isIE && !Ext.isEdge) {256 createSuite('embed', {257 tag: 'embed',258 height: 100,259 width: 100,260 type: 'image/gif',261 src: 'resources/images/foo.gif'262 });263 createSuite('object', {264 tag: 'object',265 style: 'height: 100px; width: 100px',266 type: 'image/gif',267 data: 'resources/images/foo.gif'268 });269 }270 });271 if (Ext.isIE) {272 describe("documentElement", function() {273 it("should report as focusable", function() {274 var focusable = Ext.fly(document.documentElement).isFocusable();275 expect(focusable).toBe(true);276 });277 });278 }279 describe("non-naturally focusable elements", function() {280 function createSuite(name, elConfig, selector, testClipping) {281 testClipping = testClipping == null ? true : testClipping;282 return describe(name, function() {283 beforeEach(function() {284 createElement(useFly, elConfig, selector);285 });286 describe("no special attributes", function() {287 it("is false with no tabIndex", function() {288 expect(el.isFocusable()).toBe(false);289 });290 it("is true with tabIndex < 0", function() {291 dom.setAttribute('tabIndex', '-1');292 expect(el.isFocusable()).toBe(true);293 });294 it("is true with tabIndex = 0", function() {295 dom.tabIndex = 0;296 expect(el.isFocusable()).toBe(true);297 });298 it("is true with tabIndex > 0", function() {299 dom.setAttribute('tabIndex', 10);300 expect(el.isFocusable()).toBe(true);301 });302 // Should be focusable when clipped303 createVisibilitySuites(testClipping ? true : 'skip');304 });305 describe("editable " + name, function() {306 beforeEach(function() {307 dom.setAttribute('contenteditable', true);308 });309 it("is true with no tabIndex", function() {310 expect(el.isFocusable()).toBe(true);311 });312 it("is true with tabIndex < 0", function() {313 dom.tabIndex = -1;314 expect(el.isFocusable()).toBe(true);315 });316 it("is true with tabIndex = 0", function() {317 dom.tabIndex = 0;318 expect(el.isFocusable()).toBe(true);319 });320 it("is true with tabIndex > 0", function() {321 dom.tabIndex = 1;322 expect(el.isFocusable()).toBe(true);323 });324 // editable but invisible should not be focusable325 // unless clipped326 createVisibilitySuites(testClipping ? true : 'skip');327 });328 });329 }330 createSuite('anchor w/o href', { tag: 'a' });331 createSuite('div', { tag: 'div' });332 createSuite('span', { tag: 'span' });333 createSuite('p', { tag: 'p' });334 createSuite('ul li', { tag: 'ul', cn: [{ tag: 'li' }] }, 'li');335 createSuite('ol li', { tag: 'ol', cn: [{ tag: 'li' }] }, 'li');336 createSuite('img', { tag: 'img' });337 createSuite('td', {338 tag: 'table',339 cn: [{340 tag: 'tr',341 cn: [{342 tag: 'td',343 html: ' '344 }]345 }]346 }, 'td', false);347 });348 });349 });350 describe("tabbables", function() {351 function createVisibilitySuites(clipMode) {352 function createSuite(mode, wantTabbable) {353 var realMode = Ext.Element[mode];354 wantTabbable = wantTabbable != null ? wantTabbable : false;355 return describe("hidden with mode: " + mode, function() {356 beforeEach(function() {357 el.setVisibilityMode(realMode);358 el.setVisible(false);359 });360 // tabindex < 0 makes an element always untabbable361 it("is false with tabIndex < 0", function() {362 el.set({ tabIndex: -1 });363 expect(el.isTabbable()).toBe(false);364 });365 it("is " + wantTabbable + " with tabIndex = 0", function() {366 el.set({ tabIndex: 0 });367 expect(el.isTabbable()).toBe(wantTabbable);368 });369 it("is " + wantTabbable + " with tabIndex > 0", function() {370 el.set({ tabIndex: 1 });371 expect(el.isTabbable()).toBe(wantTabbable);372 });373 });374 }375 createSuite('VISIBILITY');376 createSuite('DISPLAY');377 createSuite('OFFSETS');378 createSuite('CLIP', clipMode);379 }380 describe("isTabbable", function() {381 describe("absolutely non-tabbable elements", function() {382 function createSuite(name, elConfig) {383 return describe(name, function() {384 beforeEach(function() {385 createElement(useFly, elConfig);386 });387 it("should be non-tabbable naturally", function() {388 expect(el.isTabbable()).toBeFalsy();389 });390 it("should be non-tabbable with tabIndex < 0", function() {391 dom.setAttribute('tabIndex', -1);392 expect(el.isTabbable()).toBeFalsy();393 });394 it("should be non-tabbable with tabIndex = 0", function() {395 dom.setAttribute('tabIndex', 0);396 expect(el.isTabbable()).toBeFalsy();397 });398 it("should be non-tabbable with tabIndex > 0", function() {399 dom.setAttribute('tabIndex', 1);400 expect(el.isTabbable()).toBeFalsy();401 });402 it("should be non-tabbable with contentEditable", function() {403 dom.setAttribute('tabIndex', 0);404 dom.setAttribute('contenteditable', true);405 expect(el.isTabbable()).toBeFalsy();406 });407 // Should not be tabbable even if clipped408 createVisibilitySuites(false);409 });410 }411 createSuite('hidden input', { tag: 'input', type: 'hidden' });412 });413 describe("naturally tabbable elements", function() {414 function createSuite(name, elConfig) {415 return describe(name, function() {416 beforeEach(function() {417 createElement(useFly, elConfig);418 });419 describe("no special attributes", function() {420 it("is true with no tabIndex", function() {421 expect(el.isTabbable()).toBe(true);422 });423 it("is false with tabIndex < 0", function() {424 dom.tabIndex = -100;425 expect(el.isTabbable()).toBe(false);426 });427 it("is true with tabIndex = 0", function() {428 dom.tabIndex = 0;429 expect(el.isTabbable()).toBe(true);430 });431 it("is true with tabIndex > 0", function() {432 dom.tabIndex = 42;433 expect(el.isTabbable()).toBe(true);434 });435 // Should be tabbable when clipped436 createVisibilitySuites(true);437 });438 if (disableableTags[(elConfig.tag || 'div').toUpperCase()]) {439 describe("disabled=true " + name, function() {440 beforeEach(function() {441 dom.setAttribute('disabled', true);442 });443 it("is false with no tabIndex", function() {444 expect(el.isTabbable()).toBe(false);445 });446 it("is false for disabled " + name + " with tabIndex < 0", function() {447 dom.tabIndex = -42;448 expect(el.isTabbable()).toBe(false);449 });450 it("is false with tabIndex = 0", function() {451 dom.setAttribute('tabIndex', 0);452 expect(el.isTabbable()).toBe(false);453 });454 it("is false with tabIndex > 0", function() {455 dom.tabIndex = 42;456 expect(el.isTabbable()).toBe(false);457 });458 // disabled and invisible should not be tabbable459 // even when clipped460 createVisibilitySuites(false);461 });462 }463 describe("editable " + name, function() {464 beforeEach(function() {465 dom.setAttribute('contenteditable', true);466 });467 it("is true with no tabIndex", function() {468 expect(el.isTabbable()).toBeTruthy();469 });470 it("is false with tabIndex < 0", function() {471 dom.tabIndex = -1;472 expect(el.isTabbable()).toBeFalsy();473 });474 it("is true with tabIndex = 0", function() {475 dom.tabIndex = 0;476 expect(el.isTabbable()).toBeTruthy();477 });478 it("is true with tabIndex > 0", function() {479 dom.tabIndex = 1;480 expect(el.isTabbable()).toBeTruthy();481 });482 // editable and invisible should not be tabbable483 // unless we're clipping484 createVisibilitySuites(true);485 });486 });487 }488 createSuite('anchor with href', { tag: 'a', href: '#' });489 createSuite('button', { tag: 'button' });490 createSuite('iframe', { tag: 'iframe' });491 createSuite('bare input', { tag: 'input' });492 createSuite('button input', { tag: 'input', type: 'button' });493 createSuite('text input', { tag: 'input', type: 'text' });494 createSuite('file input', { tag: 'input', type: 'file' });495 createSuite('image input', { tag: 'input', type: 'image' });496 createSuite('password input', { tag: 'input', type: 'password' });497 createSuite('submit input', { tag: 'input', type: 'submit' });498 createSuite('checkbox', { tag: 'input', type: 'checkbox' });499 createSuite('radio button', { tag: 'input', type: 'radio' });500 createSuite('select', { tag: 'select', cn: [{ tag: 'option', value: 'foo' }] });501 createSuite('textarea', { tag: 'textarea' });502 });503 describe("non-naturally tabbable elements", function() {504 function createSuite(name, elConfig, selector) {505 return describe(name, function() {506 beforeEach(function() {507 createElement(useFly, elConfig, selector);508 });509 describe("no special attributes", function() {510 it("is false with no tabIndex", function() {511 expect(el.isTabbable()).toBe(false);512 });513 it("is false with tabIndex < 0", function() {514 dom.setAttribute('tabIndex', '-1');515 expect(el.isTabbable()).toBe(false);516 });517 it("is true with tabIndex = 0", function() {518 dom.tabIndex = 0;519 expect(el.isTabbable()).toBe(true);520 });521 it("is true with tabIndex > 0", function() {522 dom.setAttribute('tabIndex', 10);523 expect(el.isTabbable()).toBe(true);524 });525 // Should not be tabbable unless we're clippng526 createVisibilitySuites(true);527 });528 describe("editable " + name, function() {529 beforeEach(function() {530 dom.setAttribute('contenteditable', true);531 });532 it("is true with no tabIndex", function() {533 expect(el.isTabbable()).toBeTruthy();534 });535 it("is false with tabIndex < 0", function() {536 dom.tabIndex = -1;537 expect(el.isTabbable()).toBeFalsy();538 });539 it("is true with tabIndex = 0", function() {540 dom.tabIndex = 0;541 expect(el.isTabbable()).toBeTruthy();542 });543 it("is true with tabIndex > 0", function() {544 dom.tabIndex = 1;545 expect(el.isTabbable()).toBeTruthy();546 });547 // editable but invisible should not be tabbable548 // unless we're clipping549 createVisibilitySuites(true);550 });551 });552 }553 createSuite('anchor w/o href', { tag: 'a' });554 createSuite('div', { tag: 'div' });555 createSuite('span', { tag: 'span' });556 createSuite('p', { tag: 'p' });557 createSuite('ul li', { tag: 'ul', cn: [{ tag: 'li' }] }, 'li');558 createSuite('ol li', { tag: 'ol', cn: [{ tag: 'li' }] }, 'li');559 createSuite('img', { tag: 'img' });560 createSuite('td', {561 tag: 'table',562 cn: [{563 tag: 'tr',564 cn: [{565 tag: 'td',566 html: ' '567 }]568 }]569 }, 'td');570 });571 });572 describe("finding", function() {573 beforeEach(function() {574 createElement(useFly, [575 '<div tabindex="0">',576 '<a id="test7" href="#">Tabbable</a>',577 '<a id="test8" href="#" tabindex="-1">Not tabbable</a>',578 '<a id="test9" href="#" tabindex="0">Tabbable</a>',579 '<div id="test1">Not tabbable',580 '<div id="test2" tabindex="-1">Not tabbable',581 '<div id="test3" tabindex="0">Tabbable',582 '<div id="test5" tabindex="1">Tabbable</div>',583 '</div>',584 '</div>',585 '</div>',586 '<span id="test11">Not tabbable</span>',587 '<span id="test12" tabindex="-42">Not tabbable</span>',588 '<span id="test13" tabindex="0">Tabbable</span>',589 '<button id="test15">Tabbable</button>',590 '<button id="test16" tabindex="-100">Not tabbable</button>',591 '<button id="test17" tabindex="0">Tabbable</button>',592 '<button id="test18" tabindex="1" disabled="disabled">Not tabbable</button>',593 '<a id="test19">Not tabbable</a>',594 '<a id="test20" tabindex="-1">Not tabbable</a>',595 '<a id="test21" tabindex="0">Tabbable</a>',596 '<iframe id="test23">Tabbable</iframe>',597 '<iframe id="test24" tabindex="-1">Not tabbable</iframe>',598 '<iframe id="test25" tabindex="0">Tabbable</iframe>',599 '<input id="test27" name="Tabbable" />',600 '<input id="test28" name="Not tabbable 1" tabindex="-12" />',601 '<input id="test29" name="Not tabbable 2" disabled="disabled" />',602 '<select id="test30"><option>Tabbable</option></select>',603 '<select id="test31" tabindex="-1"><option>Not tabbable</option></select>',604 '<select id="test32" tabindex="1" disabled="true"><option>Not tabbable</option></select>',605 '<textarea id="test33">Tabbable</textarea>',606 '<textarea id="test34" tabindex="-1">Not tabbable</textarea>',607 '<textarea id="test35" tabindex="0" disabled="1">Not tabbable</textarea>',608 '<p id="test36">Not tabbable</p>',609 '<div>'610 ]);611 });612 describe("all nodes", function() {613 it("should find all tabbable elements including self by default", function() {614 var els = el.findTabbableElements();615 expect(els.length).toBe(14);616 });617 });618 describe("children", function() {619 var els;620 beforeEach(function() {621 els = el.findTabbableElements({622 skipSelf: true623 });624 });625 it("should find all tabbable sub-elements", function() {626 expect(els.length).toBe(13);627 });628 it("should return correct sub-elements in correct order", function() {629 expect(els[0].id).toBe('test7');630 expect(els[1].id).toBe('test9');631 expect(els[2].id).toBe('test3');632 expect(els[3].id).toBe('test5');633 expect(els[4].id).toBe('test13');634 expect(els[5].id).toBe('test15');635 expect(els[6].id).toBe('test17');636 expect(els[7].id).toBe('test21');637 expect(els[8].id).toBe('test23');638 expect(els[9].id).toBe('test25');639 expect(els[10].id).toBe('test27');640 expect(els[11].id).toBe('test30');641 expect(els[12].id).toBe('test33');642 });643 });644 describe("excludeRoot", function() {645 var els, test1;646 beforeEach(function() {647 test1 = Ext.fly('test1');648 els = el.findTabbableElements({649 skipSelf: true,650 excludeRoot: test1651 });652 });653 it("should exclude nodes within excludeRoot", function() {654 expect(els.length).toBe(11);655 });656 it("should return correct children in order", function() {657 expect(els[0].id).toBe('test7');658 expect(els[1].id).toBe('test9');659 expect(els[2].id).toBe('test13');660 expect(els[3].id).toBe('test15');661 expect(els[4].id).toBe('test17');662 expect(els[5].id).toBe('test21');663 expect(els[6].id).toBe('test23');664 expect(els[7].id).toBe('test25');665 expect(els[8].id).toBe('test27');666 expect(els[9].id).toBe('test30');667 expect(els[10].id).toBe('test33');668 });669 });670 describe("nested tabbable elements", function() {671 beforeEach(function() {672 createElement(useFly, [673 '<div id="window-1009" tabindex="-1">',674 '<div id="window-1009-tabGuardBeforeEl" tabindex="0"></div>',675 '<div id="window-1009_header" tabindex="0">',676 '<div id="window-1009_header-innerCt">',677 '<div id="window-1009_header-targetEl">',678 '<div id="window-1009_header-title">',679 '<div id="window-1009_header-title-textEl">foo</div>',680 '</div>',681 '<div id="tool-1015" tabindex="-1">',682 '<div id="tool-1015-toolEl"></div>',683 '</div>',684 '<div id="tool-1016" tabindex="-1">',685 '<div id="tool-1016-toolEl"></div>',686 '</div>',687 '</div>',688 '</div>',689 '</div>',690 '<div id="window-1009-body">',691 '<div id="window-1009-outerCt">',692 '<div id="window-1009-innerCt">',693 '<div id="window-1009-formWrap">',694 '<div id="textfield-1010">',695 '<label id="textfield-1010-labelEl" for="textfield-1010-inputEl">',696 '<span>foo:</span>',697 '</label>',698 '<div id="textfield-1010-bodyEl">',699 '<div id="textfield-1010-triggerWrap">',700 '<div id="textfield-1010-inputWrap">',701 '<input id="textfield-1010-inputEl" type="text" />',702 '</div>',703 '</div>',704 '<div id="textfield-1010-ariaErrorEl"></div>',705 '</div>',706 '</div>',707 '<div id="textfield-1011">',708 '<label id="textfield-1011-labelEl" for="textfield-1011-inputEl">',709 '<span>bar:</span>',710 '</label>',711 '<div id="textfield-1011-bodyEl">',712 '<div id="textfield-1011-triggerWrap">',713 '<div id="textfield-1011-inputWrap">',714 '<input id="textfield-1011-inputEl" type="text" />',715 '</div>',716 '</div>',717 '<div id="textfield-1011-ariaErrorEl"></div>',718 '</div>',719 '</div>',720 '</div>',721 '</div>',722 '</div>',723 '</div>',724 '<div id="toolbar-1012" tabindex="0">',725 '<div id="toolbar-1012-innerCt">',726 '<div id="toolbar-1012-targetEl">',727 '<a id="button-1013" tabindex="-1">OK</a>',728 '<a id="button-1014" tabindex="-1">Cancel</a>',729 '</div>',730 '</div>',731 '</div>',732 '<div id="window-1009-tabGuardAfterEl" tabindex="0"></div>',733 '</div>'734 ]);735 });736 it("should return elements in the right order", function() {737 var els = topEl.findTabbableElements();738 expect(els[0].id).toBe('window-1009-tabGuardBeforeEl');739 expect(els[1].id).toBe('window-1009_header');740 expect(els[2].id).toBe('textfield-1010-inputEl');741 expect(els[3].id).toBe('textfield-1011-inputEl');742 expect(els[4].id).toBe('toolbar-1012');743 expect(els[5].id).toBe('window-1009-tabGuardAfterEl');744 });745 });746 });747 describe("state attributes", function() {748 function createSuite(name, elConfig, selector, deep) {749 return describe(name, function() {750 var defaultAttr = Ext.Element.tabbableSavedValueAttribute,751 counterAttr = Ext.Element.tabbableSavedCounterAttribute;752 beforeEach(function() {753 createElement(useFly, elConfig, selector);754 });755 it("should be tabbable before the test (sanity check)", function() {756 expect(el.isTabbable()).toBeTruthy();757 });758 describe("saving", function() {759 beforeEach(function() {760 el.saveTabbableState({761 skipSelf: false,762 skipChildren: !deep763 });764 });765 it("should have the tabbable state saved", function() {766 var attr = el.getAttribute(defaultAttr);767 expect(attr).toBeTruthy();768 });769 it("should become non-tabbable", function() {770 expect(el.isTabbable()).toBeFalsy();771 });772 it("should set the counter", function() {773 var counter = +el.getAttribute(counterAttr);774 expect(counter).toBe(1);775 });776 it("should increment the counter", function() {777 el.saveTabbableState({778 skipSelf: false,779 skipChildren: !deep780 });781 var counter = +el.getAttribute(counterAttr);782 expect(counter).toBe(2);783 });784 });785 describe("restoring", function() {786 it("should be tabbable before the test (sanity check)", function() {787 expect(el.isTabbable()).toBeTruthy();788 });789 describe("saved", function() {790 beforeEach(function() {791 el.saveTabbableState({792 skipSelf: false,793 skipChildren: !deep794 });795 el.restoreTabbableState();796 });797 it("should have the saved attribute removed", function() {798 var hasIt = dom.hasAttribute(defaultAttr);799 expect(hasIt).toBeFalsy();800 });801 it("should be tabbable again", function() {802 expect(el.isTabbable()).toBe(true);803 });804 it("should remove the counter", function() {805 var hasIt = dom.hasAttribute(counterAttr);806 expect(hasIt).toBeFalsy();807 });808 });809 describe("counter", function() {810 beforeEach(function() {811 el.saveTabbableState({812 skipSelf: false,813 skipChildren: !deep814 });815 el.saveTabbableState({816 skipSelf: false,817 skipChildren: !deep818 });819 });820 it("should have counter set (sanity check)", function() {821 var counter = +el.getAttribute(counterAttr);822 expect(counter).toBe(2);823 });824 describe("> 0", function() {825 beforeEach(function() {826 el.restoreTabbableState();827 });828 it("should not restore tabbability", function() {829 expect(el.isTabbable()).toBe(false);830 });831 it("should decrement the counter", function() {832 var counter = +el.getAttribute(counterAttr);833 expect(counter).toBe(1);834 });835 });836 describe("reset", function() {837 beforeEach(function() {838 el.restoreTabbableState({ reset: true });839 });840 it("should restore tabbability", function() {841 expect(el.isTabbable()).toBe(true);842 });843 it("should remove the counter", function() {844 expect(el).not.toHaveAttr(counterAttr);845 });846 });847 });848 });849 });850 }851 // Standalone elements852 createSuite('a w/ href', { tag: 'a', href: '#' });853 createSuite('button', { tag: 'button' });854 createSuite('input', { tag: 'input', type: 'text' });855 createSuite('div', { tag: 'div', tabIndex: 0 });856 // Hierarchies857 createSuite('div w/ children', {858 tag: 'div',859 tabIndex: 0,860 cn: [{861 tag: 'div',862 tabIndex: 1,863 id: 'foo',864 cn: [{865 tag: 'div',866 tabIndex: 2867 }]868 }]869 }, '#foo', true);870 });871 describe("state", function() {872 function createSuite(name, elConfig, selector, deep) {873 return describe(name, function() {874 describe(name + " saving", function() {875 beforeEach(function() {876 createElement(useFly, elConfig, selector);877 });878 it("should be tabbable before the test (sanity check)", function() {879 expect(el.isTabbable()).toBe(true);880 });881 describe(name + " element", function() {882 beforeEach(function() {883 el.saveTabbableState({884 skipSelf: false,885 skipChildren: true886 });887 });888 it("should be removed from tab order", function() {889 expect(el.isTabbable()).toBe(false);890 });891 if (deep) {892 it("should not disable children tabbable state", function() {893 var cn = el.findTabbableElements({894 skipSelf: true895 });896 expect(cn.length).toBeTruthy();897 });898 }899 });900 if (deep) {901 describe(name + " children", function() {902 beforeEach(function() {903 el.saveTabbableState({904 skipSelf: false,905 skipChildren: !deep906 });907 });908 it("should remove children from tab order", function() {909 var cn = el.findTabbableElements({910 skipSelf: true911 });912 expect(cn.length).toBe(0);913 });914 });915 }916 });917 describe(name + " restoring", function() {918 var saved;919 beforeEach(function() {920 createElement(useFly, elConfig, selector);921 saved = undefined;922 });923 it("should be tabbable before the test (sanity check)", function() {924 expect(el.isTabbable()).toBe(true);925 });926 describe(name + " element saved", function() {927 beforeEach(function() {928 saved = dom.getAttribute('tabIndex');929 el.saveTabbableState();930 });931 it("should not be tabbable when state is saved", function() {932 expect(el.isTabbable()).toBe(false);933 });934 describe(name + " element restored", function() {935 beforeEach(function() {936 el.restoreTabbableState();937 });938 it("should have the tabIndex attribute restored", function() {939 var idx = dom.getAttribute('tabIndex');940 expect(idx).toBe(saved);941 });942 it("should be tabbable again", function() {943 expect(el.isTabbable()).toBe(true);944 });945 });946 });947 if (deep) {948 describe(name + " children saved", function() {949 beforeEach(function() {950 saved = el.saveTabbableState({951 skipSelf: true,952 skipChildren: !deep953 }) || [];954 });955 it("should have no tabbable children when saved", function() {956 var cn = el.findTabbableElements({957 skipSelf: true958 });959 expect(cn.length).toBe(0);960 });961 describe(name + " children restored", function() {962 beforeEach(function() {963 el.restoreTabbableState({ skipSelf: true });964 });965 it("should have the same number of tabbable children", function() {966 var cn = el.findTabbableElements({967 skipSelf: true968 });969 expect(cn.length).toBe(saved.length);970 });971 it("should have the same tabbable children", function() {972 var cn = el.findTabbableElements({973 skipSelf: true974 });975 for (var i = 0; i < saved.length; i++) {976 var c1 = saved[i],977 c2 = cn[i];978 expect(c1.id).toBe(c2.id);979 }980 });981 });982 });983 }984 });985 });986 }987 createSuite('anchor with href natural', { tag: 'a', href: '#' });988 createSuite('anchor with href w/ tabIndex', { tag: 'a', href: '#', tabIndex: 0 });989 createSuite('anchor w/o href', { tag: 'a', tabIndex: 0 });990 createSuite('anchor w/o href w/ children', {991 tag: 'a',992 tabIndex: 0,993 cn: [{994 tag: 'div',995 tabIndex: 1996 }]997 }, '', true);998 createSuite('button natural', { tag: 'button' });999 createSuite('button w/ tabIndex', { tag: 'button', tabIndex: 0 });1000 createSuite('iframe natural', { tag: 'iframe' });1001 createSuite('iframe w/ tabIndex', { tag: 'iframe', tabIndex: 42 });1002 createSuite('input natural', { tag: 'input' });1003 createSuite('input w/ tabIndex', { tag: 'input', tabIndex: 1 });1004 createSuite('select natural', {1005 tag: 'select',1006 cn: [{1007 tag: 'option',1008 value: 'foo'1009 }]1010 });1011 createSuite('select w/ tabIndex', {1012 tag: 'select',1013 tabIndex: 100,1014 cn: [{1015 tag: 'option',1016 value: 'bar'1017 }]1018 });1019 createSuite('textarea natural', { tag: 'textarea' });1020 createSuite('textarea w/ tabIndex', { tag: 'textarea', tabIndex: 1 });1021 createSuite('div', { tag: 'div', tabIndex: 0 });1022 createSuite('div w/ children', {1023 tag: 'div',1024 tabIndex: 0,1025 cn: [{1026 tag: 'div',1027 tabIndex: 1,1028 cn: [{1029 tag: 'div',1030 tabIndex: 21031 }]1032 }]1033 }, '', true);1034 createSuite('span', { tag: 'span', tabIndex: 0 });1035 createSuite('p', { tag: 'p', tabIndex: 0 });1036 createSuite('img', { tag: 'img', tabIndex: 0 });1037 createSuite('ul li', {1038 tag: 'ul',1039 tabIndex: 0,1040 cn: [{1041 tag: 'li',1042 tabIndex: 11043 }, {1044 tag: 'li',1045 tabIndex: 21046 }]1047 }, null, true);1048 createSuite('ol li', {1049 tag: 'ol',1050 tabIndex: 100,1051 cn: [{1052 tag: 'li',1053 tabIndex: 1011054 }, {1055 tag: 'li',1056 tabIndex: 1021057 }]1058 }, null, true);1059 createSuite('table', {1060 tag: 'table',1061 tabIndex: 0,1062 cn: [{1063 tag: 'tr',1064 cn: [{1065 tag: 'td',1066 tabIndex: 1,1067 html: ' '1068 }, {1069 tag: 'td',1070 tabIndex: 2,1071 html: ' '1072 }]1073 }]...
Using AI Code Generation
1const qawolf = require("qawolf");2const { createSuite } = qawolf;3(async () => {4 const browser = await qawolf.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.click("input[name=q]");8 await page.fill("input[name=q]", "qawolf");9 await page.press("input[name=q]", "Enter");10 await page.click("text=QA Wolf: End-to-end testing for everyone");11 await page.click("text=Sign up");12 await page.click("input[name=email]");13 await page.fill("input[name=email]", "
Using AI Code Generation
1const { createSuite } = require('qawolf');2const { launch } = require('qawolf');3const { create } = require('qawolf');4const { click } = require('qawolf');5const { type } = require('qawolf');6const { select } = require('qawolf');7const { press } = require('qawolf');8const { waitFor } = require('qawolf');9const { closeBrowser } = require('qawolf');10const { stop } = require('qawolf');11const { browser } = require('qawolf');12const { context } = require('qawolf');13const { page } = require('qawolf');14const { context } = require('qawolf');15const { page } = require('qawolf');16const { stop } = require('qawolf');17const { browser } = require('qawolf');18const { context } = require('qawolf');19const { page } = require('qawolf');20const { stop } = require('qawolf');21const { browser } = require('qawolf');22const { context } = require('qawolf');23const { page } = require('qawolf');
Using AI Code Generation
1const { createSuite } = require('qawolf');2const { create } = require('qawolf');3const { launch } = require('qawolf');4const { newPage } = require('qawolf');5const { type } = require('qawolf');6const { click } = require('qawolf');7const { closeBrowser } = require('qawolf');8const { stopTracing } = require('qawolf');9const { stopVideos } = require('qawolf');10const { stop } = require('qawolf');11const { save } = require('qawolf');12const { click } = require('qawolf');13const { closeBrowser } = require('qawolf');14const { stopTracing } = require('qawolf');15const { stopVideos } = require('qawolf');16const { stop } = require('qawolf');17const { save } = require('qawolf');18const { click } = require('qawolf');19const { closeBrowser } = require('qawolf');20const { stopTracing } = require('qawolf');21const { stopVideos } = require('qawolf');22const { stop } = require('qawolf
Using AI Code Generation
1const { createSuite } = require("qawolf");2(async () => {3 const browser = await qawolf.launch();4 const page = await browser.newPage();5 await qawolf.type(page, "input[name='q']", "Hello world");6 await qawolf.click(page, "input[value='Google Search']");7 await createSuite({8 });9})();
Using AI Code Generation
1const { createSuite } = require("qawolf");2const suite = createSuite();3const { create } = require("qawolf");4const browser = await create();5await browser.close();6const { createBrowser } = require("qawolf");7const browser = await createBrowser();8await browser.close();9const { createPage } = require("qawolf");10const page = await createPage();11await page.close();12const { createVideo } = require("qawolf");13const video = await createVideo();14await video.close();15const { createScreenshot } = require("qawolf");16const screenshot = await createScreenshot();17await screenshot.close();18const { createBrowser } = require("qawolf");19const browser = await createBrowser();20await browser.close();21const { createPage } = require("qawolf");22const page = await createPage();23await page.close();24const { createVideo } = require("qawolf");25const video = await createVideo();26await video.close();27const { createScreenshot } = require("qawolf");28const screenshot = await createScreenshot();29await screenshot.close();30const { create } = require("qawolf");31const browser = await create();32await browser.close();33const { createBrowser } = require("qawolf");34const browser = await createBrowser();35await browser.close();36const { createPage } = require("qawolf");37const page = await createPage();38await page.close();39const { createVideo } = require("qawolf");40const video = await createVideo();41await video.close();42const { createScreenshot } = require("qawolf");43const screenshot = await createScreenshot();
Using AI Code Generation
1const { createSuite } = require("qawolf");2const path = require("path");3const suite = createSuite();4async function run() {5 const browser = await suite.launchBrowser();6 const context = await browser.newContext();7 const page = await context.newPage();8 await page.click("input[type='text']");9 await page.fill("input[type='text']", "qawolf");10 await page.press("input[type='text']", "Enter");11 await page.waitForTimeout(2000);12 await browser.close();13}14run();15suite.save(path.join(process.cwd(), "test.js"));
Using AI Code Generation
1const { createSuite } = require("qawolf");2createSuite({3 test: async (browser, helpers) => {4 await browser.type("input[name=q]", "qawolf");5 await browser.click("input[value=Google Search]");6 },7});8{9 "scripts": {10 },11 "devDependencies": {12 }13}14{15 {16 },17 {18 }19}20{21 {22 },23 {24 }25}
Using AI Code Generation
1const { createSuite } = require("qawolf");2const config = require("./qawolf.config.js");3(async () => {4})();5module.exports = {6 launchOptions: {7 },8};9at Object.createSuite (C:\Users\HP\Documents\qawolf\qawolf\src\api\createSuite.ts:44:42)10at processTicksAndRejections (internal/process/task_queues.js:97:5)
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!