browser_tabdialogbox_focus.js (5863B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const TEST_ROOT_CHROME = getRootDirectory(gTestPath); 7 const TEST_DIALOG_PATH = TEST_ROOT_CHROME + "subdialog.xhtml"; 8 9 /** 10 * Tests that tab dialogs are focused when switching tabs. 11 */ 12 add_task(async function test_tabdialogbox_tab_switch_focus() { 13 // Open 3 tabs 14 let tabPromises = []; 15 for (let i = 0; i < 3; i += 1) { 16 tabPromises.push( 17 BrowserTestUtils.openNewForegroundTab( 18 gBrowser, 19 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 20 "http://example.com", 21 true 22 ) 23 ); 24 } 25 26 // Wait for tabs to be ready 27 let tabs = await Promise.all(tabPromises); 28 29 // Open subdialog in first two tabs 30 let dialogs = []; 31 for (let i = 0; i < 2; i += 1) { 32 let dialogBox = gBrowser.getTabDialogBox(tabs[i].linkedBrowser); 33 dialogBox.open(TEST_DIALOG_PATH); 34 dialogs.push(dialogBox.getTabDialogManager()._topDialog); 35 } 36 37 // Wait for dialogs to be ready 38 await Promise.all([dialogs[0]._dialogReady, dialogs[1]._dialogReady]); 39 40 // Switch to first tab which has dialog 41 await BrowserTestUtils.switchTab(gBrowser, tabs[0]); 42 43 // The textbox in the dialogs content window should be focused 44 let dialogTextbox = 45 dialogs[0]._frame.contentDocument.querySelector("#textbox"); 46 is(Services.focus.focusedElement, dialogTextbox, "Dialog textbox is focused"); 47 48 // Switch to second tab which has dialog 49 await BrowserTestUtils.switchTab(gBrowser, tabs[1]); 50 51 // The textbox in the dialogs content window should be focused 52 let dialogTextbox2 = 53 dialogs[1]._frame.contentDocument.querySelector("#textbox"); 54 is( 55 Services.focus.focusedElement, 56 dialogTextbox2, 57 "Dialog2 textbox is focused" 58 ); 59 60 // Switch to third tab which does not have a dialog 61 await BrowserTestUtils.switchTab(gBrowser, tabs[2]); 62 63 // Test that content is focused 64 is( 65 Services.focus.focusedElement, 66 tabs[2].linkedBrowser, 67 "Top level browser is focused" 68 ); 69 70 // Cleanup 71 tabs.forEach(tab => { 72 BrowserTestUtils.removeTab(tab); 73 }); 74 }); 75 76 /** 77 * Tests that if we're showing multiple tab dialogs they are focused in the 78 * correct order and custom focus handlers are called. 79 */ 80 add_task(async function test_tabdialogbox_multiple_focus() { 81 await BrowserTestUtils.withNewTab(gBrowser, async browser => { 82 let dialogBox = gBrowser.getTabDialogBox(browser); 83 let dialogAClose = dialogBox.open( 84 TEST_DIALOG_PATH, 85 {}, 86 { 87 testCustomFocusHandler: true, 88 } 89 ).closedPromise; 90 let dialogBClose = dialogBox.open(TEST_DIALOG_PATH).closedPromise; 91 let dialogCClose = dialogBox.open( 92 TEST_DIALOG_PATH, 93 {}, 94 { 95 testCustomFocusHandler: true, 96 } 97 ).closedPromise; 98 99 let dialogs = dialogBox._tabDialogManager._dialogs; 100 let [dialogA, dialogB, dialogC] = dialogs; 101 102 // Wait until all dialogs are ready 103 await Promise.all(dialogs.map(dialog => dialog._dialogReady)); 104 105 // Dialog A's custom focus target should be focused 106 let dialogElementA = 107 dialogA._frame.contentDocument.querySelector("#custom-focus-el"); 108 is( 109 Services.focus.focusedElement, 110 dialogElementA, 111 "Dialog A custom focus target is focused" 112 ); 113 114 // Close top dialog 115 dialogA.close(); 116 await dialogAClose; 117 118 // Dialog B's first focus target should be focused 119 let dialogElementB = 120 dialogB._frame.contentDocument.querySelector("#textbox"); 121 is( 122 Services.focus.focusedElement, 123 dialogElementB, 124 "Dialog B default focus target is focused" 125 ); 126 127 // close top dialog 128 dialogB.close(); 129 await dialogBClose; 130 131 // Dialog C's custom focus target should be focused 132 let dialogElementC = 133 dialogC._frame.contentDocument.querySelector("#custom-focus-el"); 134 is( 135 Services.focus.focusedElement, 136 dialogElementC, 137 "Dialog C custom focus target is focused" 138 ); 139 140 // Close last dialog 141 dialogC.close(); 142 await dialogCClose; 143 144 is( 145 dialogBox._tabDialogManager._dialogs.length, 146 0, 147 "All dialogs should be closed" 148 ); 149 is( 150 Services.focus.focusedElement, 151 browser, 152 "Focus should be back on the browser" 153 ); 154 }); 155 }); 156 157 /** 158 * Tests that other dialogs are still visible if one dialog is hidden. 159 */ 160 add_task(async function test_tabdialogbox_tab_switch_hidden() { 161 // Open 2 tabs 162 let tabPromises = []; 163 for (let i = 0; i < 2; i += 1) { 164 tabPromises.push( 165 BrowserTestUtils.openNewForegroundTab( 166 gBrowser, 167 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 168 "http://example.com", 169 true 170 ) 171 ); 172 } 173 174 // Wait for tabs to be ready 175 let tabs = await Promise.all(tabPromises); 176 177 // Open subdialog in tabs 178 let dialogs = []; 179 let dialogBox, dialogBoxManager, browser; 180 for (let i = 0; i < 2; i += 1) { 181 dialogBox = gBrowser.getTabDialogBox(tabs[i].linkedBrowser); 182 browser = tabs[i].linkedBrowser; 183 dialogBox.open(TEST_DIALOG_PATH); 184 dialogBoxManager = dialogBox.getTabDialogManager(); 185 dialogs.push(dialogBoxManager._topDialog); 186 } 187 188 // Wait for dialogs to be ready 189 await Promise.all([dialogs[0]._dialogReady, dialogs[1]._dialogReady]); 190 191 // Hide the top dialog 192 dialogBoxManager.hideDialog(browser); 193 194 ok( 195 BrowserTestUtils.isHidden(dialogBoxManager._dialogStack), 196 "Dialog stack is hidden" 197 ); 198 199 // Switch to first tab 200 await BrowserTestUtils.switchTab(gBrowser, tabs[0]); 201 202 // Check the dialog stack is showing in first tab 203 dialogBoxManager = gBrowser 204 .getTabDialogBox(tabs[0].linkedBrowser) 205 .getTabDialogManager(); 206 is(dialogBoxManager._dialogStack.hidden, false, "Dialog stack is showing"); 207 208 // Cleanup 209 tabs.forEach(tab => { 210 BrowserTestUtils.removeTab(tab); 211 }); 212 });