var gInvalidFormPopup = document.getElementById('invalid-form-popup'); ok(gInvalidFormPopup, "The browser should have a popup to show when a form is invalid"); function checkPopupShow() { ok(gInvalidFormPopup.state == 'showing' || gInvalidFormPopup.state == 'open', "[Test " + testId + "] The invalid form popup should be shown"); } function checkPopupHide() { ok(gInvalidFormPopup.state != 'showing' && gInvalidFormPopup.state != 'open', "[Test " + testId + "] The invalid form popup should not be shown"); } function checkPopupMessage(doc) { is(gInvalidFormPopup.firstChild.textContent, doc.getElementById('i').validationMessage, "[Test " + testId + "] The panel should show the message from validationMessage"); } let gObserver = { QueryInterface : XPCOMUtils.generateQI([Ci.nsIFormSubmitObserver]), notifyInvalidSubmit : function (aFormElement, aInvalidElements) { } }; var testId = -1; function nextTest() { testId++; if (testId >= tests.length) { finish(); return; } executeSoon(tests[testId]); } function test() { waitForExplicitFinish(); waitForFocus(nextTest); } var tests = [ /** * In this test, we check that no popup appears if the form is valid. */ function() { let uri = "data:text/html,
"; let tab = gBrowser.addTab(); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); let doc = gBrowser.contentDocument; doc.getElementById('s').click(); executeSoon(function() { checkPopupHide(); // Clean-up gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that, when an invalid form is submitted, * the invalid element is focused and a popup appears. */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gInvalidFormPopup.addEventListener("popupshown", function() { gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); let doc = gBrowser.contentDocument; is(doc.activeElement, doc.getElementById('i'), "First invalid element should be focused"); checkPopupShow(); checkPopupMessage(doc); // Clean-up and next test. gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }, false); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); gBrowser.contentDocument.getElementById('s').click(); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that, when an invalid form is submitted, * the first invalid element is focused and a popup appears. */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gInvalidFormPopup.addEventListener("popupshown", function() { gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); let doc = gBrowser.contentDocument; is(doc.activeElement, doc.getElementById('i'), "First invalid element should be focused"); checkPopupShow(); checkPopupMessage(doc); // Clean-up and next test. gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }, false); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); gBrowser.contentDocument.getElementById('s').click(); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that, we hide the popup by interacting with the * invalid element if the element becomes valid. */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gInvalidFormPopup.addEventListener("popupshown", function() { gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); let doc = gBrowser.contentDocument; is(doc.activeElement, doc.getElementById('i'), "First invalid element should be focused"); checkPopupShow(); checkPopupMessage(doc); EventUtils.synthesizeKey("a", {}); executeSoon(function () { checkPopupHide(); // Clean-up and next test. gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }); }, false); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); gBrowser.contentDocument.getElementById('s').click(); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that, we don't hide the popup by interacting with the * invalid element if the element is still invalid. */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gInvalidFormPopup.addEventListener("popupshown", function() { gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); let doc = gBrowser.contentDocument; is(doc.activeElement, doc.getElementById('i'), "First invalid element should be focused"); checkPopupShow(); checkPopupMessage(doc); EventUtils.synthesizeKey("a", {}); executeSoon(function () { checkPopupShow(); // Clean-up and next test. gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }); }, false); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); gBrowser.contentDocument.getElementById('s').click(); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that we can hide the popup by blurring the invalid * element. */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gInvalidFormPopup.addEventListener("popupshown", function() { gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); let doc = gBrowser.contentDocument; is(doc.activeElement, doc.getElementById('i'), "First invalid element should be focused"); checkPopupShow(); checkPopupMessage(doc); doc.getElementById('i').blur(); executeSoon(function () { checkPopupHide(); // Clean-up and next test. gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }); }, false); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); gBrowser.contentDocument.getElementById('s').click(); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that we can hide the popup by pressing TAB. */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gInvalidFormPopup.addEventListener("popupshown", function() { gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); let doc = gBrowser.contentDocument; is(doc.activeElement, doc.getElementById('i'), "First invalid element should be focused"); checkPopupShow(); checkPopupMessage(doc); EventUtils.synthesizeKey("VK_TAB", {}); executeSoon(function () { checkPopupHide(); // Clean-up and next test. gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }); }, false); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); gBrowser.contentDocument.getElementById('s').click(); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that the popup will hide if we move to another tab. */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gInvalidFormPopup.addEventListener("popupshown", function() { gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); let doc = gBrowser.contentDocument; is(doc.activeElement, doc.getElementById('i'), "First invalid element should be focused"); checkPopupShow(); checkPopupMessage(doc); // Create a new tab and move to it. gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true}); executeSoon(function() { checkPopupHide(); // Clean-up and next test. gBrowser.removeTab(gBrowser.selectedTab); gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }); }, false); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); gBrowser.contentDocument.getElementById('s').click(); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that nothing happen (no focus nor popup) if the * invalid form is submitted in another tab than the current focused one * (submitted in background). */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gObserver.notifyInvalidSubmit = function() { executeSoon(function() { let doc = tab.linkedBrowser.contentDocument; isnot(doc.activeElement, doc.getElementById('i'), "We should not focus the invalid element when the form is submitted in background"); checkPopupHide(); // Clean-up Services.obs.removeObserver(gObserver, "invalidformsubmit"); gObserver.notifyInvalidSubmit = function () {}; gBrowser.removeTab(tab); nextTest(); }); }; Services.obs.addObserver(gObserver, "invalidformsubmit", false); tab.linkedBrowser.addEventListener("load", function(e) { // Ignore load events from the iframe. if (tab.linkedBrowser.contentDocument == e.target) { let browser = e.currentTarget; browser.removeEventListener("load", arguments.callee, true); isnot(gBrowser.selectedTab.linkedBrowser, browser, "This tab should have been loaded in background"); browser.contentDocument.getElementById('s').click(); } }, true); tab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that the author defined error message is shown. */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gInvalidFormPopup.addEventListener("popupshown", function() { gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); let doc = gBrowser.contentDocument; is(doc.activeElement, doc.getElementById('i'), "First invalid element should be focused"); checkPopupShow(); is(gInvalidFormPopup.firstChild.textContent, "foo", "The panel should show the author defined error message"); // Clean-up and next test. gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }, false); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); gBrowser.contentDocument.getElementById('s').click(); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, /** * In this test, we check that the message is correctly updated when it changes. */ function() { let uri = "data:text/html,"; let tab = gBrowser.addTab(); gInvalidFormPopup.addEventListener("popupshown", function() { gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false); let doc = gBrowser.contentDocument; let input = doc.getElementById('i'); is(doc.activeElement, input, "First invalid element should be focused"); checkPopupShow(); is(gInvalidFormPopup.firstChild.textContent, input.validationMessage, "The panel should show the current validation message"); input.addEventListener('input', function() { input.removeEventListener('input', arguments.callee, false); executeSoon(function() { // Now, the element suffers from another error, the message should have // been updated. is(gInvalidFormPopup.firstChild.textContent, input.validationMessage, "The panel should show the current validation message"); // Clean-up and next test. gBrowser.removeTab(gBrowser.selectedTab); nextTest(); }); }, false); EventUtils.synthesizeKey('f', {}); }, false); tab.linkedBrowser.addEventListener("load", function(aEvent) { tab.linkedBrowser.removeEventListener("load", arguments.callee, true); gBrowser.contentDocument.getElementById('s').click(); }, true); gBrowser.selectedTab = tab; gBrowser.selectedTab.linkedBrowser.loadURI(uri); }, ];