1<!doctype html> 2<!-- 3@license 4Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 5This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 6The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 7The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 8Code distributed by Google as part of the polymer project is also 9subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 10--> 11<html> 12<head> 13 <title>active-state</title> 14 15 <script src="../../webcomponentsjs/webcomponents-lite.js"></script> 16 <script src="../../web-component-tester/browser.js"></script> 17 <script src="../../iron-test-helpers/mock-interactions.js"></script> 18 <link rel="import" href="test-elements.html"> 19 <link rel="import" href="../../paper-input/paper-input.html"> 20</head> 21<body> 22 <test-fixture id="TrivialActiveState"> 23 <template> 24 <test-button></test-button> 25 </template> 26 </test-fixture> 27 28 <test-fixture id="ToggleActiveState"> 29 <template> 30 <test-button toggles></test-button> 31 </template> 32 </test-fixture> 33 34 <test-fixture id="ButtonWithNativeInput"> 35 <template> 36 <test-light-dom><input id="input"></test-light-dom> 37 </template> 38 </test-fixture> 39 40 <test-fixture id="ButtonWithPaperInput"> 41 <template> 42 <test-light-dom><paper-input id="input"></paper-input></test-light-dom> 43 </template> 44 </test-fixture> 45 46 <script> 47 suite('active-state', function() { 48 var activeTarget; 49 50 setup(function() { 51 activeTarget = fixture('TrivialActiveState'); 52 }); 53 54 suite('active state with toggles attribute', function() { 55 setup(function() { 56 activeTarget = fixture('ToggleActiveState'); 57 }); 58 59 suite('when down', function() { 60 test('is pressed', function() { 61 MockInteractions.down(activeTarget); 62 expect(activeTarget.hasAttribute('pressed')).to.be.eql(true); 63 }); 64 }); 65 66 suite('when clicked', function() { 67 test('is activated', function(done) { 68 MockInteractions.downAndUp(activeTarget, function() { 69 try { 70 expect(activeTarget.hasAttribute('active')).to.be.eql(true); 71 expect(activeTarget.hasAttribute('aria-pressed')).to.be.eql(true); 72 expect(activeTarget.getAttribute('aria-pressed')).to.be.eql('true'); 73 done(); 74 } catch (e) { 75 done(e); 76 } 77 }); 78 }); 79 80 test('is deactivated by a subsequent click', function(done) { 81 MockInteractions.downAndUp(activeTarget, function() { 82 MockInteractions.downAndUp(activeTarget, function() { 83 try { 84 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 85 expect(activeTarget.hasAttribute('aria-pressed')).to.be.eql(true); 86 expect(activeTarget.getAttribute('aria-pressed')).to.be.eql('false'); 87 done(); 88 } catch (e) { 89 done(e); 90 } 91 }); 92 }); 93 }); 94 95 test('the correct aria attribute is set', function(done) { 96 activeTarget.ariaActiveAttribute = 'aria-checked'; 97 MockInteractions.downAndUp(activeTarget, function() { 98 try { 99 expect(activeTarget.hasAttribute('active')).to.be.eql(true); 100 expect(activeTarget.hasAttribute('aria-checked')).to.be.eql(true); 101 expect(activeTarget.getAttribute('aria-checked')).to.be.eql('true'); 102 done(); 103 } catch (e) { 104 done(e); 105 } 106 }); 107 }); 108 109 test('the aria attribute is updated correctly', function(done) { 110 activeTarget.ariaActiveAttribute = 'aria-checked'; 111 MockInteractions.downAndUp(activeTarget, function() { 112 try { 113 expect(activeTarget.hasAttribute('active')).to.be.eql(true); 114 expect(activeTarget.hasAttribute('aria-checked')).to.be.eql(true); 115 expect(activeTarget.getAttribute('aria-checked')).to.be.eql('true'); 116 117 activeTarget.ariaActiveAttribute = 'aria-pressed'; 118 expect(activeTarget.hasAttribute('aria-checked')).to.be.eql(false); 119 expect(activeTarget.hasAttribute('aria-pressed')).to.be.eql(true); 120 expect(activeTarget.getAttribute('aria-pressed')).to.be.eql('true'); 121 done(); 122 } catch (e) { 123 done(e); 124 } 125 }); 126 }); 127 }); 128 129 suite('on blur', function() { 130 test('the pressed property becomes false', function() { 131 MockInteractions.focus(activeTarget); 132 MockInteractions.down(activeTarget); 133 expect(activeTarget.hasAttribute('pressed')).to.be.eql(true); 134 MockInteractions.blur(activeTarget); 135 expect(activeTarget.hasAttribute('pressed')).to.be.eql(false); 136 }); 137 }); 138 }); 139 140 suite('without toggles attribute', function() { 141 suite('when mouse is down', function() { 142 test('does not get an active attribute', function() { 143 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 144 MockInteractions.down(activeTarget); 145 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 146 }); 147 }); 148 149 suite('when mouse is up', function() { 150 test('does not get an active attribute', function() { 151 MockInteractions.down(activeTarget); 152 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 153 MockInteractions.up(activeTarget); 154 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 155 }); 156 }); 157 }); 158 159 suite('when space is pressed', function() { 160 test('triggers a click event', function(done) { 161 activeTarget.addEventListener('click', function() { 162 done(); 163 }); 164 MockInteractions.pressSpace(activeTarget); 165 }); 166 167 test('only triggers click after the key is released', function(done) { 168 var keyupTriggered = false; 169 170 activeTarget.addEventListener('keyup', function() { 171 keyupTriggered = true; 172 }); 173 174 activeTarget.addEventListener('click', function() { 175 try { 176 expect(keyupTriggered).to.be.eql(true); 177 done(); 178 } catch (e) { 179 done(e); 180 } 181 }); 182 183 MockInteractions.pressSpace(activeTarget); 184 }); 185 }); 186 187 suite('when enter is pressed', function() { 188 test('triggers a click event', function(done) { 189 activeTarget.addEventListener('click', function() { 190 done(); 191 }); 192 193 MockInteractions.pressEnter(activeTarget); 194 }); 195 196 test('only triggers click before the key is released', function(done) { 197 var keyupTriggered = false; 198 199 activeTarget.addEventListener('keyup', function() { 200 keyupTriggered = true; 201 }); 202 203 activeTarget.addEventListener('click', function() { 204 try { 205 expect(keyupTriggered).to.be.eql(false); 206 done(); 207 } catch (e) { 208 done(e); 209 } 210 }); 211 212 MockInteractions.pressEnter(activeTarget); 213 }); 214 }); 215 216 suite('nested native input inside button', function() { 217 test('space in light child input does not trigger a button click event', function(done) { 218 var item = fixture('ButtonWithNativeInput'); 219 var input = item.querySelector('#input'); 220 221 var itemClickHandler = sinon.spy(); 222 item.addEventListener('click', itemClickHandler); 223 224 input.focus(); 225 MockInteractions.pressSpace(input); 226 Polymer.Base.async(function(){ 227 expect(itemClickHandler.callCount).to.be.equal(0); 228 done(); 229 }, 1); 230 }); 231 232 test('space in button triggers a button click event', function(done) { 233 var item = fixture('ButtonWithNativeInput'); 234 var input = item.querySelector('#input'); 235 236 var itemClickHandler = sinon.spy(); 237 item.addEventListener('click', itemClickHandler); 238 239 MockInteractions.pressSpace(item); 240 241 Polymer.Base.async(function(){ 242 // You need two ticks, one for the MockInteractions event, and one 243 // for the button event. 244 Polymer.Base.async(function(){ 245 expect(itemClickHandler.callCount).to.be.equal(1); 246 done(); 247 }, 1); 248 }, 1); 249 }); 250 }); 251 252 suite('nested paper-input inside button', function() { 253 test('space in light child input does not trigger a button click event', function(done) { 254 var item = fixture('ButtonWithPaperInput'); 255 var input = item.querySelector('#input'); 256 257 var itemClickHandler = sinon.spy(); 258 item.addEventListener('click', itemClickHandler); 259 260 input.focus(); 261 MockInteractions.pressSpace(input); 262 Polymer.Base.async(function(){ 263 expect(itemClickHandler.callCount).to.be.equal(0); 264 done(); 265 }, 1); 266 }); 267 268 test('space in button triggers a button click event', function(done) { 269 var item = fixture('ButtonWithPaperInput'); 270 var input = item.querySelector('#input'); 271 272 var itemClickHandler = sinon.spy(); 273 item.addEventListener('click', itemClickHandler); 274 275 MockInteractions.pressSpace(item); 276 Polymer.Base.async(function(){ 277 // You need two ticks, one for the MockInteractions event, and one 278 // for the button event. 279 Polymer.Base.async(function(){ 280 expect(itemClickHandler.callCount).to.be.equal(1); 281 done(); 282 }, 1); 283 }, 1); 284 }); 285 }); 286 287 }); 288 </script> 289</body> 290</html> 291