browser_dbg-reducer-cleanup-on-target-removal.js (5469B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ 4 5 // Verify that reducers are cleared on target removal 6 7 "use strict"; 8 9 const testServer = createVersionizedHttpTestServer( 10 "examples/sourcemaps-reload-uncompressed" 11 ); 12 const IFRAME_TEST_URL = testServer.urlFor("index.html"); 13 14 // Embed the integration test page into an iframe 15 const TEST_URI = `https://example.com/document-builder.sjs?html= 16 <iframe src="${encodeURI(IFRAME_TEST_URL)}"></iframe><body>`; 17 18 add_task(async function () { 19 await pushPref("devtools.debugger.map-scopes-enabled", true); 20 const dbg = await initDebuggerWithAbsoluteURL(TEST_URI); 21 22 const frameBC = await SpecialPowers.spawn( 23 gBrowser.selectedBrowser, 24 [], 25 function () { 26 return content.document.querySelector("iframe").browsingContext; 27 } 28 ); 29 30 info("Pause on an original source to ensure filling the reducers"); 31 await waitForSource(dbg, "original.js"); 32 await selectSource(dbg, "original.js"); 33 await addBreakpoint(dbg, "original.js", 8); 34 35 // The following task will never resolve as the call to foo() 36 // will be paused and never released 37 PromiseTestUtils.allowMatchingRejectionsGlobally( 38 /Actor 'SpecialPowers' destroyed before query 'Spawn'/ 39 ); 40 SpecialPowers.spawn(frameBC, [], function () { 41 return content.wrappedJSObject.foo(); 42 }); 43 44 await waitForPaused(dbg, "original.js"); 45 await assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 8); 46 // Also open the genertated source to populate the reducer for original and generated sources 47 await dbg.actions.jumpToMappedSelectedLocation(); 48 await waitForSelectedSource(dbg, "bundle.js"); 49 50 const editor = getCMEditor(dbg); 51 // There are some sources in the soource editor 52 Assert.greater( 53 editor.sourcesCount(), 54 0, 55 "Some sources exists in the source editor cache" 56 ); 57 58 // Assert that reducer do have some data before remove the target. 59 Assert.greater(dbg.selectors.getSourceCount(), 0, "Some sources exists"); 60 is(dbg.selectors.getBreakpointCount(), 1, "There is one breakpoint"); 61 is(countTabs(dbg), 2, "Two tabs are opened"); 62 Assert.greater( 63 dbg.selectors.getAllThreads().length, 64 1, 65 "There is many targets/threads involved by the intergration test" 66 ); 67 ok( 68 !!dbg.selectors.getSourcesTreeSources().length, 69 "There is sources displayed in the SourceTree" 70 ); 71 const location = dbg.selectors.getSelectedLocation(); 72 is( 73 location.source.id, 74 findSource(dbg, "bundle.js").id, 75 "The generated source is reporeted as selected" 76 ); 77 ok(!!dbg.selectors.getFocusedSourceItem(), "Has a focused source tree item"); 78 Assert.greater( 79 dbg.selectors.getExpandedState().size, 80 0, 81 "Has some expanded source tree items" 82 ); 83 let state = dbg.store.getState(); 84 85 Assert.greater(state.ast.mutableInScopeLines.size, 0, "Some scopes exists"); 86 Assert.greater( 87 state.sourceActors.mutableSourceActors.size, 88 0, 89 "Some source actor exists" 90 ); 91 Assert.greater( 92 state.sourceActors.mutableBreakableLines.size, 93 0, 94 "Some breakable line exists" 95 ); 96 Assert.greater( 97 state.sources.mutableBreakpointPositions.size, 98 0, 99 "Some breakable positions exists" 100 ); 101 Assert.greater( 102 state.sources.mutableOriginalBreakableLines.size, 103 0, 104 "Some original breakable lines exists" 105 ); 106 107 info("Remove the iframe"); 108 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { 109 content.document.querySelector("iframe").remove(); 110 }); 111 112 info("Wait for all sources to be removed"); 113 await waitFor(() => dbg.selectors.getSourceCount() == 0); 114 info("Wait for target to be removed"); 115 await waitFor(() => dbg.selectors.getAllThreads().length == 1); 116 117 // The pause thread being removed, we are no longer paused. 118 assertNotPaused(dbg); 119 120 // Assert they largest reducer data is cleared on thread removal 121 122 // First via common selectors 123 is(editor.sourcesCount(), 0, "No sources exists in the source editor cache"); 124 is(dbg.selectors.getSourceCount(), 0, "No sources exists"); 125 is(dbg.selectors.getBreakpointCount(), 0, "No breakpoints exists"); 126 is(countTabs(dbg), 0, "No tabs exists"); 127 is( 128 dbg.selectors.getAllThreads().length, 129 1, 130 "There is only the top level target/thread" 131 ); 132 is( 133 dbg.selectors.getSourcesTreeSources().length, 134 0, 135 "There is no source in the SourceTree" 136 ); 137 is( 138 dbg.selectors.getSelectedLocation(), 139 null, 140 "Selected location is nullified as the selected source has been removed" 141 ); 142 ok(!dbg.selectors.getFocusedSourceItem(), "No more focused source tree item"); 143 is( 144 dbg.selectors.getExpandedState().size, 145 0, 146 "No more expanded source tree items" 147 ); 148 149 // But also directly querying the reducer states, as we don't necessarily 150 // have selectors exposing their raw internals 151 state = dbg.store.getState(); 152 is(Object.keys(state.ast.mutableInScopeLines).length, 0, "No scopes exists"); 153 is(state.sourceActors.mutableSourceActors.size, 0, "No source actor exists"); 154 is( 155 state.sourceActors.mutableBreakableLines.size, 156 0, 157 "No breakable line exists" 158 ); 159 is( 160 state.sources.mutableBreakpointPositions.size, 161 0, 162 "No breakable positions exists" 163 ); 164 is( 165 state.sources.mutableOriginalBreakableLines.size, 166 0, 167 "No original breakable lines exists" 168 ); 169 });