browser_navigation_api_restore.js (4860B)
1 "use strict"; 2 3 const PATH = getRootDirectory(gTestPath).replace( 4 "chrome://mochitests/content/", 5 "https://example.com/" 6 ); 7 const EMPTY_URL = PATH + "empty.html"; 8 const EMPTY_FRAME_URL = PATH + "empty_frame.html"; 9 10 add_setup(async () => { 11 await SpecialPowers.pushPrefEnv({ 12 set: [["dom.navigation.webidl.enabled", true]], 13 }); 14 }); 15 16 async function checkNavigationEntries(browser, urls, inFrame = null) { 17 let entryUrls = await SpecialPowers.spawn(browser, [inFrame], aInFrame => 18 (aInFrame ? content.frames[0].navigation : content.navigation) 19 .entries() 20 .map(entry => entry.url) 21 ); 22 for (const [entryUrl, expectedUrl] of urls.map((expected, i) => [ 23 entryUrls[i], 24 expected, 25 ])) { 26 is(entryUrl, expectedUrl); 27 } 28 } 29 30 add_task(async function test_toplevel_fragment_navigations() { 31 let tab = BrowserTestUtils.addTab(gBrowser, EMPTY_URL); 32 let browser = tab.linkedBrowser; 33 await promiseBrowserLoaded(browser); 34 35 let hashes = ["#1", "#2", "#3"]; 36 for (const hash of hashes) { 37 await SpecialPowers.spawn(browser, [hash], async url => { 38 content.history.pushState(null, "", url); 39 }); 40 } 41 await SpecialPowers.spawn(browser, [], async () => { 42 content.history.back(); 43 }); 44 45 let expectedUrls = ["", ...hashes].map(hash => `${EMPTY_URL}${hash}`); 46 await checkNavigationEntries(browser, expectedUrls); 47 48 await TabStateFlusher.flush(browser); 49 let { entries } = JSON.parse(ss.getTabState(tab)); 50 is(entries.length, 4); 51 52 await SessionStoreTestUtils.closeTab(tab); 53 tab = ss.undoCloseTab(window, 0); 54 await promiseTabRestored(tab); 55 browser = tab.linkedBrowser; 56 57 await checkNavigationEntries(browser, expectedUrls); 58 59 gBrowser.removeTab(tab); 60 }); 61 62 add_task(async function test_frame_fragment_navigations() { 63 let tab = BrowserTestUtils.addTab(gBrowser, EMPTY_FRAME_URL); 64 let browser = tab.linkedBrowser; 65 await promiseBrowserLoaded(browser); 66 67 let hashes = ["#1", "#2", "#3"]; 68 for (const hash of hashes) { 69 await SpecialPowers.spawn(browser, [hash], async url => { 70 content.frames[0].history.pushState(null, "", url); 71 }); 72 } 73 await SpecialPowers.spawn(browser, [], async () => { 74 content.history.back(); 75 }); 76 77 let expectedUrls = ["", ...hashes].map(hash => `${EMPTY_URL}${hash}`); 78 await checkNavigationEntries(browser, expectedUrls, true); 79 80 await TabStateFlusher.flush(browser); 81 let { entries } = JSON.parse(ss.getTabState(tab)); 82 is(entries.length, 4); 83 84 await SessionStoreTestUtils.closeTab(tab); 85 tab = ss.undoCloseTab(window, 0); 86 await promiseTabRestored(tab); 87 browser = tab.linkedBrowser; 88 89 await checkNavigationEntries(browser, expectedUrls, true); 90 91 gBrowser.removeTab(tab); 92 }); 93 94 add_task(async function test_mixed_fragment_navigations() { 95 let tab = BrowserTestUtils.addTab(gBrowser, EMPTY_FRAME_URL); 96 let browser = tab.linkedBrowser; 97 await promiseBrowserLoaded(browser); 98 99 let hashes = ["#frame1", "#frame2", "#frame3"]; 100 101 await SpecialPowers.spawn(browser, [], async () => { 102 content.frames[0].history.pushState(null, "", "#frame1"); 103 content.frames[0].history.pushState(null, "", "#frame2"); 104 content.history.pushState(null, "", "#top"); 105 content.frames[0].history.pushState(null, "", "#frame3"); 106 }); 107 108 let expectedTopUrls = ["", "#top"].map(hash => `${EMPTY_FRAME_URL}${hash}`); 109 await checkNavigationEntries(browser, expectedTopUrls); 110 let expectedFrameUrls = ["", ...hashes].map(hash => `${EMPTY_URL}${hash}`); 111 await checkNavigationEntries(browser, expectedFrameUrls, true); 112 113 await TabStateFlusher.flush(browser); 114 let { entries } = JSON.parse(ss.getTabState(tab)); 115 is(entries.length, 5, "Got expected number of history entries"); 116 117 await SessionStoreTestUtils.closeTab(tab); 118 tab = ss.undoCloseTab(window, 0); 119 await promiseTabRestored(tab); 120 browser = tab.linkedBrowser; 121 122 await checkNavigationEntries(browser, expectedTopUrls); 123 await checkNavigationEntries(browser, expectedFrameUrls, true); 124 125 gBrowser.removeTab(tab); 126 }); 127 128 add_task(async function test_toplevel_navigations() { 129 let tab = BrowserTestUtils.addTab(gBrowser, EMPTY_URL); 130 let browser = tab.linkedBrowser; 131 await promiseBrowserLoaded(browser); 132 133 let urls = ["entry1.html", "entry2.html", "entry3.html"].map( 134 url => `${PATH}${url}` 135 ); 136 for (const url of urls) { 137 BrowserTestUtils.startLoadingURIString(browser, url); 138 await BrowserTestUtils.browserLoaded(browser); 139 } 140 141 let expectedUrls = [EMPTY_URL, ...urls]; 142 await checkNavigationEntries(browser, expectedUrls); 143 144 await TabStateFlusher.flush(browser); 145 let { entries } = JSON.parse(ss.getTabState(tab)); 146 is(entries.length, 4); 147 148 await SessionStoreTestUtils.closeTab(tab); 149 tab = ss.undoCloseTab(window, 0); 150 await promiseTabRestored(tab); 151 browser = tab.linkedBrowser; 152 153 await checkNavigationEntries(browser, expectedUrls); 154 155 gBrowser.removeTab(tab); 156 });