browser_dbg-blackbox.js (23633B)
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 // This test covers all the blackboxing functionality relating to a selected 6 // source open in the debugger editor. 7 8 "use strict"; 9 10 requestLongerTimeout(5); 11 12 const contextMenuItems = { 13 ignoreSource: { selector: "#node-menu-blackbox", label: "Ignore source" }, 14 unignoreSource: { selector: "#node-menu-blackbox", label: "Unignore source" }, 15 ignoreLines: { selector: "#node-menu-blackbox-lines", label: "Ignore lines" }, 16 unignoreLines: { 17 selector: "#node-menu-blackbox-lines", 18 label: "Unignore lines", 19 }, 20 ignoreLine: { selector: "#node-menu-blackbox-line", label: "Ignore line" }, 21 unignoreLine: { 22 selector: "#node-menu-blackbox-line", 23 label: "Unignore line", 24 }, 25 }; 26 27 const SOURCE_IS_FULLY_IGNORED = "source"; 28 const SOURCE_LINES_ARE_IGNORED = "line"; 29 const SOURCE_IS_NOT_IGNORED = "none"; 30 31 // Tests basic functionality for blackbox source and blackbox single and multiple lines 32 add_task(async function testAllBlackBox() { 33 // using the doc-command-click.html as it has a simple js file we can use 34 // testing. 35 const file = "simple4.js"; 36 const dbg = await initDebugger("doc-command-click.html", file); 37 38 const source = findSource(dbg, file); 39 40 await selectSource(dbg, source); 41 42 await addBreakpoint(dbg, file, 8); 43 44 await testBlackBoxSource(dbg, source); 45 await testBlackBoxMultipleLines(dbg, source); 46 await testBlackBoxSingleLine(dbg, source); 47 }); 48 49 // Test that the blackboxed lines are persisted accross reloads and still work accordingly. 50 add_task(async function testBlackBoxOnReload() { 51 const file = "simple4.js"; 52 const dbg = await initDebugger("doc-command-click.html", file); 53 54 const source = findSource(dbg, file); 55 56 await selectSource(dbg, source); 57 58 // Adding 2 breakpoints in funcB() and funcC() which 59 // would be hit in order. 60 await addBreakpoint(dbg, file, 8); 61 await addBreakpoint(dbg, file, 12); 62 63 info("Reload without any blackboxing to make all necesary postions are hit"); 64 const onReloaded = reload(dbg, file); 65 66 await waitForPaused(dbg); 67 await assertPausedAtSourceAndLine(dbg, source.id, 2); 68 await resume(dbg); 69 70 await waitForPaused(dbg); 71 await assertPausedAtSourceAndLine(dbg, source.id, 8); 72 await resume(dbg); 73 74 await waitForPaused(dbg); 75 await assertPausedAtSourceAndLine(dbg, source.id, 12); 76 await resume(dbg); 77 78 info("Wait for reload to complete after resume"); 79 await onReloaded; 80 81 assertNotPaused(dbg); 82 83 info("Ignoring line 2 using the gutter context menu"); 84 await openContextMenuInDebugger(dbg, "gutterElement", 2); 85 await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); 86 87 info("Ignoring line 7 to 9 using the editor context menu"); 88 await selectEditorLinesAndOpenContextMenu(dbg, { startLine: 7, endLine: 9 }); 89 await selectBlackBoxContextMenuItem(dbg, "blackbox-lines"); 90 91 const onReloaded2 = reload(dbg, file); 92 93 await waitForPaused(dbg); 94 await assertPausedAtSourceAndLine(dbg, source.id, 12); 95 await resume(dbg); 96 info("Wait for reload to complete after resume"); 97 await onReloaded2; 98 99 assertNotPaused(dbg); 100 101 info( 102 "Check that the expected blackbox context menu state is correct across reload" 103 ); 104 105 await assertEditorBlackBoxBoxContextMenuItems(dbg, { 106 blackboxedLine: 2, 107 nonBlackBoxedLine: 4, 108 blackBoxedLines: [7, 9], 109 nonBlackBoxedLines: [3, 4], 110 blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, 111 }); 112 113 await assertGutterBlackBoxBoxContextMenuItems(dbg, { 114 blackboxedLine: 2, 115 nonBlackBoxedLine: 4, 116 blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, 117 }); 118 119 await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { 120 blackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), 121 nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), 122 }); 123 }); 124 125 add_task(async function testBlackBoxOnToolboxRestart() { 126 const dbg = await initDebugger("doc-command-click.html", "simple4.js"); 127 const source = findSource(dbg, "simple4.js"); 128 129 await selectSource(dbg, source); 130 131 const onReloaded = reload(dbg, "simple4.js"); 132 await waitForPaused(dbg); 133 134 info("Assert it paused at the debugger statement"); 135 await assertPausedAtSourceAndLine(dbg, source.id, 2); 136 await resume(dbg); 137 await onReloaded; 138 139 info("Ignoring line 2 using the gutter context menu"); 140 await openContextMenuInDebugger(dbg, "gutterElement", 2); 141 await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); 142 143 await reloadBrowser(); 144 // Wait a little bit incase of a pause 145 await wait(1000); 146 147 info("Assert that the debugger no longer pauses on the debugger statement"); 148 assertNotPaused(dbg); 149 150 info("Close the toolbox"); 151 await dbg.toolbox.closeToolbox(); 152 153 info("Reopen the toolbox on the debugger"); 154 const toolbox = await openToolboxForTab(gBrowser.selectedTab, "jsdebugger"); 155 const dbg2 = createDebuggerContext(toolbox); 156 await waitForSelectedSource(dbg2, findSource(dbg2, "simple4.js")); 157 158 // Reloading will automatically re-apply blackboxing which triggers a RDP request. 159 // Wait for blackbox action and requests to settle to avoid unhandled promise 160 // rejections due to pending promises. 161 const onBlackboxDone = waitForDispatch(dbg2.store, "BLACKBOX_SOURCE_RANGES"); 162 await reloadBrowser(); 163 164 info("Wait for the blackbox action to complete"); 165 await onBlackboxDone; 166 await waitForRequestsToSettle(dbg); 167 168 // Wait a little incase of a pause 169 await wait(1000); 170 171 info("Assert that debbuger still does not pause on the debugger statement"); 172 assertNotPaused(dbg2); 173 }); 174 175 async function testBlackBoxSource(dbg, source) { 176 info("Start testing blackboxing the whole source"); 177 178 info("Assert the blackbox context menu items before any blackboxing is done"); 179 // When the source is not blackboxed there are no blackboxed lines 180 await assertEditorBlackBoxBoxContextMenuItems(dbg, { 181 blackboxedLine: null, 182 nonBlackBoxedLine: 4, 183 blackBoxedLines: null, 184 nonBlackBoxedLines: [3, 4], 185 blackboxedSourceState: SOURCE_IS_NOT_IGNORED, 186 }); 187 188 await assertGutterBlackBoxBoxContextMenuItems(dbg, { 189 blackboxedLine: null, 190 nonBlackBoxedLine: 4, 191 blackboxedSourceState: SOURCE_IS_NOT_IGNORED, 192 }); 193 194 await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { 195 blackBoxedSourceTreeNode: null, 196 nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), 197 }); 198 199 info( 200 "Blackbox the whole simple4.js source file using the editor context menu" 201 ); 202 await openContextMenuInDebugger(dbg, "CodeMirrorLines"); 203 await selectBlackBoxContextMenuItem(dbg, "blackbox"); 204 205 info("Assert that all lines in the source are styled correctly"); 206 await assertIgnoredStyleInSourceLines(dbg, { hasBlackboxedLinesClass: true }); 207 208 info("Assert that the source tree for simple4.js has the ignored style"); 209 const node = findSourceNodeWithText(dbg, "simple4.js"); 210 ok( 211 node.querySelector(".blackboxed"), 212 "simple4.js node does not have the ignored style" 213 ); 214 215 invokeInTab("funcA"); 216 217 info( 218 "The debugger statement on line 2 and the breakpoint on line 8 should not be hit" 219 ); 220 assertNotPaused(dbg); 221 222 info("Assert the blackbox context menu items after blackboxing is done"); 223 // When the whole source is blackboxed there are no nonBlackboxed lines 224 await assertEditorBlackBoxBoxContextMenuItems(dbg, { 225 blackboxedLine: 2, 226 nonBlackBoxedLine: null, 227 blackBoxedLines: [3, 5], 228 nonBlackBoxedLines: null, 229 blackboxedSourceState: SOURCE_IS_FULLY_IGNORED, 230 }); 231 232 await assertGutterBlackBoxBoxContextMenuItems(dbg, { 233 blackboxedLine: 2, 234 nonBlackBoxedLine: null, 235 blackboxedSourceState: SOURCE_IS_FULLY_IGNORED, 236 }); 237 238 await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { 239 blackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), 240 nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), 241 }); 242 243 info("Unblackbox the whole source using the sourcetree context menu"); 244 rightClickEl(dbg, findSourceNodeWithText(dbg, "simple4.js")); 245 await waitForContextMenu(dbg); 246 await selectBlackBoxContextMenuItem(dbg, "blackbox"); 247 248 info("Assert that all lines in the source are un-styled correctly"); 249 await assertIgnoredStyleInSourceLines(dbg, { 250 hasBlackboxedLinesClass: false, 251 }); 252 253 info( 254 "Assert that the source tree for simple4.js does not have the ignored style" 255 ); 256 const nodeAfterBlackbox = findSourceNodeWithText(dbg, "simple4.js"); 257 ok( 258 !nodeAfterBlackbox.querySelector(".blackboxed"), 259 "simple4.js node still has the ignored style" 260 ); 261 262 invokeInTab("funcA"); 263 264 info("assert the pause at the debugger statement on line 2"); 265 await waitForPaused(dbg); 266 await assertPausedAtSourceAndLine(dbg, source.id, 2); 267 await resume(dbg); 268 269 info("assert the pause at the breakpoint set on line 8"); 270 await waitForPaused(dbg); 271 await assertPausedAtSourceAndLine(dbg, source.id, 8); 272 await resume(dbg); 273 274 assertNotPaused(dbg); 275 276 // When the source is not blackboxed there are no blackboxed lines 277 await assertEditorBlackBoxBoxContextMenuItems(dbg, { 278 blackboxedLine: null, 279 nonBlackBoxedLine: 4, 280 blackBoxedLines: null, 281 nonBlackBoxedLines: [3, 4], 282 blackboxedSourceState: SOURCE_IS_NOT_IGNORED, 283 }); 284 285 await assertGutterBlackBoxBoxContextMenuItems(dbg, { 286 blackboxedLine: null, 287 nonBlackBoxedLine: 4, 288 blackboxedSourceState: SOURCE_IS_NOT_IGNORED, 289 }); 290 291 await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { 292 blackBoxedSourceTreeNode: null, 293 nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), 294 }); 295 } 296 297 async function testBlackBoxMultipleLines(dbg, source) { 298 info("Blackbox lines 7 to 13 using the editor content menu items"); 299 await selectEditorLinesAndOpenContextMenu(dbg, { startLine: 7, endLine: 13 }); 300 await selectBlackBoxContextMenuItem(dbg, "blackbox-lines"); 301 302 await assertEditorBlackBoxBoxContextMenuItems(dbg, { 303 blackboxedLine: null, 304 nonBlackBoxedLine: 3, 305 blackBoxedLines: [7, 9], 306 nonBlackBoxedLines: [3, 4], 307 blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, 308 }); 309 310 await assertGutterBlackBoxBoxContextMenuItems(dbg, { 311 blackboxedLine: null, 312 nonBlackBoxedLine: 3, 313 blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, 314 }); 315 316 await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { 317 blackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), 318 nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), 319 }); 320 321 info("Assert that the ignored lines are styled correctly"); 322 await assertIgnoredStyleInSourceLines(dbg, { 323 lines: [7, 13], 324 hasBlackboxedLinesClass: true, 325 }); 326 327 info("Assert that the source tree for simple4.js has the ignored style"); 328 const node = findSourceNodeWithText(dbg, "simple4.js"); 329 330 ok( 331 node.querySelector(".blackboxed"), 332 "simple4.js node does not have the ignored style" 333 ); 334 335 invokeInTab("funcA"); 336 337 info("assert the pause at the debugger statement on line 2"); 338 await waitForPaused(dbg); 339 await assertPausedAtSourceAndLine(dbg, source.id, 2); 340 await resume(dbg); 341 342 info( 343 "The breakpoint set on line 8 should not get hit as its within the blackboxed range" 344 ); 345 assertNotPaused(dbg); 346 347 info("Unblackbox lines 7 to 13"); 348 await selectEditorLinesAndOpenContextMenu(dbg, { startLine: 7, endLine: 13 }); 349 await selectBlackBoxContextMenuItem(dbg, "blackbox-lines"); 350 351 await assertEditorBlackBoxBoxContextMenuItems(dbg, { 352 blackboxedLine: null, 353 nonBlackBoxedLine: 4, 354 blackBoxedLines: null, 355 nonBlackBoxedLines: [3, 4], 356 blackboxedSourceState: SOURCE_IS_NOT_IGNORED, 357 }); 358 359 await assertGutterBlackBoxBoxContextMenuItems(dbg, { 360 blackboxedLine: null, 361 nonBlackBoxedLine: 4, 362 blackboxedSourceState: SOURCE_IS_NOT_IGNORED, 363 }); 364 365 await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { 366 blackBoxedSourceTreeNode: null, 367 nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), 368 }); 369 370 info("Assert that the un-ignored lines are no longer have the style"); 371 await assertIgnoredStyleInSourceLines(dbg, { 372 lines: [7, 13], 373 hasBlackboxedLinesClass: false, 374 }); 375 376 info( 377 "Assert that the source tree for simple4.js does not have the ignored style" 378 ); 379 const nodeAfterBlackbox = findSourceNodeWithText(dbg, "simple4.js"); 380 ok( 381 !nodeAfterBlackbox.querySelector(".blackboxed"), 382 "simple4.js still has the ignored style" 383 ); 384 385 invokeInTab("funcA"); 386 387 // assert the pause at the debugger statement on line 2 388 await waitForPaused(dbg); 389 await assertPausedAtSourceAndLine(dbg, source.id, 2); 390 await resume(dbg); 391 392 // assert the pause at the breakpoint set on line 8 393 await waitForPaused(dbg); 394 await assertPausedAtSourceAndLine(dbg, source.id, 8); 395 await resume(dbg); 396 397 assertNotPaused(dbg); 398 } 399 400 async function testBlackBoxSingleLine(dbg, source) { 401 info("Black box line 2 of funcA() with the debugger statement"); 402 await openContextMenuInDebugger(dbg, "gutterElement", 2); 403 await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); 404 405 await assertEditorBlackBoxBoxContextMenuItems(dbg, { 406 blackboxedLine: 2, 407 nonBlackBoxedLine: 4, 408 blackBoxedLines: null, 409 nonBlackBoxedLines: [3, 4], 410 blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, 411 }); 412 413 await assertGutterBlackBoxBoxContextMenuItems(dbg, { 414 blackboxedLine: null, 415 nonBlackBoxedLine: 4, 416 blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, 417 }); 418 419 await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { 420 blackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), 421 nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), 422 }); 423 424 info("Assert that the ignored line 2 is styled correctly"); 425 await assertIgnoredStyleInSourceLines(dbg, { 426 lines: [2], 427 hasBlackboxedLinesClass: true, 428 }); 429 430 info("Black box line 4 of funcC() with the debugger statement"); 431 await openContextMenuInDebugger(dbg, "gutterElement", 4); 432 await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); 433 434 info("Assert that the ignored line 4 is styled correctly"); 435 await assertIgnoredStyleInSourceLines(dbg, { 436 lines: [4], 437 hasBlackboxedLinesClass: true, 438 }); 439 440 invokeInTab("funcA"); 441 442 // assert the pause at the breakpoint set on line 8 443 await waitForPaused(dbg); 444 await assertPausedAtSourceAndLine(dbg, source.id, 8); 445 await resume(dbg); 446 447 assertNotPaused(dbg); 448 449 info("Un-blackbox line 2 of funcA()"); 450 await selectEditorLinesAndOpenContextMenu( 451 dbg, 452 { startLine: 2, endLine: 2 }, 453 "CodeMirrorLines" 454 ); 455 await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); 456 457 await assertEditorBlackBoxBoxContextMenuItems(dbg, { 458 blackboxedLine: 4, 459 nonBlackBoxedLine: 3, 460 blackBoxedLines: null, 461 nonBlackBoxedLines: [11, 12], 462 blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, 463 }); 464 465 await assertGutterBlackBoxBoxContextMenuItems(dbg, { 466 blackboxedLine: 4, 467 nonBlackBoxedLine: 3, 468 blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, 469 }); 470 471 await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { 472 blackBoxedSourceTreeNode: null, 473 nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), 474 }); 475 476 info("Assert that the un-ignored line 2 is styled correctly"); 477 await assertIgnoredStyleInSourceLines(dbg, { 478 lines: [2], 479 hasBlackboxedLinesClass: false, 480 }); 481 482 invokeInTab("funcA"); 483 484 // assert the pause at the debugger statement on line 2 485 await waitForPaused(dbg); 486 await assertPausedAtSourceAndLine(dbg, source.id, 2); 487 await resume(dbg); 488 489 // assert the pause at the breakpoint set on line 8 490 await waitForPaused(dbg); 491 await assertPausedAtSourceAndLine(dbg, source.id, 8); 492 await resume(dbg); 493 494 assertNotPaused(dbg); 495 } 496 497 async function assertContextMenuDisabled(dbg, selector, shouldBeDisabled) { 498 const item = await waitFor(() => findContextMenu(dbg, selector)); 499 is( 500 item.disabled, 501 shouldBeDisabled, 502 `The the context menu item is ${ 503 shouldBeDisabled ? "disabled" : "not disabled" 504 }` 505 ); 506 } 507 508 /** 509 * Asserts that the gutter blackbox context menu items which are visible are correct 510 * 511 * @param {object} dbg 512 * @param {Array} testFixtures 513 * Details needed for the assertion. Any blackboxed/nonBlackboxed lines 514 * and any blackboxed/nonBlackboxed sources 515 */ 516 async function assertGutterBlackBoxBoxContextMenuItems(dbg, testFixtures) { 517 const { blackboxedLine, nonBlackBoxedLine, blackboxedSourceState } = 518 testFixtures; 519 if (blackboxedLine) { 520 info( 521 "Asserts that the gutter context menu items when clicking on the gutter of a blackboxed line" 522 ); 523 const popup = await openContextMenuInDebugger( 524 dbg, 525 "gutterElement", 526 blackboxedLine 527 ); 528 // When the whole source is blackboxed the the gutter visually shows `ignore line` 529 // but it is disabled indicating that individual lines cannot be nonBlackboxed. 530 const item = 531 blackboxedSourceState == SOURCE_IS_FULLY_IGNORED 532 ? contextMenuItems.ignoreLine 533 : contextMenuItems.unignoreLine; 534 535 await assertContextMenuLabel(dbg, item.selector, item.label); 536 await assertContextMenuDisabled( 537 dbg, 538 item.selector, 539 blackboxedSourceState == SOURCE_IS_FULLY_IGNORED 540 ); 541 await closeContextMenu(dbg, popup); 542 } 543 544 if (nonBlackBoxedLine) { 545 info( 546 "Asserts that the gutter context menu items when clicking on the gutter of a nonBlackboxed line" 547 ); 548 549 // Wait for CM6 to complete any updates so the popup 550 // does not lose focus while asserting the context menu items due 551 // late updates completion. 552 await waitForDocumentLoadComplete(dbg); 553 554 const popup = await openContextMenuInDebugger( 555 dbg, 556 "gutterElement", 557 nonBlackBoxedLine 558 ); 559 const item = contextMenuItems.ignoreLine; 560 await assertContextMenuLabel(dbg, item.selector, item.label); 561 await assertContextMenuDisabled(dbg, item.selector, false); 562 await closeContextMenu(dbg, popup); 563 } 564 } 565 566 /** 567 * Asserts that the source tree blackbox context menu items which are visible are correct 568 * 569 * @param {object} dbg 570 * @param {Array} testFixtures 571 * Details needed for the assertion. Any blackboxed/nonBlackboxed sources 572 */ 573 async function assertSourceTreeBlackBoxBoxContextMenuItems(dbg, testFixtures) { 574 const { blackBoxedSourceTreeNode, nonBlackBoxedSourceTreeNode } = 575 testFixtures; 576 if (blackBoxedSourceTreeNode) { 577 info( 578 "Asserts that the source tree blackbox context menu items when clicking on a blackboxed source tree node" 579 ); 580 rightClickEl(dbg, blackBoxedSourceTreeNode); 581 const popup = await waitForContextMenu(dbg); 582 const item = contextMenuItems.unignoreSource; 583 await assertContextMenuLabel(dbg, item.selector, item.label); 584 await closeContextMenu(dbg, popup); 585 } 586 587 if (nonBlackBoxedSourceTreeNode) { 588 info( 589 "Asserts that the source tree blackbox context menu items when clicking on an un-blackboxed sorce tree node" 590 ); 591 rightClickEl(dbg, nonBlackBoxedSourceTreeNode); 592 const popup = await waitForContextMenu(dbg); 593 const _item = contextMenuItems.ignoreSource; 594 await assertContextMenuLabel(dbg, _item.selector, _item.label); 595 await closeContextMenu(dbg, popup); 596 } 597 } 598 599 /** 600 * Asserts that the editor blackbox context menu items which are visible are correct 601 * 602 * @param {object} dbg 603 * @param {Array} testFixtures 604 * Details needed for the assertion. Any blackboxed/nonBlackboxed lines 605 * and any blackboxed/nonBlackboxed sources 606 */ 607 async function assertEditorBlackBoxBoxContextMenuItems(dbg, testFixtures) { 608 const { 609 blackboxedLine, 610 nonBlackBoxedLine, 611 blackBoxedLines, 612 nonBlackBoxedLines, 613 blackboxedSourceState, 614 } = testFixtures; 615 616 if (blackboxedLine) { 617 info( 618 "Asserts the editor blackbox context menu items when right-clicking on a single blackboxed line" 619 ); 620 const popup = await selectEditorLinesAndOpenContextMenu(dbg, { 621 startLine: blackboxedLine, 622 }); 623 624 const expectedContextMenuItems = [contextMenuItems.unignoreSource]; 625 626 if (blackboxedSourceState !== SOURCE_IS_FULLY_IGNORED) { 627 expectedContextMenuItems.push(contextMenuItems.unignoreLine); 628 } 629 630 for (const expectedContextMenuItem of expectedContextMenuItems) { 631 info( 632 "Checking context menu item " + 633 expectedContextMenuItem.selector + 634 " with label " + 635 expectedContextMenuItem.label 636 ); 637 await assertContextMenuLabel( 638 dbg, 639 expectedContextMenuItem.selector, 640 expectedContextMenuItem.label 641 ); 642 } 643 await closeContextMenu(dbg, popup); 644 } 645 646 if (nonBlackBoxedLine) { 647 info( 648 "Asserts the editor blackbox context menu items when right-clicking on a single non-blackboxed line" 649 ); 650 const popup = await selectEditorLinesAndOpenContextMenu(dbg, { 651 startLine: nonBlackBoxedLine, 652 }); 653 654 const expectedContextMenuItems = [ 655 blackboxedSourceState == SOURCE_IS_NOT_IGNORED 656 ? contextMenuItems.ignoreSource 657 : contextMenuItems.unignoreSource, 658 contextMenuItems.ignoreLine, 659 ]; 660 661 for (const expectedContextMenuItem of expectedContextMenuItems) { 662 info( 663 "Checking context menu item " + 664 expectedContextMenuItem.selector + 665 " with label " + 666 expectedContextMenuItem.label 667 ); 668 await assertContextMenuLabel( 669 dbg, 670 expectedContextMenuItem.selector, 671 expectedContextMenuItem.label 672 ); 673 } 674 await closeContextMenu(dbg, popup); 675 } 676 677 if (blackBoxedLines) { 678 info( 679 "Asserts the editor blackbox context menu items when right-clicking on multiple blackboxed lines" 680 ); 681 const popup = await selectEditorLinesAndOpenContextMenu(dbg, { 682 startLine: blackBoxedLines[0], 683 endLine: blackBoxedLines[1], 684 }); 685 686 const expectedContextMenuItems = [contextMenuItems.unignoreSource]; 687 688 if (blackboxedSourceState !== SOURCE_IS_FULLY_IGNORED) { 689 expectedContextMenuItems.push(contextMenuItems.unignoreLines); 690 } 691 692 for (const expectedContextMenuItem of expectedContextMenuItems) { 693 info( 694 "Checking context menu item " + 695 expectedContextMenuItem.selector + 696 " with label " + 697 expectedContextMenuItem.label 698 ); 699 await assertContextMenuLabel( 700 dbg, 701 expectedContextMenuItem.selector, 702 expectedContextMenuItem.label 703 ); 704 } 705 await closeContextMenu(dbg, popup); 706 } 707 708 if (nonBlackBoxedLines) { 709 info( 710 "Asserts the editor blackbox context menu items when right-clicking on multiple non-blackboxed lines" 711 ); 712 const popup = await selectEditorLinesAndOpenContextMenu(dbg, { 713 startLine: nonBlackBoxedLines[0], 714 endLine: nonBlackBoxedLines[1], 715 }); 716 717 const expectedContextMenuItems = [ 718 blackboxedSourceState == SOURCE_IS_NOT_IGNORED 719 ? contextMenuItems.ignoreSource 720 : contextMenuItems.unignoreSource, 721 ]; 722 723 if (blackboxedSourceState !== SOURCE_IS_FULLY_IGNORED) { 724 expectedContextMenuItems.push(contextMenuItems.ignoreLines); 725 } 726 727 for (const expectedContextMenuItem of expectedContextMenuItems) { 728 info( 729 "Checking context menu item " + 730 expectedContextMenuItem.selector + 731 " with label " + 732 expectedContextMenuItem.label 733 ); 734 await assertContextMenuLabel( 735 dbg, 736 expectedContextMenuItem.selector, 737 expectedContextMenuItem.label 738 ); 739 } 740 await closeContextMenu(dbg, popup); 741 } 742 }