dijit
Version:
Dijit provides a complete collection of user interface controls based on Dojo, giving you the power to create web applications that are highly optimized for usability, performance, internationalization, accessibility, but above all deliver an incredible u
702 lines (670 loc) • 24.4 kB
HTML
<html>
<head>
<title>doh.robot Spinner Test</title>
<style>
@import "../../../../util/doh/robot/robot.css";
</style>
<!-- required: dojo.js -->
<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dijit.robotx");
dojo.ready(function(){
var spin1;
var spin2;
var spin3;
var spinnerIds = ["integerspinner1", "integerspinner2", "integertextbox3", "realspinner1"];
doh.robot.initRobot('../test_Spinner.html');
// focus handlers for noticing tab/shift+tab navigation
var focusCountZ = 0;
var blurCountZ = 0;
var countFocus = function(){
focusCountZ++;
};
var countBlur = function(){
blurCountZ++;
};
var focusConnect;
var blurConnect;
var tabFocusSetup = function(inSpinnerId){
var spinner = dijit.byId(inSpinnerId);
dijit.byId('integerspinner1').focus();
focusCountZ = 0;
blurCountZ = 0;
focusConnect = spinner.connect(spinner.focusNode, "onfocus", countFocus);
blurConnect = spinner.connect(spinner.focusNode, "onblur", countBlur);
};
// Setup to test manipulation of spinner via keystrokes.
var results; // array holding both expected value and actual value after each keypress
var strokeIndex = 0;
var noteConnect;
function keyStrokeSetup(inSpinnerId){
// summary:
// Populates results[] with expected values after each keypress.
// Also sets up listener to every keyboard event (arrow key etc) on a spinner and
// records to record the actual spinner values into results[].
var spinner = dijit.byId(inSpinnerId);
results = populateExpected(spinner);
strokeIndex = 0;
noteConnect = spinner.connect(spinner.focusNode, "onkeydown", function(){
setTimeout(function(){
results[strokeIndex].actual = spinner.get('value');
strokeIndex++;
}, 5);
});
}
// Use spinner api to calculate values for a set of keystrokes.
// Returns array of expected values.
var populateExpected = function(/*Spinner Widget*/inSpinner){
var initVal = inSpinner.get('value');
var eVals = [];
var newVal;
var i;
// The values expected by pressing HOME, right arrow five times,
// PgUp twice, PgDn, up arrow twice, down arrow once,
// left arrow once, and END.
if(inSpinner.constraints.min){
inSpinner.set('value', inSpinner.constraints.min);
}
newVal = inSpinner.get('value');
eVals.push({stroke: "HOME", expected: newVal});
// UP 5 times
for(i = 0; i < 5; i++){
newVal = inSpinner.adjust(newVal, inSpinner.smallDelta);
inSpinner.set('value', newVal);
newVal = inSpinner.get('value');
eVals.push({stroke: "UP", expected: newVal});
}
// PgUp twice
for(i = 0; i < 2; i++){
newVal = inSpinner.adjust(newVal, inSpinner.largeDelta);
inSpinner.set('value', newVal);
newVal = inSpinner.get('value');
eVals.push({stroke: "PgUp", expected: newVal});
}
// PgDn once.
newVal = inSpinner.adjust(newVal, -inSpinner.largeDelta);
inSpinner.set('value', newVal);
newVal = inSpinner.get('value');
eVals.push({stroke: "PgDn", expected: newVal});
// DOWN
newVal = inSpinner.adjust(newVal, -inSpinner.smallDelta);
inSpinner.set('value', newVal);
newVal = inSpinner.get('value');
eVals.push({stroke: "DOWN", expected: newVal});
// END
if(inSpinner.constraints.max){
inSpinner.set('value', inSpinner.constraints.max);
}
newVal = inSpinner.get('value');
eVals.push({stroke: "END", expected: newVal});
// reset <inSpinner> back to its initial value, and return
inSpinner.set('value', initVal);
return eVals;
};
// execute some test as soon as the widget gets focus
var focusThenRun = function(widget, fcn){
if(!widget.focused){
var handler = widget.connect(widget, '_onFocus', function(){
widget.disconnect(handler);
setTimeout(fcn, 1);
});
widget.focus();
}else{
fcn();
}
};
// common robot TAB-focus test function.
var a11yTabFocus = function(inSpinnerId){
var d = new doh.Deferred();
var spinner = dijit.byId(inSpinnerId);
focusThenRun(spinner, function(){
var handler = spinner.connect(spinner, '_onBlur', function(){
spinner.disconnect(handler);
setTimeout(function(){
handler = spinner.connect(spinner, '_onFocus', function(){
spinner.disconnect(handler);
setTimeout(function(){
handler = spinner.connect(spinner, '_onBlur', function(){
spinner.disconnect(handler);
setTimeout(function(){
handler = spinner.connect(spinner, '_onFocus', function(){
spinner.disconnect(handler);
setTimeout(d.getTestCallback(function(){
spinner.disconnect(focusConnect);
spinner.disconnect(blurConnect);
doh.is(3, focusCountZ, "# of times focused (" + spinner.id + ")");
doh.is(2, blurCountZ, "# of times lost focus (" + spinner.id + ")");
}), 1);
});
doh.robot.keyPress(dojo.keys.TAB, 1, {shift:true}); // refocus
}, 1);
});
doh.robot.keyPress(dojo.keys.TAB, 1); // reblur
}, 1);
});
doh.robot.keyPress(dojo.keys.TAB, 1); // refocus
}, 1);
});
doh.robot.keyPress(dojo.keys.TAB, 1, {shift:true}); // blur
});
return d;
};
// common robot keystroke test function.
var a11yKeystrokeTest = function(inSpinnerId){
var d = new doh.Deferred();
var spinner = dijit.byId(inSpinnerId);
var initVal = spinner.get('value');
focusThenRun(spinner, function(){
doh.robot.keyPress(dojo.keys.HOME, 1);
doh.robot.keyPress(dojo.keys.UP_ARROW, 200);
doh.robot.keyPress(dojo.keys.UP_ARROW, 200);
doh.robot.keyPress(dojo.keys.UP_ARROW, 200);
doh.robot.keyPress(dojo.keys.UP_ARROW, 200);
doh.robot.keyPress(dojo.keys.UP_ARROW, 200);
doh.robot.keyPress(dojo.keys.PAGE_UP, 200);
doh.robot.keyPress(dojo.keys.PAGE_UP, 200);
doh.robot.keyPress(dojo.keys.PAGE_DOWN, 200);
doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
doh.robot.keyPress(dojo.keys.END, 200);
var testPresses = function(){
spinner.disconnect(noteConnect);
spinner.set('value', initVal);
for(var i = 0; i < results.length; i++){
var aResult = results[i];
if(!(isNaN(aResult.expected) && isNaN(aResult.actual))){
doh.is(aResult.expected, aResult.actual, aResult.stroke);
}
}
};
doh.robot.sequence(d.getTestCallback(testPresses), 1000, 1000);
});
return d;
};
doh.register("setUp",{
name: "setUp",
timeout: 5000,
setUp:function(){
spin1 = dijit.byId('integerspinner1');
spin2 = dijit.byId('integerspinner2');
spin3 = dijit.byId('realspinner1');
spin4 = dijit.byId('spinnerMinOnly');
safeClick = dojo.byId('form1');
},
runTest: function(){
// assert onChange not fired
doh.is("not fired yet!", dojo.byId('oc1').value, "onChange should not have fired");
// make sure initial values are what we expect
doh.is(1, spin1.smallDelta);
doh.is(900, spin1.get('value'), "integerspinner1");
doh.is(1000, spin2.get('value'), "integerspinner2");
doh.is(1.0, spin3.get('value'), "realspinner1");
doh.is(1.0, spin4.get('value'), "spinnerMinOnly");
}
});
doh.register("dojo.query() input by name",
dojo.map(spinnerIds, function(id){
return {
name: id,
spinner: id,
spinnerName: id,
runTest:function(){
this.spinner = dijit.byId(this.spinner);
var queried=dojo.query("input[name="+this.spinnerName+"]");
doh.is(1, queried.length,"Expected 1 spinner with name "+this.spinnerName+", found "+queried.length);
doh.is(this.spinner.valueNode, queried[0],"Spinner's valueNode did not match the one found by dojo.query.");
}
};
})
);
doh.register("a11y", [
{
name: "spinner2_typematic",
timeout: 9000,
runTest: function(){
// test typematic
var d=new doh.Deferred();
spin2.set('value', 900);
focusThenRun(spin2, function(){
doh.robot.keyDown(dojo.keys.DOWN_ARROW, 1);
doh.robot.keyUp(dojo.keys.DOWN_ARROW, 5000);
doh.robot.sequence(d.getTestCallback(function(){
var v = spin2.get('value');
doh.t(v <= 800, 'Error in typematic test. Expected <=800, got '+v);
}), 1000);
});
return d;
}
},
{
name: "spinner2_max",
timeout: 5000,
runTest: function(){
// test max with arrow key
var d=new doh.Deferred();
spin2.set('value', 1549);
focusThenRun(spin2, function(){
// press once: should move up
doh.robot.keyPress(dojo.keys.UP_ARROW, 1);
doh.robot.sequence(d.getTestErrback(function(){
doh.is(1550, spin2.get('value'), "value 1: " + spin2.get('value'));
doh.is("1550", spin2.focusNode.value, "displayed value 1: " + spin2.focusNode.value);
doh.t(spin2.isValid(), "invalid 1");
// press again: shouldn't move
doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
doh.robot.sequence(d.getTestCallback(function(){
doh.is(1550, spin2.get('value'), "value 2: " + spin2.get('value'));
doh.is("1550", spin2.focusNode.value, "displayed value 2: " + spin2.focusNode.value);
doh.t(spin2.isValid(), "invalid 2");
}), 500);
}), 500);
});
return d;
}
},
{
name: "spinner2_min",
timeout: 5000,
runTest: function(){
// test min with arrow key
var d=new doh.Deferred();
spin2.set('value', 10);
focusThenRun(spin2, function(){
// press once: should move up
doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1);
doh.robot.sequence(d.getTestErrback(function(){
doh.is(9, spin2.get('value'), "value 1: " + spin2.get('value'));
doh.is("9", spin2.focusNode.value, "displayed value 1: " + spin2.focusNode.value);
doh.t(spin2.isValid(), "invalid 1");
// press again: shouldn't move
doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
doh.robot.sequence(d.getTestCallback(function(){
doh.is(9, spin2.get('value'), "value 2: " + spin2.get('value'));
doh.is("9", spin2.focusNode.value, "displayed value 2: " + spin2.focusNode.value);
doh.t(spin2.isValid(), "invalid 2");
}), 500);
}), 500);
});
return d;
}
},
{
name: "spinner2_invalid",
timeout: 3000,
runTest: function(){
// assert invalid works
var d=new doh.Deferred();
spin2.set("value", NaN);
focusThenRun(spin2, function(){
doh.robot.typeKeys("0.5", 1, 600);
doh.robot.sequence(d.getTestCallback(function(){
doh.f(spin2.isValid(), "valid");
}), 500);
});
return d;
}
}
]);
// Test ARIA role. Since role attribute is set in template,
// checking one should be sufficient.
doh.register("a11yAriaRole",
function spinnerRole(){
var spinner = dijit.byId("integerspinner1");
doh.isNot(spinner, null, "can't find 'integerspinner1'");
doh.is(dojo.attr(spinner.focusNode, "role"), "spinbutton", spinner.id + ": aria role (spinbutton)");
}
);
// Check ARIA min/max values.
// - both min and max.
// - min, no max.
// - max, no min.
// - neither.
doh.register("a11yMinMaxValues",
[
function minAndMax(){
var spinner = dijit.byId("integerspinner2");
doh.isNot(spinner, null, "can't find 'integerspinner2'");
doh.is(spinner.focusNode.getAttribute("aria-valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
doh.is(spinner.focusNode.getAttribute("aria-valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
},
function minOnly(){
var spinner = dijit.byId("spinnerMinOnly");
doh.isNot(spinner, null, "can't find 'spinnerMinOnly'");
doh.is(spinner.focusNode.getAttribute("aria-valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
if(spinner.constraints.max){
doh.is(spinner.focusNode.getAttribute("aria-valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
}else{
if(spinner.focusNode.hasAttribute){ // not available on IE6/7
doh.f(spinner.focusNode.hasAttribute("aria-valuemax"), spinner.id + ": aria-valuemax");
}
}
},
function maxOnly(){
var spinner = dijit.byId("integertextbox3");
doh.isNot(spinner, null, "can't find 'integertextbox3'");
doh.is(spinner.focusNode.getAttribute("aria-valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
if(spinner.constraints.min){
doh.is(spinner.focusNode.getAttribute("aria-valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
}else{
if(spinner.focusNode.hasAttribute){ // not available on IE6/7
doh.f(spinner.focusNode.hasAttribute("aria-valuemin"), spinner.id + ": aria-valuemin");
}
}
},
function neitherMinNorMax(){
var spinner = dijit.byId("integertextbox3");
doh.isNot(spinner, null, "can't find 'integertextbox3'");
if(spinner.constraints.min){
doh.is(spinner.focusNode.getAttribute("aria-valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
}else{
if(spinner.focusNode.hasAttribute){ // not available on IE6/7
doh.f(spinner.focusNode.hasAttribute("aria-valuemin"), spinner.id + ": aria-valuemin");
}
}
if(spinner.constraints.max){
doh.is(spinner.focusNode.getAttribute("aria-valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
}else{
if(spinner.focusNode.hasAttribute){ // not available on IE6/7
doh.f(spinner.focusNode.hasAttribute("aria-valuemax"), spinner.id + ": aria-valuemax");
}
}
}
]
);
// Loop to test each spinner for aria-valuenow
// TODO:
// Is testing one spinner sufficient?
//
// test aria valuemin, valuemax, valuenow.
doh.register("a11yValueNow",
dojo.map(spinnerIds, function(id){
return {
name: id+"_value",
spinnerId: id,
runTest:function(){
var spinner = dijit.byId(this.spinnerId);
spinner.set('value', 100);
var ariaVal = spinner.focusNode.getAttribute("aria-valuenow");
doh.is(100, ariaVal, spinner.id + ": aria-valuenow");
}
};
})
);
// test "null" aria-valuenow
/* Remove null aria-valuenow test until #7866 is resolved
doh.register("a11yNullValuenow", {
name:spinnerIds[i]+"_nullValueNow",
spinnerId:spinnerIds[i],
runTest:function(){
var spinner = dijit.byId(this.spinnerId);
var initVal = spinner.get('value');
spinner.set('value', null);
var spinnerVal = spinner.get('value');
var nowVal = spinner.focusNode.getAttribute("aria-valuenow");
var invalid = spinner.focusNode.getAttribute("aria-invalid");
spinner.set('value', initVal);
doh.t(invalid, spinner.id + ": aria-invalid");
if(!(isNaN(spinnerVal) && isNaN(nowVal))){
doh.is(spinnerVal, nowVal, spinner.id + ": null aria-valuenow");
}
}
});
*/
// a11y tab focus tests (robot)
doh.register("a11yTabFocus",
[
// don't test integerspinner1 since shift-tab from there goes to address bar and the robot doesn't like that at all
{
name:"integertextbox3TabFocus",
timeout:3000,
setUp:function(){
tabFocusSetup("integertextbox3");
},
runTest:function(){
return a11yTabFocus("integertextbox3");
}
},
{ // test integerspinner2 second since the previous test group already had it focused
name:"integerspinner2TabFocus",
timeout:3000,
setUp:function(){
tabFocusSetup("integerspinner2");
},
runTest:function(){
return a11yTabFocus("integerspinner2");
}
},
{
name:"realspinner1TabFocus",
timeout:3000,
setUp:function(){
tabFocusSetup("realspinner1");
},
runTest:function(){
return a11yTabFocus("realspinner1");
}
}
]);
// a11y keystroke tests
doh.register("a11yKeystrokes",
[
{
name:"integerspinner1Keystrokes",
timeout:9000,
setUp:function(){
keyStrokeSetup("integerspinner1");
},
runTest:function(){
return a11yKeystrokeTest("integerspinner1");
}
},
{
name:"integerspinner2Keystrokes",
timeout:9000,
setUp:function(){
keyStrokeSetup("integerspinner2");
},
runTest:function(){
return a11yKeystrokeTest("integerspinner2");
}
},
{
name:"integertextbox3Keystrokes",
timeout:9000,
setUp:function(){
keyStrokeSetup("integertextbox3");
},
runTest:function(){
return a11yKeystrokeTest("integertextbox3");
}
},
{
name:"realspinner1Keystrokes",
timeout:9000,
setUp:function(){
keyStrokeSetup("realspinner1");
},
runTest:function(){
return a11yKeystrokeTest("realspinner1");
}
}
]);
// exponential value keystroke tests
doh.register("exponential",
[
{
name: "spinnerMinOnly large exp",
timeout: 5000,
runTest: function(){
var d=new doh.Deferred();
spin4.set("value", NaN);
focusThenRun(spin4, function(){
var handler = spin4.connect(spin4, '_onBlur',
function(){
spin4.disconnect(handler);
setTimeout(d.getTestCallback(function(){
doh.f(spin4.isValid(false), "large exponential is invalid");
doh.f(spin4.isInRange(false), "large exponential is out of range");
doh.is(spin4.getErrorMessage(true), spin4.rangeMessage, "large exponential showing out of range message");
doh.is("5e+98", spin4.get('displayedValue'), "large exponential reformatted to standard form");
}), 150);
});
doh.robot.typeKeys("0.5e99", 1, 1200);
doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
});
return d;
}
},
{
name: "spinnerMinOnly adjust small exp",
timeout: 5000,
runTest: function(){
var d=new doh.Deferred();
spin4.set("value", NaN);
focusThenRun(spin4, function(){
var handler = spin4.connect(spin4, '_onBlur',
function(){
spin4.disconnect(handler);
setTimeout(d.getTestCallback(function(){
doh.t(spin4.isValid(false), "small exponential is valid");
doh.t(spin4.isInRange(false), "small exponential is in range");
doh.is(500000000.1, spin4.get('value'), "small exponential converted to whole number");
doh.is("500,000,000.1", spin4.get('displayedValue'), "small exponential converted to whole number with formatting");
}), 150);
});
doh.robot.typeKeys("0.5e9", 1, 1000);
doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
});
return d;
}
},
{
name: "spinnerMinOnly adjust max exp",
timeout: 9000,
runTest: function(){
var d=new doh.Deferred();
spin4.set("value", NaN);
focusThenRun(spin4, function(){
var handler = spin4.connect(spin4, '_onBlur',
function(){
spin4.disconnect(handler);
setTimeout(d.getTestCallback(function(){
doh.t(spin4.isValid(false), "large exponential converted to max is valid");
doh.t(spin4.isInRange(false), "max value is in range");
doh.is(89999999999999.9, spin4.get('value'), "max value (-.1)");
doh.is("89,999,999,999,999.9", spin4.get('displayedValue'), "max value (-.1) with formatting");
}), 150);
});
doh.robot.typeKeys("0.5e99", 1, 1200);
doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // convert to max
doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
});
return d;
}
}
]);
// invalid editing keystroke tests
doh.register("invalid editing",
[
{
name: "HOME key, out of range",
timeout: 5000,
runTest: function(){
var d=new doh.Deferred();
spin4.set("value", NaN);
focusThenRun(spin4, function(){
doh.robot.typeKeys("0.5e99", 1, 1200);
doh.robot.keyPress(dojo.keys.HOME, 500);
doh.robot.sequence(d.getTestCallback(function(){
doh.t(spin4.isValid(true), "HOME changed large exponential to valid min, value is instead: "+spin4.focusNode.value);
doh.t(spin4.isInRange(true), "HOME changed large exponential to in range");
doh.is(-10.9, spin4.get('value'), "HOME changed large exponential to min value");
doh.is("-10.9", spin4.get('displayedValue'), "HOME changed large exponential to min display");
}), 500);
});
return d;
}
},
{
name: "HOME key, invalid",
timeout: 9000,
runTest: function(){
var d=new doh.Deferred();
spin4.set("value", NaN);
focusThenRun(spin4, function(){
doh.robot.typeKeys(".5e9a", 1, 1000);
doh.robot.keyPress(dojo.keys.HOME, 500);
if(dojo.isMac){
doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {meta:true});
}
doh.robot.typeKeys("1", 500, 200);
doh.robot.keyPress(dojo.keys.END, 500);
if(dojo.isMac){
doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {meta:true});
}
doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
doh.robot.sequence(d.getTestCallback(function(){
doh.t(spin4.isValid(true), "edited exponential is now valid");
doh.is(1.5e+9, spin4.get('value'), "edited exponential");
}), 500);
});
return d;
}
},
{
name: "out-of-range formatting",
timeout: 5000,
runTest: function(){
var d=new doh.Deferred();
spin3.set("value", NaN);
focusThenRun(spin3, function(){
var handler = spin3.connect(spin3, '_onBlur',
function(){
spin3.disconnect(handler);
setTimeout(d.getTestCallback(function(){
doh.f(spin3.isValid(), "out-of-range is invalid");
doh.is('156.0', spin3.get('displayedValue'), "fraction not removed from out-of-range");
doh.is(156, spin3.get('value'), "out-of-range number returns number");
}), 150);
});
doh.robot.typeKeys("156.0", 1, 1000);
doh.robot.keyPress(dojo.keys.TAB, 500);
});
return d;
}
}
]);
doh.register("rounding",
[
{
name: "simple",
timeout: 5000,
runTest: function(){
var d=new doh.Deferred();
var spinner = dijit.byId("integertextbox3");
spinner.set('value', '');
focusThenRun(spinner, function(){
var handler = spinner.connect(spinner, '_onBlur',
function(){
spinner.disconnect(handler);
setTimeout(d.getTestCallback(function(){
doh.t(spinner.isValid(false), "no error when rounding");
doh.is(1.234, spinner.get('value'), "value is rounded");
doh.is("1.234", spinner.get('displayedValue'), "rounded value correctly displayed");
}), 150);
});
doh.robot.typeKeys("1.2339", 1, 1200);
doh.robot.keyPress(dojo.keys.TAB, 500);
});
return d;
}
}
]);
doh.run();
});
</script>
</head>
</html>