browser_contextmenu.js (60899B)
1 "use strict"; 2 3 let contextMenu; 4 let LOGIN_FILL_ITEMS = ["---", null, "manage-saved-logins", true]; 5 let NAVIGATION_ITEMS = 6 AppConstants.platform == "macosx" 7 ? [ 8 "context-back", 9 false, 10 "context-forward", 11 false, 12 "context-reload", 13 true, 14 "---", 15 null, 16 "context-bookmarkpage", 17 true, 18 ] 19 : [ 20 "context-navigation", 21 null, 22 [ 23 "context-back", 24 false, 25 "context-forward", 26 false, 27 "context-reload", 28 true, 29 "context-bookmarkpage", 30 true, 31 ], 32 null, 33 "---", 34 null, 35 ]; 36 37 const askChatMenu = [ 38 "context-ask-chat", 39 true, 40 // Need a blank entry here because the Ask Chat submenu is dynamically built with no ids. 41 "", 42 null, 43 ]; 44 let hasStripOnShare = Services.prefs.getBoolPref( 45 "privacy.query_stripping.strip_on_share.enabled" 46 ); 47 let hasContainers = 48 Services.prefs.getBoolPref("privacy.userContext.enabled") && 49 ContextualIdentityService.getPublicIdentities().length; 50 51 const hasSelectTranslations = 52 Services.prefs.getBoolPref("browser.translations.enable") && 53 Services.prefs.getBoolPref("browser.translations.select.enable"); 54 55 const example_base = 56 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 57 "http://example.com/browser/browser/base/content/test/contextMenu/"; 58 const about_preferences_base = "about:preferences"; 59 const chrome_base = 60 "chrome://mochitests/content/browser/browser/base/content/test/contextMenu/"; 61 const head_base = 62 "chrome://mochitests/content/browser/browser/base/content/test/contextMenu/"; 63 64 /* import-globals-from contextmenu_common.js */ 65 Services.scriptloader.loadSubScript( 66 chrome_base + "contextmenu_common.js", 67 this 68 ); 69 70 function getThisFrameSubMenu(base_menu) { 71 if (AppConstants.NIGHTLY_BUILD) { 72 let osPidItem = ["context-frameOsPid", false]; 73 base_menu = base_menu.concat(osPidItem); 74 } 75 return base_menu; 76 } 77 78 add_setup(async function () { 79 await SpecialPowers.pushPrefEnv({ 80 set: [ 81 ["test.wait300msAfterTabSwitch", true], 82 ["browser.search.separatePrivateDefault.ui.enabled", true], 83 ], 84 }); 85 }); 86 87 // Below are test cases for XUL element 88 add_task(async function test_xul_text_link_label() { 89 let url = chrome_base + "subtst_contextmenu_xul.xhtml"; 90 91 await BrowserTestUtils.openNewForegroundTab({ 92 gBrowser, 93 url, 94 waitForLoad: true, 95 waitForStateStop: true, 96 }); 97 98 await test_contextmenu( 99 "#test-xul-text-link-label", 100 [ 101 "context-openlinkintab", 102 true, 103 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 104 // We need a blank entry here because the containers submenu is 105 // dynamically generated with no ids. 106 ...(hasContainers ? ["", null] : []), 107 "context-openlink", 108 true, 109 "context-openlinkprivate", 110 true, 111 "context-previewlink", 112 true, 113 "---", 114 null, 115 "context-bookmarklink", 116 true, 117 "context-savelink", 118 true, 119 "context-copylink", 120 true, 121 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 122 "---", 123 null, 124 "context-searchselect", 125 true, 126 "context-searchselect-private", 127 true, 128 ...askChatMenu, 129 ], 130 { 131 awaitOnMenuBuilt: { 132 id: "context-ask-chat", 133 }, 134 } 135 ); 136 137 // Clean up so won't affect HTML element test cases. 138 lastElementSelector = null; 139 gBrowser.removeCurrentTab(); 140 }); 141 142 // Below are test cases for HTML element. 143 144 add_task(async function test_setup_html() { 145 let url = example_base + "subtst_contextmenu.html"; 146 147 await BrowserTestUtils.openNewForegroundTab(gBrowser, url); 148 149 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () { 150 let doc = content.document; 151 let audioIframe = doc.querySelector("#test-audio-in-iframe"); 152 // media documents always use a <video> tag. 153 let audio = audioIframe.contentDocument.querySelector("video"); 154 let videoIframe = doc.querySelector("#test-video-in-iframe"); 155 let video = videoIframe.contentDocument.querySelector("video"); 156 157 audio.loop = true; 158 audio.src = "audio.ogg"; 159 video.loop = true; 160 video.src = "video.webm"; 161 162 let awaitPause = ContentTaskUtils.waitForEvent(audio, "pause"); 163 await ContentTaskUtils.waitForCondition( 164 () => !audio.paused, 165 "Making sure audio is playing before calling pause" 166 ); 167 audio.pause(); 168 await awaitPause; 169 170 awaitPause = ContentTaskUtils.waitForEvent(video, "pause"); 171 await ContentTaskUtils.waitForCondition( 172 () => !video.paused, 173 "Making sure video is playing before calling pause" 174 ); 175 video.pause(); 176 await awaitPause; 177 }); 178 }); 179 180 let plainTextItems; 181 add_task(async function test_plaintext() { 182 await test_contextmenu("#test-text", [ 183 ...NAVIGATION_ITEMS, 184 "context-savepage", 185 true, 186 "context-selectall", 187 true, 188 "---", 189 null, 190 "context-take-screenshot", 191 true, 192 "---", 193 null, 194 ...askChatMenu, 195 "---", 196 null, 197 "context-viewsource", 198 true, 199 ]); 200 }); 201 202 const kLinkItems = [ 203 "context-openlinkintab", 204 true, 205 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 206 // We need a blank entry here because the containers submenu is 207 // dynamically generated with no ids. 208 ...(hasContainers ? ["", null] : []), 209 "context-openlink", 210 true, 211 "context-openlinkprivate", 212 true, 213 "context-previewlink", 214 true, 215 "---", 216 null, 217 "context-bookmarklink", 218 true, 219 "context-savelink", 220 true, 221 "context-copylink", 222 true, 223 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 224 "---", 225 null, 226 "context-searchselect", 227 true, 228 "context-searchselect-private", 229 true, 230 ]; 231 232 add_task(async function test_link() { 233 await test_contextmenu( 234 "#test-link", 235 [ 236 ...kLinkItems, 237 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 238 ...askChatMenu, 239 ], 240 { 241 awaitOnMenuBuilt: { 242 id: "context-ask-chat", 243 }, 244 } 245 ); 246 }); 247 248 add_task(async function test_link_in_shadow_dom() { 249 await test_contextmenu( 250 "#shadow-host", 251 [ 252 ...kLinkItems, 253 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 254 ...askChatMenu, 255 ], 256 { 257 offsetX: 6, 258 offsetY: 6, 259 awaitOnMenuBuilt: { 260 id: "context-ask-chat", 261 }, 262 } 263 ); 264 }); 265 266 add_task(async function test_linkpreviewcommand() { 267 await SpecialPowers.pushPrefEnv({ 268 set: [["browser.ml.linkPreview.prefetchOnEnable", false]], 269 }); 270 await SpecialPowers.pushPrefEnv({ 271 set: [["browser.ml.linkPreview.enabled", true]], 272 }); 273 await test_contextmenu( 274 "#test-link", 275 [ 276 "context-openlinkintab", 277 true, 278 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 279 // We need a blank entry here because the containers submenu is 280 // dynamically generated with no ids. 281 ...(hasContainers ? ["", null] : []), 282 "context-openlink", 283 true, 284 "context-openlinkprivate", 285 true, 286 "context-previewlink", 287 true, 288 "---", 289 null, 290 "context-bookmarklink", 291 true, 292 "context-savelink", 293 true, 294 "context-copylink", 295 true, 296 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 297 "---", 298 null, 299 "context-searchselect", 300 true, 301 "context-searchselect-private", 302 true, 303 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 304 ...askChatMenu, 305 ], 306 { 307 awaitOnMenuBuilt: { 308 id: "context-ask-chat", 309 }, 310 } 311 ); 312 313 await SpecialPowers.popPrefEnv(); 314 }); 315 316 add_task(async function test_linkpreviewcommand_disabled() { 317 await SpecialPowers.pushPrefEnv({ 318 set: [["browser.ml.linkPreview.enabled", false]], 319 }); 320 await test_contextmenu( 321 "#test-link", 322 [ 323 "context-openlinkintab", 324 true, 325 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 326 // We need a blank entry here because the containers submenu is 327 // dynamically generated with no ids. 328 ...(hasContainers ? ["", null] : []), 329 "context-openlink", 330 true, 331 "context-openlinkprivate", 332 true, 333 //missing context-previewlink is expected 334 "---", 335 null, 336 "context-bookmarklink", 337 true, 338 "context-savelink", 339 true, 340 "context-copylink", 341 true, 342 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 343 "---", 344 null, 345 "context-searchselect", 346 true, 347 "context-searchselect-private", 348 true, 349 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 350 ...askChatMenu, 351 ], 352 { 353 awaitOnMenuBuilt: { 354 id: "context-ask-chat", 355 }, 356 } 357 ); 358 await SpecialPowers.popPrefEnv(); 359 }); 360 361 add_task(async function test_linkpreviewcommand_not_on_text() { 362 await SpecialPowers.pushPrefEnv({ 363 set: [["browser.ml.linkPreview.prefetchOnEnable", false]], 364 }); 365 await SpecialPowers.pushPrefEnv({ 366 set: [["browser.ml.linkPreview.enabled", true]], 367 }); 368 369 // Verify that context-previewlink doesn't appear in the context menu for text elements 370 await test_contextmenu( 371 "#test-text", 372 [ 373 ...NAVIGATION_ITEMS, 374 "context-savepage", 375 true, 376 "context-selectall", 377 true, 378 "---", 379 null, 380 "context-take-screenshot", 381 true, 382 "---", 383 null, 384 ...askChatMenu, 385 "---", 386 null, 387 "context-viewsource", 388 true, 389 ], 390 { 391 awaitOnMenuBuilt: { 392 id: "context-ask-chat", 393 }, 394 } 395 ); 396 397 await SpecialPowers.popPrefEnv(); 398 }); 399 400 add_task(async function test_link_over_shadow_dom() { 401 await test_contextmenu( 402 "#shadow-host-in-link", 403 [...kLinkItems, ...askChatMenu], 404 { 405 offsetX: 6, 406 offsetY: 6, 407 awaitOnMenuBuilt: { 408 id: "context-ask-chat", 409 }, 410 } 411 ); 412 }); 413 414 add_task(async function test_mailto() { 415 await test_contextmenu( 416 "#test-mailto", 417 [ 418 "context-copyemail", 419 true, 420 "---", 421 null, 422 "context-searchselect", 423 true, 424 "context-searchselect-private", 425 true, 426 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 427 ...askChatMenu, 428 ], 429 { 430 awaitOnMenuBuilt: { 431 id: "context-ask-chat", 432 }, 433 } 434 ); 435 }); 436 437 add_task(async function test_tel() { 438 await test_contextmenu( 439 "#test-tel", 440 [ 441 "context-copyphone", 442 true, 443 "---", 444 null, 445 "context-searchselect", 446 true, 447 "context-searchselect-private", 448 true, 449 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 450 ...askChatMenu, 451 ], 452 { 453 awaitOnMenuBuilt: { 454 id: "context-ask-chat", 455 }, 456 } 457 ); 458 }); 459 460 add_task(async function test_image() { 461 for (let selector of ["#test-image", "#test-svg-image"]) { 462 await test_contextmenu( 463 selector, 464 [ 465 "context-viewimage", 466 true, 467 "context-saveimage", 468 true, 469 "context-copyimage-contents", 470 true, 471 "context-copyimage", 472 true, 473 "context-sendimage", 474 true, 475 ...getTextRecognitionItems(), 476 ...(Services.prefs.getBoolPref("browser.menu.showViewImageInfo", false) 477 ? ["context-viewimageinfo", true] 478 : []), 479 ...// The visual-search menu item is not shown on SVGs. 480 (selector != "#test-svg-image" && 481 Services.prefs.getBoolPref("browser.search.visualSearch.featureGate") 482 ? ["context-visual-search", true] 483 : []), 484 "---", 485 null, 486 "context-setDesktopBackground", 487 true, 488 "---", 489 null, 490 "context-take-screenshot", 491 true, 492 "---", 493 null, 494 ...askChatMenu, 495 ], 496 { 497 onContextMenuShown() { 498 is( 499 typeof gContextMenu.imageInfo.height, 500 "number", 501 "Should have height" 502 ); 503 is( 504 typeof gContextMenu.imageInfo.width, 505 "number", 506 "Should have width" 507 ); 508 }, 509 awaitOnMenuBuilt: { 510 id: "context-ask-chat", 511 }, 512 } 513 ); 514 } 515 }); 516 517 add_task(async function test_canvas() { 518 await test_contextmenu( 519 "#test-canvas", 520 [ 521 "context-viewimage", 522 true, 523 "context-saveimage", 524 true, 525 "---", 526 null, 527 "context-selectall", 528 true, 529 "---", 530 null, 531 "context-take-screenshot", 532 true, 533 "---", 534 null, 535 ...askChatMenu, 536 ], 537 { 538 awaitOnMenuBuilt: { 539 id: "context-ask-chat", 540 }, 541 } 542 ); 543 }); 544 545 add_task(async function test_video_ok() { 546 await SpecialPowers.pushPrefEnv({ 547 set: [["media.videocontrols.picture-in-picture.enabled", true]], 548 }); 549 550 await test_contextmenu( 551 "#test-video-ok", 552 [ 553 "context-media-play", 554 true, 555 "context-media-mute", 556 true, 557 "context-media-playbackrate", 558 null, 559 [ 560 "context-media-playbackrate-050x", 561 true, 562 "context-media-playbackrate-100x", 563 true, 564 "context-media-playbackrate-125x", 565 true, 566 "context-media-playbackrate-150x", 567 true, 568 "context-media-playbackrate-200x", 569 true, 570 ], 571 null, 572 "context-media-loop", 573 true, 574 "context-video-fullscreen", 575 true, 576 "context-media-hidecontrols", 577 true, 578 "---", 579 null, 580 "context-viewvideo", 581 true, 582 "context-video-pictureinpicture", 583 true, 584 "---", 585 null, 586 "context-video-saveimage", 587 true, 588 "context-savevideo", 589 true, 590 "context-copyvideourl", 591 true, 592 "context-sendvideo", 593 true, 594 "---", 595 null, 596 "context-take-screenshot", 597 true, 598 "---", 599 null, 600 ...askChatMenu, 601 ], 602 { 603 awaitOnMenuBuilt: { 604 id: "context-ask-chat", 605 }, 606 } 607 ); 608 609 await SpecialPowers.popPrefEnv(); 610 611 await SpecialPowers.pushPrefEnv({ 612 set: [["media.videocontrols.picture-in-picture.enabled", false]], 613 }); 614 615 await test_contextmenu( 616 "#test-video-ok", 617 [ 618 "context-media-play", 619 true, 620 "context-media-mute", 621 true, 622 "context-media-playbackrate", 623 null, 624 [ 625 "context-media-playbackrate-050x", 626 true, 627 "context-media-playbackrate-100x", 628 true, 629 "context-media-playbackrate-125x", 630 true, 631 "context-media-playbackrate-150x", 632 true, 633 "context-media-playbackrate-200x", 634 true, 635 ], 636 null, 637 "context-media-loop", 638 true, 639 "context-video-fullscreen", 640 true, 641 "context-media-hidecontrols", 642 true, 643 "---", 644 null, 645 "context-viewvideo", 646 true, 647 "---", 648 null, 649 "context-video-saveimage", 650 true, 651 "context-savevideo", 652 true, 653 "context-copyvideourl", 654 true, 655 "context-sendvideo", 656 true, 657 "---", 658 null, 659 "context-take-screenshot", 660 true, 661 "---", 662 null, 663 ...askChatMenu, 664 ], 665 { 666 awaitOnMenuBuilt: { 667 id: "context-ask-chat", 668 }, 669 } 670 ); 671 672 await SpecialPowers.popPrefEnv(); 673 }); 674 675 add_task(async function test_audio_in_video() { 676 await test_contextmenu( 677 "#test-audio-in-video", 678 [ 679 "context-media-play", 680 true, 681 "context-media-mute", 682 true, 683 "context-media-playbackrate", 684 null, 685 [ 686 "context-media-playbackrate-050x", 687 true, 688 "context-media-playbackrate-100x", 689 true, 690 "context-media-playbackrate-125x", 691 true, 692 "context-media-playbackrate-150x", 693 true, 694 "context-media-playbackrate-200x", 695 true, 696 ], 697 null, 698 "context-media-loop", 699 true, 700 "context-media-showcontrols", 701 true, 702 "---", 703 null, 704 "context-saveaudio", 705 true, 706 "context-copyaudiourl", 707 true, 708 "context-sendaudio", 709 true, 710 "---", 711 null, 712 ...askChatMenu, 713 ], 714 { 715 awaitOnMenuBuilt: { 716 id: "context-ask-chat", 717 }, 718 } 719 ); 720 }); 721 722 add_task(async function test_video_bad() { 723 await SpecialPowers.pushPrefEnv({ 724 set: [["media.videocontrols.picture-in-picture.enabled", true]], 725 }); 726 727 await test_contextmenu( 728 "#test-video-bad", 729 [ 730 "context-media-play", 731 false, 732 "context-media-mute", 733 false, 734 "context-media-playbackrate", 735 null, 736 [ 737 "context-media-playbackrate-050x", 738 false, 739 "context-media-playbackrate-100x", 740 false, 741 "context-media-playbackrate-125x", 742 false, 743 "context-media-playbackrate-150x", 744 false, 745 "context-media-playbackrate-200x", 746 false, 747 ], 748 null, 749 "context-media-loop", 750 true, 751 "context-video-fullscreen", 752 false, 753 "context-media-hidecontrols", 754 false, 755 "---", 756 null, 757 "context-viewvideo", 758 true, 759 "---", 760 null, 761 "context-video-saveimage", 762 false, 763 "context-savevideo", 764 true, 765 "context-copyvideourl", 766 true, 767 "context-sendvideo", 768 true, 769 "---", 770 null, 771 "context-take-screenshot", 772 true, 773 "---", 774 null, 775 ...askChatMenu, 776 ], 777 { 778 awaitOnMenuBuilt: { 779 id: "context-ask-chat", 780 }, 781 } 782 ); 783 784 await SpecialPowers.popPrefEnv(); 785 786 await SpecialPowers.pushPrefEnv({ 787 set: [["media.videocontrols.picture-in-picture.enabled", false]], 788 }); 789 790 await test_contextmenu( 791 "#test-video-bad", 792 [ 793 "context-media-play", 794 false, 795 "context-media-mute", 796 false, 797 "context-media-playbackrate", 798 null, 799 [ 800 "context-media-playbackrate-050x", 801 false, 802 "context-media-playbackrate-100x", 803 false, 804 "context-media-playbackrate-125x", 805 false, 806 "context-media-playbackrate-150x", 807 false, 808 "context-media-playbackrate-200x", 809 false, 810 ], 811 null, 812 "context-media-loop", 813 true, 814 "context-video-fullscreen", 815 false, 816 "context-media-hidecontrols", 817 false, 818 "---", 819 null, 820 "context-viewvideo", 821 true, 822 "---", 823 null, 824 "context-video-saveimage", 825 false, 826 "context-savevideo", 827 true, 828 "context-copyvideourl", 829 true, 830 "context-sendvideo", 831 true, 832 "---", 833 null, 834 "context-take-screenshot", 835 true, 836 "---", 837 null, 838 "context-ask-chat", 839 true, 840 "", 841 null, 842 ], 843 { 844 awaitOnMenuBuilt: { 845 id: "context-ask-chat", 846 }, 847 } 848 ); 849 850 await SpecialPowers.popPrefEnv(); 851 }); 852 853 add_task(async function test_video_bad2() { 854 await SpecialPowers.pushPrefEnv({ 855 set: [["media.videocontrols.picture-in-picture.enabled", true]], 856 }); 857 858 await test_contextmenu( 859 "#test-video-bad2", 860 [ 861 "context-media-play", 862 false, 863 "context-media-mute", 864 false, 865 "context-media-playbackrate", 866 null, 867 [ 868 "context-media-playbackrate-050x", 869 false, 870 "context-media-playbackrate-100x", 871 false, 872 "context-media-playbackrate-125x", 873 false, 874 "context-media-playbackrate-150x", 875 false, 876 "context-media-playbackrate-200x", 877 false, 878 ], 879 null, 880 "context-media-loop", 881 true, 882 "context-video-fullscreen", 883 false, 884 "context-media-hidecontrols", 885 false, 886 "---", 887 null, 888 "context-viewvideo", 889 false, 890 "---", 891 null, 892 "context-video-saveimage", 893 false, 894 "context-savevideo", 895 false, 896 "context-copyvideourl", 897 false, 898 "context-sendvideo", 899 false, 900 "---", 901 null, 902 "context-take-screenshot", 903 true, 904 "---", 905 null, 906 ...askChatMenu, 907 ], 908 { 909 awaitOnMenuBuilt: { 910 id: "context-ask-chat", 911 }, 912 } 913 ); 914 915 await SpecialPowers.popPrefEnv(); 916 917 await SpecialPowers.pushPrefEnv({ 918 set: [["media.videocontrols.picture-in-picture.enabled", false]], 919 }); 920 921 await test_contextmenu( 922 "#test-video-bad2", 923 [ 924 "context-media-play", 925 false, 926 "context-media-mute", 927 false, 928 "context-media-playbackrate", 929 null, 930 [ 931 "context-media-playbackrate-050x", 932 false, 933 "context-media-playbackrate-100x", 934 false, 935 "context-media-playbackrate-125x", 936 false, 937 "context-media-playbackrate-150x", 938 false, 939 "context-media-playbackrate-200x", 940 false, 941 ], 942 null, 943 "context-media-loop", 944 true, 945 "context-video-fullscreen", 946 false, 947 "context-media-hidecontrols", 948 false, 949 "---", 950 null, 951 "context-viewvideo", 952 false, 953 "---", 954 null, 955 "context-video-saveimage", 956 false, 957 "context-savevideo", 958 false, 959 "context-copyvideourl", 960 false, 961 "context-sendvideo", 962 false, 963 "---", 964 null, 965 "context-take-screenshot", 966 true, 967 "---", 968 null, 969 ...askChatMenu, 970 ], 971 { 972 awaitOnMenuBuilt: { 973 id: "context-ask-chat", 974 }, 975 } 976 ); 977 978 await SpecialPowers.popPrefEnv(); 979 }); 980 981 add_task(async function test_iframe() { 982 await test_contextmenu( 983 "#test-iframe", 984 [ 985 ...NAVIGATION_ITEMS, 986 "context-savepage", 987 true, 988 "context-selectall", 989 true, 990 "---", 991 null, 992 "context-take-screenshot", 993 true, 994 "---", 995 null, 996 ...askChatMenu, 997 "frame", 998 null, 999 getThisFrameSubMenu([ 1000 "context-showonlythisframe", 1001 true, 1002 "context-openframeintab", 1003 true, 1004 "context-openframe", 1005 true, 1006 "---", 1007 null, 1008 "context-reloadframe", 1009 true, 1010 "---", 1011 null, 1012 "context-bookmarkframe", 1013 true, 1014 "context-saveframe", 1015 true, 1016 "---", 1017 null, 1018 "context-printframe", 1019 true, 1020 "---", 1021 null, 1022 "context-viewframesource", 1023 true, 1024 "context-viewframeinfo", 1025 true, 1026 ]), 1027 null, 1028 "---", 1029 null, 1030 "context-viewsource", 1031 true, 1032 ], 1033 { 1034 awaitOnMenuBuilt: { 1035 id: "context-ask-chat", 1036 }, 1037 } 1038 ); 1039 }); 1040 1041 add_task(async function test_video_in_iframe() { 1042 await SpecialPowers.pushPrefEnv({ 1043 set: [["media.videocontrols.picture-in-picture.enabled", true]], 1044 }); 1045 1046 await test_contextmenu( 1047 "#test-video-in-iframe", 1048 [ 1049 "context-media-play", 1050 true, 1051 "context-media-mute", 1052 true, 1053 "context-media-playbackrate", 1054 null, 1055 [ 1056 "context-media-playbackrate-050x", 1057 true, 1058 "context-media-playbackrate-100x", 1059 true, 1060 "context-media-playbackrate-125x", 1061 true, 1062 "context-media-playbackrate-150x", 1063 true, 1064 "context-media-playbackrate-200x", 1065 true, 1066 ], 1067 null, 1068 "context-media-loop", 1069 true, 1070 "context-video-fullscreen", 1071 true, 1072 "context-media-hidecontrols", 1073 true, 1074 "---", 1075 null, 1076 "context-viewvideo", 1077 true, 1078 "context-video-pictureinpicture", 1079 true, 1080 "---", 1081 null, 1082 "context-video-saveimage", 1083 true, 1084 "context-savevideo", 1085 true, 1086 "context-copyvideourl", 1087 true, 1088 "context-sendvideo", 1089 true, 1090 "---", 1091 null, 1092 "context-take-screenshot", 1093 true, 1094 "---", 1095 null, 1096 ...askChatMenu, 1097 "frame", 1098 null, 1099 getThisFrameSubMenu([ 1100 "context-showonlythisframe", 1101 true, 1102 "context-openframeintab", 1103 true, 1104 "context-openframe", 1105 true, 1106 "---", 1107 null, 1108 "context-reloadframe", 1109 true, 1110 "---", 1111 null, 1112 "context-bookmarkframe", 1113 true, 1114 "context-saveframe", 1115 true, 1116 "---", 1117 null, 1118 "context-printframe", 1119 true, 1120 "---", 1121 null, 1122 "context-viewframeinfo", 1123 true, 1124 ]), 1125 null, 1126 ], 1127 { 1128 awaitOnMenuBuilt: { 1129 id: "context-ask-chat", 1130 }, 1131 } 1132 ); 1133 1134 await SpecialPowers.popPrefEnv(); 1135 1136 await SpecialPowers.pushPrefEnv({ 1137 set: [["media.videocontrols.picture-in-picture.enabled", false]], 1138 }); 1139 1140 await test_contextmenu( 1141 "#test-video-in-iframe", 1142 [ 1143 "context-media-play", 1144 true, 1145 "context-media-mute", 1146 true, 1147 "context-media-playbackrate", 1148 null, 1149 [ 1150 "context-media-playbackrate-050x", 1151 true, 1152 "context-media-playbackrate-100x", 1153 true, 1154 "context-media-playbackrate-125x", 1155 true, 1156 "context-media-playbackrate-150x", 1157 true, 1158 "context-media-playbackrate-200x", 1159 true, 1160 ], 1161 null, 1162 "context-media-loop", 1163 true, 1164 "context-video-fullscreen", 1165 true, 1166 "context-media-hidecontrols", 1167 true, 1168 "---", 1169 null, 1170 "context-viewvideo", 1171 true, 1172 "---", 1173 null, 1174 "context-video-saveimage", 1175 true, 1176 "context-savevideo", 1177 true, 1178 "context-copyvideourl", 1179 true, 1180 "context-sendvideo", 1181 true, 1182 "---", 1183 null, 1184 "context-take-screenshot", 1185 true, 1186 "---", 1187 null, 1188 ...askChatMenu, 1189 "frame", 1190 null, 1191 getThisFrameSubMenu([ 1192 "context-showonlythisframe", 1193 true, 1194 "context-openframeintab", 1195 true, 1196 "context-openframe", 1197 true, 1198 "---", 1199 null, 1200 "context-reloadframe", 1201 true, 1202 "---", 1203 null, 1204 "context-bookmarkframe", 1205 true, 1206 "context-saveframe", 1207 true, 1208 "---", 1209 null, 1210 "context-printframe", 1211 true, 1212 "---", 1213 null, 1214 "context-viewframeinfo", 1215 true, 1216 ]), 1217 null, 1218 ], 1219 { 1220 awaitOnMenuBuilt: { 1221 id: "context-ask-chat", 1222 }, 1223 } 1224 ); 1225 1226 await SpecialPowers.popPrefEnv(); 1227 }); 1228 1229 add_task(async function test_audio_in_iframe() { 1230 await test_contextmenu( 1231 "#test-audio-in-iframe", 1232 [ 1233 "context-media-play", 1234 true, 1235 "context-media-mute", 1236 true, 1237 "context-media-playbackrate", 1238 null, 1239 [ 1240 "context-media-playbackrate-050x", 1241 true, 1242 "context-media-playbackrate-100x", 1243 true, 1244 "context-media-playbackrate-125x", 1245 true, 1246 "context-media-playbackrate-150x", 1247 true, 1248 "context-media-playbackrate-200x", 1249 true, 1250 ], 1251 null, 1252 "context-media-loop", 1253 true, 1254 "---", 1255 null, 1256 "context-saveaudio", 1257 true, 1258 "context-copyaudiourl", 1259 true, 1260 "context-sendaudio", 1261 true, 1262 "---", 1263 null, 1264 ...askChatMenu, 1265 "frame", 1266 null, 1267 getThisFrameSubMenu([ 1268 "context-showonlythisframe", 1269 true, 1270 "context-openframeintab", 1271 true, 1272 "context-openframe", 1273 true, 1274 "---", 1275 null, 1276 "context-reloadframe", 1277 true, 1278 "---", 1279 null, 1280 "context-bookmarkframe", 1281 true, 1282 "context-saveframe", 1283 true, 1284 "---", 1285 null, 1286 "context-printframe", 1287 true, 1288 "---", 1289 null, 1290 "context-viewframeinfo", 1291 true, 1292 ]), 1293 null, 1294 ], 1295 { 1296 awaitOnMenuBuilt: { 1297 id: "context-ask-chat", 1298 }, 1299 } 1300 ); 1301 }); 1302 1303 add_task(async function test_image_in_iframe() { 1304 await test_contextmenu( 1305 "#test-image-in-iframe", 1306 [ 1307 "context-viewimage", 1308 true, 1309 "context-saveimage", 1310 true, 1311 "context-copyimage-contents", 1312 true, 1313 "context-copyimage", 1314 true, 1315 "context-sendimage", 1316 true, 1317 ...getTextRecognitionItems(), 1318 ...(Services.prefs.getBoolPref("browser.menu.showViewImageInfo", false) 1319 ? ["context-viewimageinfo", true] 1320 : []), 1321 ...(Services.prefs.getBoolPref("browser.search.visualSearch.featureGate") 1322 ? ["context-visual-search", true] 1323 : []), 1324 "---", 1325 null, 1326 "context-setDesktopBackground", 1327 true, 1328 "---", 1329 null, 1330 "context-take-screenshot", 1331 true, 1332 "---", 1333 null, 1334 ...askChatMenu, 1335 "frame", 1336 null, 1337 getThisFrameSubMenu([ 1338 "context-showonlythisframe", 1339 true, 1340 "context-openframeintab", 1341 true, 1342 "context-openframe", 1343 true, 1344 "---", 1345 null, 1346 "context-reloadframe", 1347 true, 1348 "---", 1349 null, 1350 "context-bookmarkframe", 1351 true, 1352 "context-saveframe", 1353 true, 1354 "---", 1355 null, 1356 "context-printframe", 1357 true, 1358 "---", 1359 null, 1360 "context-viewframeinfo", 1361 true, 1362 ]), 1363 null, 1364 ], 1365 { 1366 awaitOnMenuBuilt: { 1367 id: "context-ask-chat", 1368 }, 1369 } 1370 ); 1371 }); 1372 1373 add_task(async function test_pdf_viewer_in_iframe() { 1374 await test_contextmenu( 1375 "#test-pdf-viewer-in-frame", 1376 [ 1377 ...NAVIGATION_ITEMS, 1378 "context-savepage", 1379 true, 1380 "context-selectall", 1381 true, 1382 "---", 1383 null, 1384 "context-take-screenshot", 1385 true, 1386 "---", 1387 null, 1388 ...askChatMenu, 1389 "frame", 1390 null, 1391 getThisFrameSubMenu([ 1392 "context-showonlythisframe", 1393 true, 1394 "context-openframeintab", 1395 true, 1396 "context-openframe", 1397 true, 1398 "---", 1399 null, 1400 "context-reloadframe", 1401 true, 1402 "---", 1403 null, 1404 "context-bookmarkframe", 1405 true, 1406 "context-saveframe", 1407 true, 1408 "---", 1409 null, 1410 "context-printframe", 1411 true, 1412 "---", 1413 null, 1414 "context-viewframeinfo", 1415 true, 1416 ]), 1417 null, 1418 "---", 1419 null, 1420 "context-viewsource", 1421 true, 1422 ], 1423 { 1424 shiftkey: true, 1425 awaitOnMenuBuilt: { 1426 id: "context-ask-chat", 1427 }, 1428 } 1429 ); 1430 }); 1431 1432 add_task(async function test_textarea() { 1433 // Disabled since this is seeing spell-check-enabled 1434 // instead of spell-add-dictionaries-main 1435 todo(false, "spell checker tests are failing, bug 1246296"); 1436 1437 /* 1438 yield test_contextmenu("#test-textarea", 1439 ["context-undo", false, 1440 "context-redo", false, 1441 "---", null, 1442 "context-cut", true, 1443 "context-copy", true, 1444 "context-paste", null, 1445 "context-delete", false, 1446 "---", null, 1447 "context-selectall", true, 1448 "---", null, 1449 "spell-add-dictionaries-main", true, 1450 ], 1451 { 1452 skipFocusChange: true, 1453 } 1454 ); 1455 */ 1456 }); 1457 1458 add_task(async function test_textarea_spellcheck() { 1459 todo(false, "spell checker tests are failing, bug 1246296"); 1460 1461 /* 1462 yield test_contextmenu("#test-textarea", 1463 ["*chubbiness", true, // spelling suggestion 1464 "spell-add-to-dictionary", true, 1465 "---", null, 1466 "context-undo", false, 1467 "context-redo", false, 1468 "---", null, 1469 "context-cut", true, 1470 "context-copy", true, 1471 "context-paste", null, // ignore clipboard state 1472 "context-delete", false, 1473 "---", null, 1474 "context-selectall", true, 1475 "---", null, 1476 "spell-check-enabled", true, 1477 "spell-dictionaries", true, 1478 ["spell-check-dictionary-en-US", true, 1479 "---", null, 1480 "spell-add-dictionaries", true], null 1481 ], 1482 { 1483 waitForSpellCheck: true, 1484 offsetX: 6, 1485 offsetY: 6, 1486 postCheckContextMenuFn() { 1487 document.getElementById("spell-add-to-dictionary").doCommand(); 1488 } 1489 } 1490 ); 1491 */ 1492 }); 1493 1494 add_task(async function test_plaintext2() { 1495 await test_contextmenu("#test-text", plainTextItems); 1496 }); 1497 1498 add_task(async function test_undo_add_to_dictionary() { 1499 todo(false, "spell checker tests are failing, bug 1246296"); 1500 1501 /* 1502 yield test_contextmenu("#test-textarea", 1503 ["spell-undo-add-to-dictionary", true, 1504 "---", null, 1505 "context-undo", false, 1506 "context-redo", false, 1507 "---", null, 1508 "context-cut", true, 1509 "context-copy", true, 1510 "context-paste", null, // ignore clipboard state 1511 "context-delete", false, 1512 "context-selectall", true, 1513 "---", null, 1514 "spell-check-enabled", true, 1515 "spell-dictionaries", true, 1516 ["spell-check-dictionary-en-US", true, 1517 "---", null, 1518 "spell-add-dictionaries", true], null 1519 ], 1520 { 1521 waitForSpellCheck: true, 1522 postCheckContextMenuFn() { 1523 document.getElementById("spell-undo-add-to-dictionary") 1524 .doCommand(); 1525 } 1526 } 1527 ); 1528 */ 1529 }); 1530 1531 add_task(async function test_contenteditable() { 1532 todo(false, "spell checker tests are failing, bug 1246296"); 1533 1534 /* 1535 yield test_contextmenu("#test-contenteditable", 1536 ["spell-no-suggestions", false, 1537 "spell-add-to-dictionary", true, 1538 "---", null, 1539 "context-undo", false, 1540 "context-redo", false, 1541 "---", null, 1542 "context-cut", true, 1543 "context-copy", true, 1544 "context-paste", null, // ignore clipboard state 1545 "context-delete", false, 1546 "context-selectall", true, 1547 "---", null, 1548 "spell-check-enabled", true, 1549 "spell-dictionaries", true, 1550 ["spell-check-dictionary-en-US", true, 1551 "---", null, 1552 "spell-add-dictionaries", true], null 1553 ], 1554 {waitForSpellCheck: true} 1555 ); 1556 */ 1557 }); 1558 1559 add_task(async function test_copylinkcommand() { 1560 await test_contextmenu("#test-link", null, { 1561 async postCheckContextMenuFn() { 1562 document.commandDispatcher 1563 .getControllerForCommand("cmd_copyLink") 1564 .doCommand("cmd_copyLink"); 1565 1566 // The easiest way to check the clipboard is to paste the contents 1567 // into a textbox. 1568 await SpecialPowers.spawn( 1569 gBrowser.selectedBrowser, 1570 [], 1571 async function () { 1572 let doc = content.document; 1573 let input = doc.getElementById("test-input"); 1574 input.focus(); 1575 input.value = ""; 1576 } 1577 ); 1578 document.commandDispatcher 1579 .getControllerForCommand("cmd_paste") 1580 .doCommand("cmd_paste"); 1581 await SpecialPowers.spawn( 1582 gBrowser.selectedBrowser, 1583 [], 1584 async function () { 1585 let doc = content.document; 1586 let input = doc.getElementById("test-input"); 1587 Assert.equal( 1588 input.value, 1589 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 1590 "http://mozilla.com/", 1591 "paste for command cmd_paste" 1592 ); 1593 // Don't keep focus, because that may affect clipboard commands in 1594 // subsequently-opened menus. 1595 input.blur(); 1596 } 1597 ); 1598 }, 1599 }); 1600 }); 1601 1602 add_task(async function test_dom_full_screen() { 1603 let exited = BrowserTestUtils.waitForEvent(window, "MozDOMFullscreen:Exited"); 1604 1605 let fullscreenItems = NAVIGATION_ITEMS.concat([ 1606 "context-leave-dom-fullscreen", 1607 true, 1608 "---", 1609 null, 1610 "context-savepage", 1611 true, 1612 "context-selectall", 1613 true, 1614 "---", 1615 null, 1616 "context-take-screenshot", 1617 true, 1618 "---", 1619 null, 1620 ...askChatMenu, 1621 "---", 1622 null, 1623 "context-viewsource", 1624 true, 1625 ]); 1626 if (AppConstants.platform == "macosx") { 1627 // Put the bookmarks item next to save page: 1628 const bmPageIndex = fullscreenItems.indexOf("context-bookmarkpage"); 1629 let bmPageItems = fullscreenItems.splice(bmPageIndex, 2); 1630 fullscreenItems.splice( 1631 fullscreenItems.indexOf("context-savepage"), 1632 0, 1633 ...bmPageItems 1634 ); 1635 } 1636 await test_contextmenu("#test-dom-full-screen", fullscreenItems, { 1637 shiftkey: true, 1638 async preCheckContextMenuFn() { 1639 await SpecialPowers.pushPrefEnv({ 1640 set: [ 1641 ["full-screen-api.allow-trusted-requests-only", false], 1642 ["full-screen-api.transition-duration.enter", "0 0"], 1643 ["full-screen-api.transition-duration.leave", "0 0"], 1644 ], 1645 }); 1646 await SpecialPowers.spawn( 1647 gBrowser.selectedBrowser, 1648 [], 1649 async function () { 1650 let doc = content.document; 1651 let win = doc.defaultView; 1652 let full_screen_element = doc.getElementById("test-dom-full-screen"); 1653 let awaitFullScreenChange = ContentTaskUtils.waitForEvent( 1654 win, 1655 "fullscreenchange" 1656 ); 1657 full_screen_element.requestFullscreen(); 1658 await awaitFullScreenChange; 1659 } 1660 ); 1661 }, 1662 async postCheckContextMenuFn() { 1663 await SpecialPowers.spawn( 1664 gBrowser.selectedBrowser, 1665 [], 1666 async function () { 1667 let win = content.document.defaultView; 1668 let awaitFullScreenChange = ContentTaskUtils.waitForEvent( 1669 win, 1670 "fullscreenchange" 1671 ); 1672 content.document.exitFullscreen(); 1673 await awaitFullScreenChange; 1674 } 1675 ); 1676 }, 1677 awaitOnMenuBuilt: { 1678 id: "context-ask-chat", 1679 }, 1680 }); 1681 await exited; 1682 1683 await BrowserTestUtils.waitForCondition(() => { 1684 return !gBrowser.selectedBrowser.browsingContext.currentWindowGlobal.getActor( 1685 "DOMFullscreen" 1686 ).timerId; 1687 }); 1688 1689 if (AppConstants.platform == "macosx") { 1690 // On macOS, the fullscreen transition takes some extra time 1691 // to complete, and we don't receive events for it. We need to 1692 // wait for it to complete or else input events in the next test 1693 // might get eaten up. This is the best we can currently do. 1694 1695 // eslint-disable-next-line mozilla/no-arbitrary-setTimeout 1696 await new Promise(resolve => setTimeout(resolve, 2000)); 1697 } 1698 1699 await SimpleTest.promiseFocus(window); 1700 }); 1701 1702 add_task(async function test_pagemenu2() { 1703 await test_contextmenu( 1704 "#test-text", 1705 [ 1706 ...NAVIGATION_ITEMS, 1707 "context-savepage", 1708 true, 1709 "context-selectall", 1710 true, 1711 "---", 1712 null, 1713 "context-take-screenshot", 1714 true, 1715 "---", 1716 null, 1717 ...askChatMenu, 1718 "---", 1719 null, 1720 "context-viewsource", 1721 true, 1722 ], 1723 { 1724 shiftkey: true, 1725 awaitOnMenuBuilt: { 1726 id: "context-ask-chat", 1727 }, 1728 } 1729 ); 1730 }); 1731 1732 add_task(async function test_select_text() { 1733 await test_contextmenu( 1734 "#test-select-text", 1735 [ 1736 "context-copy", 1737 true, 1738 "context-selectall", 1739 true, 1740 "context-print-selection", 1741 true, 1742 "---", 1743 null, 1744 "context-copy-link-to-highlight", 1745 null, 1746 "context-copy-clean-link-to-highlight", 1747 null, 1748 "---", 1749 null, 1750 "context-take-screenshot", 1751 true, 1752 "---", 1753 null, 1754 "context-searchselect", 1755 true, 1756 "context-searchselect-private", 1757 true, 1758 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 1759 ...askChatMenu, 1760 "---", 1761 null, 1762 "context-viewpartialsource-selection", 1763 true, 1764 ], 1765 { 1766 offsetX: 6, 1767 offsetY: 6, 1768 async preCheckContextMenuFn() { 1769 await selectText("#test-select-text"); 1770 }, 1771 awaitOnMenuBuilt: { 1772 id: "context-ask-chat", 1773 }, 1774 } 1775 ); 1776 }); 1777 1778 add_task(async function test_select_text_search_service_not_initialized() { 1779 let statuses = ["not initialized", "failed", "started"]; 1780 for (let status of statuses) { 1781 Services.search.wrappedJSObject.forceInitializationStatusForTests(status); 1782 await test_contextmenu( 1783 "#test-select-text", 1784 [ 1785 "context-copy", 1786 true, 1787 "context-selectall", 1788 true, 1789 "context-print-selection", 1790 true, 1791 "---", 1792 null, 1793 "context-copy-link-to-highlight", 1794 null, 1795 "context-copy-clean-link-to-highlight", 1796 null, 1797 "---", 1798 null, 1799 "context-take-screenshot", 1800 true, 1801 ...(hasSelectTranslations 1802 ? ["---", null, "context-translate-selection", true] 1803 : []), 1804 ...askChatMenu, 1805 "---", 1806 null, 1807 "context-viewpartialsource-selection", 1808 true, 1809 ], 1810 { 1811 offsetX: 6, 1812 offsetY: 6, 1813 async preCheckContextMenuFn() { 1814 await selectText("#test-select-text"); 1815 }, 1816 awaitOnMenuBuilt: { 1817 id: "context-ask-chat", 1818 }, 1819 } 1820 ); 1821 } 1822 // Restore the search service initialization status 1823 Services.search.wrappedJSObject.forceInitializationStatusForTests("success"); 1824 }); 1825 1826 add_task(async function test_select_text_link() { 1827 await test_contextmenu( 1828 "#test-select-text-link", 1829 [ 1830 "context-openlinkincurrent", 1831 true, 1832 "context-openlinkintab", 1833 true, 1834 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 1835 // We need a blank entry here because the containers submenu is 1836 // dynamically generated with no ids. 1837 ...(hasContainers ? ["", null] : []), 1838 "context-openlink", 1839 true, 1840 "context-openlinkprivate", 1841 true, 1842 "context-previewlink", 1843 true, 1844 "---", 1845 null, 1846 "context-bookmarklink", 1847 true, 1848 "context-savelink", 1849 true, 1850 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 1851 "---", 1852 null, 1853 "context-copy", 1854 true, 1855 "context-selectall", 1856 true, 1857 "context-print-selection", 1858 true, 1859 "---", 1860 null, 1861 "context-copy-link-to-highlight", 1862 null, 1863 "context-copy-clean-link-to-highlight", 1864 null, 1865 "---", 1866 null, 1867 "context-searchselect", 1868 true, 1869 "context-searchselect-private", 1870 true, 1871 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 1872 ...askChatMenu, 1873 "---", 1874 null, 1875 "context-viewpartialsource-selection", 1876 true, 1877 ], 1878 { 1879 offsetX: 6, 1880 offsetY: 6, 1881 async preCheckContextMenuFn() { 1882 await selectText("#test-select-text-link"); 1883 }, 1884 async postCheckContextMenuFn() { 1885 await SpecialPowers.spawn( 1886 gBrowser.selectedBrowser, 1887 [], 1888 async function () { 1889 let win = content.document.defaultView; 1890 win.getSelection().removeAllRanges(); 1891 } 1892 ); 1893 }, 1894 awaitOnMenuBuilt: { 1895 id: "context-ask-chat", 1896 }, 1897 } 1898 ); 1899 }); 1900 1901 add_task(async function test_imagelink() { 1902 await test_contextmenu( 1903 "#test-image-link", 1904 [ 1905 "context-openlinkintab", 1906 true, 1907 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 1908 // We need a blank entry here because the containers submenu is 1909 // dynamically generated with no ids. 1910 ...(hasContainers ? ["", null] : []), 1911 "context-openlink", 1912 true, 1913 "context-openlinkprivate", 1914 true, 1915 "context-previewlink", 1916 true, 1917 "---", 1918 null, 1919 "context-bookmarklink", 1920 true, 1921 "context-savelink", 1922 true, 1923 "context-copylink", 1924 true, 1925 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 1926 "---", 1927 null, 1928 "context-viewimage", 1929 true, 1930 "context-saveimage", 1931 true, 1932 "context-copyimage-contents", 1933 true, 1934 "context-copyimage", 1935 true, 1936 "context-sendimage", 1937 true, 1938 ...getTextRecognitionItems(), 1939 ...(Services.prefs.getBoolPref("browser.menu.showViewImageInfo", false) 1940 ? ["context-viewimageinfo", true] 1941 : []), 1942 ...(Services.prefs.getBoolPref("browser.search.visualSearch.featureGate") 1943 ? ["context-visual-search", true] 1944 : []), 1945 "---", 1946 null, 1947 "context-setDesktopBackground", 1948 true, 1949 "---", 1950 null, 1951 ...askChatMenu, 1952 ], 1953 { 1954 awaitOnMenuBuilt: { 1955 id: "context-ask-chat", 1956 }, 1957 } 1958 ); 1959 }); 1960 1961 add_task(async function test_select_input_text() { 1962 todo(false, "spell checker tests are failing, bug 1246296"); 1963 1964 /* 1965 yield test_contextmenu("#test-select-input-text", 1966 ["context-undo", false, 1967 "context-redo", false, 1968 "---", null, 1969 "context-cut", true, 1970 "context-copy", true, 1971 "context-paste", null, // ignore clipboard state 1972 "context-delete", true, 1973 "context-selectall", true, 1974 "---", null, 1975 "context-searchselect", true, 1976 "context-searchselect-private", true, 1977 "---", null, 1978 "spell-check-enabled", true 1979 ].concat(LOGIN_FILL_ITEMS), 1980 { 1981 *preCheckContextMenuFn() { 1982 yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() { 1983 let doc = content.document; 1984 let win = doc.defaultView; 1985 win.getSelection().removeAllRanges(); 1986 let element = doc.querySelector("#test-select-input-text"); 1987 element.select(); 1988 }); 1989 } 1990 } 1991 ); 1992 */ 1993 }); 1994 1995 add_task(async function test_select_input_text_password() { 1996 todo(false, "spell checker tests are failing, bug 1246296"); 1997 1998 /* 1999 yield test_contextmenu("#test-select-input-text-type-password", 2000 ["context-undo", false, 2001 "context-redo", false, 2002 "---", null, 2003 "context-cut", true, 2004 "context-copy", true, 2005 "context-paste", null, // ignore clipboard state 2006 "context-delete", true, 2007 "context-selectall", true, 2008 "---", null, 2009 "spell-check-enabled", true, 2010 // spell checker is shown on input[type="password"] on this testcase 2011 "spell-dictionaries", true, 2012 ["spell-check-dictionary-en-US", true, 2013 "---", null, 2014 "spell-add-dictionaries", true], null 2015 ].concat(LOGIN_FILL_ITEMS), 2016 { 2017 *preCheckContextMenuFn() { 2018 yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() { 2019 let doc = content.document; 2020 let win = doc.defaultView; 2021 win.getSelection().removeAllRanges(); 2022 let element = doc.querySelector("#test-select-input-text-type-password"); 2023 element.select(); 2024 }); 2025 }, 2026 *postCheckContextMenuFn() { 2027 yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() { 2028 let win = content.document.defaultView; 2029 win.getSelection().removeAllRanges(); 2030 }); 2031 } 2032 } 2033 ); 2034 */ 2035 }); 2036 2037 add_task(async function test_longdesc() { 2038 await test_contextmenu( 2039 "#test-longdesc", 2040 [ 2041 "context-viewimage", 2042 true, 2043 "context-saveimage", 2044 true, 2045 "context-copyimage-contents", 2046 true, 2047 "context-copyimage", 2048 true, 2049 "context-sendimage", 2050 true, 2051 ...getTextRecognitionItems(), 2052 ...(Services.prefs.getBoolPref("browser.menu.showViewImageInfo", false) 2053 ? ["context-viewimageinfo", true] 2054 : []), 2055 "context-viewimagedesc", 2056 true, 2057 ...(Services.prefs.getBoolPref("browser.search.visualSearch.featureGate") 2058 ? ["context-visual-search", true] 2059 : []), 2060 "---", 2061 null, 2062 "context-setDesktopBackground", 2063 true, 2064 "---", 2065 null, 2066 "context-take-screenshot", 2067 true, 2068 "---", 2069 null, 2070 ...askChatMenu, 2071 ], 2072 { 2073 awaitOnMenuBuilt: { 2074 id: "context-ask-chat", 2075 }, 2076 } 2077 ); 2078 }); 2079 2080 add_task(async function test_srcdoc() { 2081 await test_contextmenu( 2082 "#test-srcdoc", 2083 [ 2084 ...NAVIGATION_ITEMS, 2085 "context-savepage", 2086 true, 2087 "context-selectall", 2088 true, 2089 "---", 2090 null, 2091 "context-take-screenshot", 2092 true, 2093 "---", 2094 null, 2095 ...askChatMenu, 2096 "frame", 2097 null, 2098 getThisFrameSubMenu([ 2099 "context-reloadframe", 2100 true, 2101 "---", 2102 null, 2103 "context-saveframe", 2104 true, 2105 "---", 2106 null, 2107 "context-printframe", 2108 true, 2109 "---", 2110 null, 2111 "context-viewframesource", 2112 true, 2113 "context-viewframeinfo", 2114 true, 2115 ]), 2116 null, 2117 "---", 2118 null, 2119 "context-viewsource", 2120 true, 2121 ], 2122 { 2123 awaitOnMenuBuilt: { 2124 id: "context-ask-chat", 2125 }, 2126 } 2127 ); 2128 }); 2129 2130 add_task(async function test_input_spell_false() { 2131 todo(false, "spell checker tests are failing, bug 1246296"); 2132 2133 /* 2134 yield test_contextmenu("#test-contenteditable-spellcheck-false", 2135 ["context-undo", false, 2136 "context-redo", false, 2137 "---", null, 2138 "context-cut", true, 2139 "context-copy", true, 2140 "context-paste", null, // ignore clipboard state 2141 "context-delete", false, 2142 "context-selectall", true, 2143 ] 2144 ); 2145 */ 2146 }); 2147 2148 add_task(async function test_svg_link() { 2149 await test_contextmenu( 2150 "#svg-with-link > a", 2151 [ 2152 "context-openlinkintab", 2153 true, 2154 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 2155 // We need a blank entry here because the containers submenu is 2156 // dynamically generated with no ids. 2157 ...(hasContainers ? ["", null] : []), 2158 "context-openlink", 2159 true, 2160 "context-openlinkprivate", 2161 true, 2162 "context-previewlink", 2163 true, 2164 "---", 2165 null, 2166 "context-bookmarklink", 2167 true, 2168 "context-savelink", 2169 true, 2170 "context-copylink", 2171 true, 2172 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 2173 "---", 2174 null, 2175 "context-searchselect", 2176 true, 2177 "context-searchselect-private", 2178 true, 2179 ...askChatMenu, 2180 ], 2181 { 2182 awaitOnMenuBuilt: { 2183 id: "context-ask-chat", 2184 }, 2185 } 2186 ); 2187 2188 await test_contextmenu( 2189 "#svg-with-link2 > a", 2190 [ 2191 "context-openlinkintab", 2192 true, 2193 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 2194 // We need a blank entry here because the containers submenu is 2195 // dynamically generated with no ids. 2196 ...(hasContainers ? ["", null] : []), 2197 "context-openlink", 2198 true, 2199 "context-openlinkprivate", 2200 true, 2201 "context-previewlink", 2202 true, 2203 "---", 2204 null, 2205 "context-bookmarklink", 2206 true, 2207 "context-savelink", 2208 true, 2209 "context-copylink", 2210 true, 2211 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 2212 "---", 2213 null, 2214 "context-searchselect", 2215 true, 2216 "context-searchselect-private", 2217 true, 2218 ...askChatMenu, 2219 ], 2220 { 2221 awaitOnMenuBuilt: { 2222 id: "context-ask-chat", 2223 }, 2224 } 2225 ); 2226 2227 await test_contextmenu( 2228 "#svg-with-link3 > a", 2229 [ 2230 "context-openlinkintab", 2231 true, 2232 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 2233 // We need a blank entry here because the containers submenu is 2234 // dynamically generated with no ids. 2235 ...(hasContainers ? ["", null] : []), 2236 "context-openlink", 2237 true, 2238 "context-openlinkprivate", 2239 true, 2240 "context-previewlink", 2241 true, 2242 "---", 2243 null, 2244 "context-bookmarklink", 2245 true, 2246 "context-savelink", 2247 true, 2248 "context-copylink", 2249 true, 2250 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 2251 "---", 2252 null, 2253 "context-searchselect", 2254 true, 2255 "context-searchselect-private", 2256 true, 2257 ...askChatMenu, 2258 ], 2259 { 2260 awaitOnMenuBuilt: { 2261 id: "context-ask-chat", 2262 }, 2263 } 2264 ); 2265 }); 2266 2267 add_task(async function test_svg_relative_link() { 2268 await test_contextmenu( 2269 "#svg-with-relative-link > a", 2270 [ 2271 "context-openlinkintab", 2272 true, 2273 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 2274 // We need a blank entry here because the containers submenu is 2275 // dynamically generated with no ids. 2276 ...(hasContainers ? ["", null] : []), 2277 "context-openlink", 2278 true, 2279 "context-openlinkprivate", 2280 true, 2281 "context-previewlink", 2282 true, 2283 "---", 2284 null, 2285 "context-bookmarklink", 2286 true, 2287 "context-savelink", 2288 true, 2289 "context-copylink", 2290 true, 2291 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 2292 "---", 2293 null, 2294 "context-searchselect", 2295 true, 2296 "context-searchselect-private", 2297 true, 2298 ...askChatMenu, 2299 ], 2300 { 2301 awaitOnMenuBuilt: { 2302 id: "context-ask-chat", 2303 }, 2304 } 2305 ); 2306 2307 await test_contextmenu( 2308 "#svg-with-relative-link2 > a", 2309 [ 2310 "context-openlinkintab", 2311 true, 2312 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 2313 // We need a blank entry here because the containers submenu is 2314 // dynamically generated with no ids. 2315 ...(hasContainers ? ["", null] : []), 2316 "context-openlink", 2317 true, 2318 "context-openlinkprivate", 2319 true, 2320 "context-previewlink", 2321 true, 2322 "---", 2323 null, 2324 "context-bookmarklink", 2325 true, 2326 "context-savelink", 2327 true, 2328 "context-copylink", 2329 true, 2330 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 2331 "---", 2332 null, 2333 "context-searchselect", 2334 true, 2335 "context-searchselect-private", 2336 true, 2337 ...askChatMenu, 2338 ], 2339 { 2340 awaitOnMenuBuilt: { 2341 id: "context-ask-chat", 2342 }, 2343 } 2344 ); 2345 2346 await test_contextmenu( 2347 "#svg-with-relative-link3 > a", 2348 [ 2349 "context-openlinkintab", 2350 true, 2351 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 2352 // We need a blank entry here because the containers submenu is 2353 // dynamically generated with no ids. 2354 ...(hasContainers ? ["", null] : []), 2355 "context-openlink", 2356 true, 2357 "context-openlinkprivate", 2358 true, 2359 "context-previewlink", 2360 true, 2361 "---", 2362 null, 2363 "context-bookmarklink", 2364 true, 2365 "context-savelink", 2366 true, 2367 "context-copylink", 2368 true, 2369 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 2370 "---", 2371 null, 2372 "context-searchselect", 2373 true, 2374 "context-searchselect-private", 2375 true, 2376 ...askChatMenu, 2377 ], 2378 { 2379 awaitOnMenuBuilt: { 2380 id: "context-ask-chat", 2381 }, 2382 } 2383 ); 2384 }); 2385 2386 add_task(async function test_background_image() { 2387 let bgImageItems = [ 2388 "context-viewimage", 2389 true, 2390 "context-copyimage", 2391 true, 2392 "context-sendimage", 2393 true, 2394 "---", 2395 null, 2396 "context-savepage", 2397 true, 2398 "context-selectall", 2399 true, 2400 "---", 2401 null, 2402 "context-take-screenshot", 2403 true, 2404 "---", 2405 null, 2406 ...askChatMenu, 2407 "---", 2408 null, 2409 "context-viewsource", 2410 true, 2411 ]; 2412 if (AppConstants.platform == "macosx") { 2413 // Back/fwd/(stop|reload) and their separator go before the image items, 2414 // followed by the bookmark item which goes with save page - so we need 2415 // to split up NAVIGATION_ITEMS and bgImageItems: 2416 bgImageItems = [ 2417 ...NAVIGATION_ITEMS.slice(0, 8), 2418 ...bgImageItems.slice(0, 8), 2419 ...NAVIGATION_ITEMS.slice(8), 2420 ...bgImageItems.slice(8), 2421 ]; 2422 } else { 2423 bgImageItems = NAVIGATION_ITEMS.concat(bgImageItems); 2424 } 2425 await test_contextmenu("#test-background-image", bgImageItems, { 2426 awaitOnMenuBuilt: { 2427 id: "context-ask-chat", 2428 }, 2429 }); 2430 2431 // Don't show image related context menu commands for links with background images. 2432 await test_contextmenu( 2433 "#test-background-image-link", 2434 [ 2435 "context-openlinkintab", 2436 true, 2437 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 2438 // We need a blank entry here because the containers submenu is 2439 // dynamically generated with no ids. 2440 ...(hasContainers ? ["", null] : []), 2441 "context-openlink", 2442 true, 2443 "context-openlinkprivate", 2444 true, 2445 "context-previewlink", 2446 true, 2447 "---", 2448 null, 2449 "context-bookmarklink", 2450 true, 2451 "context-savelink", 2452 true, 2453 "context-copylink", 2454 true, 2455 ...(hasStripOnShare ? ["context-stripOnShareLink", false] : []), 2456 "---", 2457 null, 2458 "context-searchselect", 2459 true, 2460 "context-searchselect-private", 2461 true, 2462 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 2463 ...askChatMenu, 2464 ], 2465 { 2466 awaitOnMenuBuilt: { 2467 id: "context-ask-chat", 2468 }, 2469 } 2470 ); 2471 2472 // Don't show image related context menu commands when there is a selection 2473 // with background images. 2474 await test_contextmenu( 2475 "#test-background-image", 2476 [ 2477 "context-copy", 2478 true, 2479 "context-selectall", 2480 true, 2481 "context-print-selection", 2482 true, 2483 "---", 2484 null, 2485 "context-copy-link-to-highlight", 2486 null, 2487 "context-copy-clean-link-to-highlight", 2488 null, 2489 "---", 2490 null, 2491 "context-take-screenshot", 2492 true, 2493 "---", 2494 null, 2495 "context-searchselect", 2496 true, 2497 "context-searchselect-private", 2498 true, 2499 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 2500 ...askChatMenu, 2501 "---", 2502 null, 2503 "context-viewpartialsource-selection", 2504 true, 2505 ], 2506 { 2507 async preCheckContextMenuFn() { 2508 await selectText("#test-background-image"); 2509 }, 2510 awaitOnMenuBuilt: { 2511 id: "context-ask-chat", 2512 }, 2513 } 2514 ); 2515 }); 2516 2517 add_task(async function test_cleanup_html() { 2518 lastElementSelector = null; 2519 gBrowser.removeCurrentTab(); 2520 }); 2521 2522 /* 2523 * Testing that Copy without Site Tracking option does not 2524 * appear on internal about: pages. 2525 */ 2526 add_task(async function test_strip_on_share_on_secure_about_page() { 2527 let url = about_preferences_base; 2528 2529 let tab = await BrowserTestUtils.openNewForegroundTab({ 2530 gBrowser, 2531 url, 2532 }); 2533 2534 let browser2 = tab.linkedBrowser; 2535 2536 await SpecialPowers.spawn(browser2, [], () => { 2537 let link = content.document.createElement("a"); 2538 link.href = "https://mozilla.com"; 2539 link.textContent = "link with query param"; 2540 link.id = "link-test-strip"; 2541 content.document.body.appendChild(link); 2542 }); 2543 2544 // the Copy without Site Tracking option should not 2545 // show up within internal about: pages 2546 await test_contextmenu( 2547 "#link-test-strip", 2548 [ 2549 "context-openlinkintab", 2550 true, 2551 ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []), 2552 // We need a blank entry here because the containers submenu is 2553 // dynamically generated with no ids. 2554 ...(hasContainers ? ["", null] : []), 2555 "context-openlink", 2556 true, 2557 "context-openlinkprivate", 2558 true, 2559 "context-previewlink", 2560 true, 2561 "---", 2562 null, 2563 "context-bookmarklink", 2564 true, 2565 "context-savelink", 2566 true, 2567 "context-copylink", 2568 true, 2569 "---", 2570 null, 2571 "context-searchselect", 2572 true, 2573 "context-searchselect-private", 2574 true, 2575 ...(hasSelectTranslations ? ["context-translate-selection", true] : []), 2576 ...askChatMenu, 2577 ], 2578 { 2579 awaitOnMenuBuilt: { 2580 id: "context-ask-chat", 2581 }, 2582 } 2583 ); 2584 2585 // Clean up 2586 lastElementSelector = null; 2587 gBrowser.removeCurrentTab(); 2588 }); 2589 2590 /** 2591 * Selects the text of the element that matches the provided `selector` 2592 * 2593 * @param {string} selector 2594 * A selector passed to querySelector to find 2595 * the element that will be referenced. 2596 */ 2597 async function selectText(selector) { 2598 await SpecialPowers.spawn( 2599 gBrowser.selectedBrowser, 2600 [selector], 2601 async function (contentSelector) { 2602 info(`Selecting text of ${contentSelector}`); 2603 let doc = content.document; 2604 let win = doc.defaultView; 2605 win.getSelection().removeAllRanges(); 2606 let div = doc.createRange(); 2607 let element = doc.querySelector(contentSelector); 2608 Assert.ok(element, "Found element to select text from"); 2609 div.setStartBefore(element); 2610 div.setEndAfter(element); 2611 win.getSelection().addRange(div); 2612 } 2613 ); 2614 } 2615 2616 /** 2617 * Not all platforms support text recognition. 2618 * 2619 * @returns {string[]} 2620 */ 2621 function getTextRecognitionItems() { 2622 return Services.prefs.getBoolPref("dom.text-recognition.enabled") && 2623 Services.appinfo.isTextRecognitionSupported 2624 ? ["context-imagetext", true] 2625 : []; 2626 }