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
688 lines (591 loc) • 20.8 kB
HTML
<html>
<head>
<title>Dialog Widget Automated (non-robot) Tests</title>
<script src="boilerplate.js"></script>
<script type="text/javascript">
require([
"doh/runner",
"dojo/_base/declare", "dojo/dom", "dojo/dom-geometry", "dojo/dom-style", "dojo/window",
"dijit/focus", "dijit/registry", "dijit/Dialog", "dijit/DialogUnderlay", "dijit/_WidgetBase",
"dijit/tests/helpers", "dojo/domReady!"
], function(doh, declare, dom, domGeom, domStyle, winUtils,
focus, registry, Dialog, DialogUnderlay, _WidgetBase, helpers){
// Non robot tests to see if nested dialogs work correctly
// when obscured dialogs are destroyed/hidden, on race conditions of
// multiple dialogs fading in/out at once, etc.
doh.register("setup", function(){
// Start focus on a button on the page (although we aren't going
// to click the button)
var d = new doh.Deferred();
setTimeout(d.getTestErrback(function(){
dom.byId("button").focus();
setTimeout(d.getTestCallback(function(){
doh.is("button", focus.curNode.id, "focus is on the main page");
}), 100);
}), 300);
return d;
});
doh.register("out-of-order dialog hide/destroy", [
{
name: "open first dialog",
timeout: 10000,
runTest: function(){
var d = new doh.Deferred(),
dlg1;
// Create and show first dialog
dlg1 = new Dialog({
id: "dlg1",
title: "dialog 1",
content:
"<input id='dlg1_inputA'><br>" +
"<input id='dlg1_inputB'><br>" +
"<input id='dlg1_inputC'><br>" +
"<input id='dlg1_inputD'><br>" +
"<input id='dlg1_inputE'><br>" +
"<input id='dlg1_inputF'><br>" +
"<input id='dlg1_inputG'><br>" +
"<input id='dlg1_inputH'><br>"
});
dlg1.show().then(d.getTestCallback(function(){
doh.t(helpers.isVisible(dlg1), "dialog 1 is visible");
var dialog1Z = domStyle.get(dlg1.domNode, "zIndex"),
underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
doh.t(dialog1Z > underlayZ, "dialog1 (zIndex=" + dialog1Z +
") above underlay (zIndex=" + underlayZ + ")");
doh.is("dlg1_inputA", focus.curNode.id, "focus is on the first field");
// For back-compat, startup() should be called on children even if Dialog.startup()
// isn't called explicitly.
doh.t(dlg1._started, "dlg1 started");
}));
return d;
}
},
{
name: "open second dialog",
timeout: 20000,
runTest: function(){
var d = new doh.Deferred(),
dlg1 = registry.byId("dlg1"),
dlg2;
// Create and show second dialog
dlg2 = new Dialog({
id: "dlg2",
title: "dialog 2",
content:
"<input id='dlg2_inputA'><br>" +
"<input id='dlg2_inputB'><br>" +
"<input id='dlg2_inputC'><br>" +
"<input id='dlg2_inputD'><br>" +
"<input id='dlg2_inputE'><br>" +
"<input id='dlg2_inputF'><br>"
});
dlg2.show().then(d.getTestCallback(function(){
doh.t(helpers.isVisible(dlg2), "dialog 2 is visible");
var dialog1Z = domStyle.get(dlg1.domNode, "zIndex"),
dialog2Z = domStyle.get(dlg2.domNode, "zIndex"),
underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
doh.t(underlayZ > dialog1Z, "underlay (zIndex=" + underlayZ +
") above dialog1 (zIndex=" + dialog1Z + ")");
doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
") above underlay (zIndex=" + underlayZ + ")");
doh.is("dlg2_inputA", focus.curNode.id, "focus is on the first field");
}));
return d;
}
},
{
name: "destroy first dialog",
timeout: 20000,
runTest: function(){
var d = new doh.Deferred(),
dlg1 = registry.byId("dlg1"),
dlg2 = registry.byId("dlg2");
dlg1.destroy();
setTimeout(d.getTestCallback(function(){
doh.t(helpers.isVisible(dlg2), "dialog 2 is still visible");
doh.t(helpers.isVisible(DialogUnderlay._singleton), "underlay is still visible");
doh.is("dlg2_inputA", focus.curNode.id, "dialog 2 still has focus");
var dialog2Z = domStyle.get(dlg2.domNode, "zIndex"),
underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
") above underlay (zIndex=" + underlayZ + ")");
}), 2000);
return d;
}
},
{
name: "open third dialog",
timeout: 20000,
runTest: function(){
var d = new doh.Deferred(),
dlg2 = registry.byId("dlg2"),
dlg3;
// Create and show third dialog
dlg3 = new Dialog({
id: "dlg3",
title: "dialog 3",
content:
"<input id='dlg3_inputA'><br>" +
"<input id='dlg3_inputB'><br>" +
"<input id='dlg3_inputC'><br>" +
"<input id='dlg3_inputD'><br>"
});
dlg3.show().then(d.getTestCallback(function(){
doh.t(helpers.isVisible(dlg3), "dialog 3 is visible");
// Even though a dialog was deleted, the zIndex of the dialog 3
// should be above dialog 2. This test is to make sure we don't
// merely use _dialogStack.length to compute zIndex
var dialog2Z = domStyle.get(dlg2.domNode, "zIndex"),
dialog3Z = domStyle.get(dlg3.domNode, "zIndex"),
underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
doh.t(underlayZ > dialog2Z, "underlay (zIndex=" + underlayZ +
") above dialog2 (zIndex=" + dialog2Z + ")");
doh.t(dialog3Z > underlayZ, "dialog3 (zIndex=" + dialog3Z +
") above underlay (zIndex=" + underlayZ + ")");
doh.is("dlg3_inputA", focus.curNode.id, "focus is on the first field");
}));
return d;
}
},
{
name: "open fourth dialog",
timeout: 30000,
runTest: function(){
var d = new doh.Deferred(),
dlg3 = registry.byId("dlg3"),
dlg4;
// Create and show fourth dialog
dlg4 = new Dialog({
id: "dlg4",
title: "dialog 4",
content:
"<input id='dlg4_inputA'><br>" +
"<input id='dlg4_inputB'>"
});
dlg4.show().then(d.getTestCallback(function(){
doh.t(helpers.isVisible(dlg4), "dialog 4 is visible");
var dialog3Z = domStyle.get(dlg3.domNode, "zIndex"),
dialog4Z = domStyle.get(dlg4.domNode, "zIndex"),
underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
doh.t(underlayZ > dialog3Z, "underlay (zIndex=" + underlayZ +
") above dialog3 (zIndex=" + dialog3Z + ")");
doh.t(dialog4Z > underlayZ, "dialog4 (zIndex=" + dialog4Z +
") above underlay (zIndex=" + underlayZ + ")");
doh.is("dlg4_inputA", focus.curNode.id, "focus is on the first field");
}));
return d;
}
},
{
name: "hide third dialog",
timeout: 40000,
runTest: function(){
var d = new doh.Deferred(),
dlg3 = registry.byId("dlg3"),
dlg4 = registry.byId("dlg4");
dlg3.hide().then(d.getTestCallback(function(){
doh.t(helpers.isVisible(dlg4), "dialog 4 is still visible");
doh.t(helpers.isVisible(DialogUnderlay._singleton), "underlay is still visible");
doh.is("dlg4_inputA", focus.curNode.id, "dialog 4 still has focus");
var dialog4Z = domStyle.get(dlg4.domNode, "zIndex"),
underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
doh.t(dialog4Z > underlayZ, "dialog4 (zIndex=" + dialog4Z +
") above underlay (zIndex=" + underlayZ + ")");
}));
return d;
}
},
{
name: "close fourth dialog",
timeout: 30000,
runTest: function(){
var d = new doh.Deferred(),
dlg2 = registry.byId("dlg2"),
dlg3 = registry.byId("dlg3"),
dlg4 = registry.byId("dlg4");
// Closing fourth dialog should move focus to second dialog, since we already destroyed the
// third dialog. Delay needed for IE9+ where focus shift is asynchronous.
dlg4.hide().then(function(){
setTimeout(d.getTestCallback(function(){
doh.t(helpers.isHidden(dlg4), "dialog 4 is hidden");
doh.t(helpers.isHidden(dlg3), "dialog 3 is hidden");
doh.t(helpers.isVisible(dlg2), "dialog 2 is visible");
var dialog2Z = domStyle.get(dlg2.domNode, "zIndex"),
underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
") above underlay (zIndex=" + underlayZ + ")");
doh.is("dlg2_inputA", focus.curNode.id, "focus is on the first field");
}));
});
return d;
}
},
{
name: "close second dialog",
timeout: 30000,
runTest: function(){
var d = new doh.Deferred(),
dlg2 = registry.byId("dlg2");
// Since we already destroyed first dialog, closing second dialog should hide underlay and
// revert focus to the main page. Need the setTimeout() for IE9+ where focus change is not
// instant.
dlg2.hide().then(function(){
setTimeout(d.getTestCallback(function(){
doh.t(helpers.isHidden(dlg2), "dialog 4 is hidden");
doh.t(helpers.isHidden(DialogUnderlay._singleton), "underlay hidden");
doh.is("button", focus.curNode.id, "focus is on the main page");
}));
});
return d;
}
}
]);
var dlgA, dlgB;
doh.register("concurrent hide show (multiple dialogs)", {
name: "concurrent hide show",
timeout: 20000,
setUp: function(){
// Create and show first dialog
dlgA = new Dialog({
id: "dlgA",
title: "Dialog A",
content:
"<button type='button'>OK</button>"
});
dlgB = new Dialog({
id: "dlgB",
title: "dialog B",
content:
"<button type='button'>OK</button>"
});
dlgA.show();
},
runTest: function(){
var d = new doh.Deferred(),
cnt=0;
handle = setInterval(d.getTestErrback(function(){
var hidden = cnt%2 ? dlgA : dlgB,
shown = cnt%2 ? dlgB : dlgA;
if(cnt > 10){
clearInterval(handle);
handle = null;
d.callback(true);
return;
}
doh.t(helpers.isVisible(shown), shown.title + " visible");
doh.t(helpers.isHidden(hidden), hidden.title + " hidden");
doh.t(helpers.isVisible(DialogUnderlay._singleton), "underlay visible");
var shownZ = domStyle.get(shown.domNode, "zIndex"),
underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
doh.t(shownZ > underlayZ, "visible dialog (zIndex=" + shownZ +
") above underlay (zIndex=" + underlayZ + ")");
hidden.show();
shown.hide();
cnt++;
}), 1000);
return d;
},
tearDown: function(){
dlgA.hide();
dlgB.hide();
if(handle){
clearInterval(handle);
}
}
});
var slow, fast;
doh.register("fast double show", [
function create(){
console.log("creating slow, fast");
var d = new doh.Deferred();
slow = new Dialog({
id: "slow",
title: "Dialog C",
content:
"Hello world " +
"<button type='button' id='slowOK' onfocus='window.slowFocused=true;'>OK</button>" +
"<button type='button' id='slowCancel'>Cancel</button>",
duration: 500
});
fast = new Dialog({
id: "fast",
title: "dialog D",
content:
"<button type='button'>OK</button>",
duration: 100
});
},
{
name: "show Dialog C then show Dialog D before Dialog C fade-in completes",
timeout: 20000,
runTest: function(){
var d = new doh.Deferred();
slow.show();
setTimeout(d.getTestErrback(function(){
fast.show();
}), slow.duration / 2);
setTimeout(d.getTestCallback(function(){
doh.t(helpers.isVisible(slow), "dialog C visible");
doh.t(helpers.isVisible(fast), "dialog D visible");
doh.f(window.slowFocused, "dialog C never got focus")
}), slow.duration * 2);
return d;
}
},
{
name: "close dialogD",
timeout: 20000,
runTest: function(){
var d = new doh.Deferred();
fast.hide();
setTimeout(d.getTestCallback(function(){
doh.is("slowOK", focus.curNode.id, "focused to dialog C");
doh.t(window.slowFocused, "onfocus handler working");
}), fast.duration * 2);
return d;
}
},
{
name: "close dialogC",
timeout: 20000,
runTest: function(){
return slow.hide();
}
}
]);
doh.register("fast double hide", [
function create(){
var d = new doh.Deferred();
// Create a test dialog
dlg = new Dialog({
id: "doubleHide",
title: "Double Hide",
content: "Hello World",
duration: 100
});
// First show it
var secondHideCalled;
dlg.show().then(d.getTestErrback(function(){
// Then call hide(), as though user had clicked close icon.
// Return from this test when this hide() call completes.
dlg.hide().then(d.getTestCallback(function(){
doh.t(secondHideCalled, "hide() was called while hide() in progress and no problems");
dlg.hide(); // this should also have no effect
}));
// While first hide() is in progress, call hide() a few more times to make sure it
// doesn't break anything
dlg.hide(); // should do nothing
setTimeout(d.getTestErrback(function(){
dlg.hide(); // should also do nothing
secondHideCalled = true;
}), 10);
}));
return d;
}
]);
doh.register("concurrent show hide (single dialog)", [
function show(){
var d = new doh.Deferred();
var onShowCtr = 0,
dlg = new Dialog({
id: "show",
title: "onShow Dialog",
content:"Hello world ",
onShow: function(){ onShowCtr++; }
});
doh.is(1, Dialog._dialogStack.length, "initially, no dialogs in stack");
dlg.show();
doh.is(1, onShowCtr, "onShow first time");
dlg.hide();
doh.is(1, onShowCtr, "onHide first time");
dlg.show();
doh.is(2, onShowCtr, "onShow second time");
dlg.hide().then(d.getTestCallback(function(){
doh.is(2, onShowCtr, "onHide second time");
doh.is(1, Dialog._dialogStack.length, "at end, no dialogs in stack");
}));
return d;
}
]);
doh.register("zero duration", [
{
name: "open",
timeout: 10000,
runTest: function(){
dlg1 = new Dialog({
id: "dlg1",
title: "dialog 1",
duration: 0,
content: "<input id='dlg1_inputA'>"
});
var promise = dlg1.show();
doh.t(promise.isResolved(), "resolved");
doh.t(helpers.isVisible(dlg1), "dialog visible");
}
},
{
name: "close",
timeout: 10000,
runTest: function(){
var promise = dlg1.hide();
doh.t(promise.isResolved(), "resolved");
doh.t(helpers.isHidden(dlg1), "dialog hidden");
}
}
]);
doh.register("show/hide return", [
{
name: "open",
timeout: 10000,
runTest: function(){
var d = new doh.Deferred();
dlg5 = new Dialog({
id: "dlg5",
title: "dialog 1",
content: "<input id='dlg1_inputA'>"
});
// This tests that show() returns a promise.
dlg5.show().then(d.getTestCallback(function(){
// And this tests that it still returns a promise even when the Dialog is already shown.
var promise = dlg5.show();
doh.t(promise.isResolved(), "resolved");
doh.t(helpers.isVisible(dlg5), "dialog visible");
}));
return d;
}
},
{
name: "close",
timeout: 10000,
runTest: function(){
var d = new doh.Deferred();
// This tests that hide() returns a promise.
dlg5.hide().then(d.getTestCallback(function(){
// And this tests that it still returns a promise even when the Dialog is already hidden.
var promise = dlg5.hide();
doh.t(promise.isResolved(), "resolved");
doh.t(helpers.isHidden(dlg5), "dialog hidden");
}));
return d;
}
}
]);
LayoutWidget = declare(_WidgetBase, {
resize: function(dim){
this._resized = true;
this._resizeArg = dim;
}
});
doh.register("sizing", [
{
name: "href",
timeout: 10000,
runTest: function(){
hrefDlg = new Dialog({
id: "bigHref",
title: "big dialog with href",
href: "loremIpsum"
});
return hrefDlg.show().then(function(){
var dlgPos = domGeom.position(hrefDlg.domNode),
viewport = winUtils.getBox();
doh.t(dlgPos.h < viewport.h, "viewport height");
doh.t(dlgPos.y > 0, "position");
});
}
},
{
name: "resize",
timeout: 10000,
runTest: function(){
hrefDlg.resize({h: 200, w: 300});
var domPos = domGeom.position(hrefDlg.domNode);
doh.is(200, domPos.h, "domNode.h");
doh.is(300, domPos.w, "domNode.w");
// containerNode should be slightly smaller
var containerPos = domGeom.position(hrefDlg.containerNode);
doh.t(containerPos.h > 150 && containerPos.h < 190, "containerNode.h " + containerPos.h);
doh.is(298, containerPos.w, "containerNode.w");
doh.is("auto", hrefDlg.containerNode.style.overflow, "overflow style")
}
},
{
name: "single layout child",
timeout: 10000,
runTest: function(){
single = new Dialog({
id: "singleLayoutChild",
title: "single layout child",
content: "<div data-dojo-type=LayoutWidget data-dojo-id=layout1></div>"
});
// resize() should be called on the child layout widget, but without any size specified,
// because the Dialog itself doesn't have a size specified
single.show();
doh.t(layout1._resized, "resized");
doh.is(undefined, layout1._resizeArg, "resize arg");
// Calling resize on the Dialog should resize the single layout child widget
single.resize({h: 200, w: 300});
doh.isNot(undefined, layout1._resizeArg, "resize arg");
doh.t(layout1._resizeArg.h > 150 && layout1._resizeArg.h < 190, "single child resize() call param");
}
},
{
name: "multiple layout children",
timeout: 10000,
runTest: function(){
multiple = new Dialog({
id: "multipleLayoutChildren",
title: "multiple layout children",
content:
"<div data-dojo-type=LayoutWidget data-dojo-id=layout2></div>" +
"<div data-dojo-type=LayoutWidget data-dojo-id=layout3></div>"
});
// resize() should be called on each child layout widget, but without any size specified
multiple.show();
doh.t(layout2._resized, "layout2 resized");
doh.is(undefined, layout2._resizeArg, "layout2 resize arg");
doh.t(layout3._resized, "layout3 resized");
doh.is(undefined, layout3._resizeArg, "layout3 resize arg");
// Calling resize on the Dialog might resize the layout child widgets, but they still
// shouldn't get a size specified
multiple.resize({h: 200, w: 300});
doh.is(undefined, layout2._resizeArg, "layout2 resize arg after dialog resize");
doh.is(undefined, layout3._resizeArg, "layout3 resize arg after dialog resize");
}
},
// titlebar is optional for back-compat and to support dojox.image.LightboxDialog
{
name: "no titlebar node",
timeout: 10000,
runTest: function() {
noTbDialog = new Dialog({
id: "noTbDialog",
templateString: '<div style="border: 1px solid black">' +
'<span data-dojo-attach-point="closeButtonNode" role="button" tabindex="-1">x</span>' +
'<div data-dojo-attach-point="containerNode"></div>' +
"</div>",
content: "custom template w/no titlebar"
});
return noTbDialog.show().then(function () {
noTbDialog.resize({h: 200, w: 300});
var domPos = domGeom.position(noTbDialog.domNode);
doh.is(200, domPos.h, "domNode.h");
doh.is(300, domPos.w, "domNode.w");
// containerNode should be slightly smaller
var containerPos = domGeom.position(noTbDialog.containerNode);
doh.is(198, containerPos.h, "containerNode.h");
doh.is(298, containerPos.w, "containerNode.w");
});
}
}
]);
doh.run();
});
</script>
</head>
<body>
<h1 class="testTitle">Dijit Dialog Automated (non-robot) tests</h1>
<button id="button">focus point</button>
</body>
</html>