fake-frontend.html (4454B)
1 <!DOCTYPE html> 2 <!-- This Source Code Form is subject to the terms of the Mozilla Public 3 - License, v. 2.0. If a copy of the MPL was not distributed with this 4 - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> 5 <html> 6 <head> 7 <meta charset="utf-8"/> 8 <title></title> 9 </head> 10 <body> 11 <script> 12 "use strict"; 13 // This file is used to test the injection of performance profiles into a front-end, 14 // specifically the mechanism used to inject into profiler.firefox.com. Rather 15 // than using some kind of complicated message passing scheme to talk to the test 16 // harness, modify the title of the page. The tests can easily read the window 17 // title to see if things worked as expected. 18 19 // The following are the titles used to communicate the page's state to the tests. 20 // Keep these in sync with any tests that read them. 21 const initialTitle = "Waiting on the profile"; 22 const successTitle = "Profile received"; 23 const errorTitle = "Error" 24 25 document.title = initialTitle; 26 27 // A function which requests the profile from the browser using the GET_PROFILE 28 // WebChannel message. 29 function getProfile() { 30 return new Promise((resolve, reject) => { 31 const requestId = 0; 32 33 function listener(event) { 34 window.removeEventListener( 35 "WebChannelMessageToContent", 36 listener, 37 true 38 ); 39 40 const { id, message } = event.detail; 41 42 if (id !== "profiler.firefox.com" || 43 !message || 44 typeof message !== "object" 45 ) { 46 console.error(message); 47 reject(new Error("A malformed WebChannel event was received.")); 48 return; 49 } 50 51 if (!message.type) { 52 console.error(message); 53 reject(new Error("The WebChannel event indicates an error.")); 54 return; 55 } 56 57 if (message.requestId === requestId) { 58 if (message.type === "SUCCESS_RESPONSE") { 59 resolve(message.response); 60 } else { 61 reject(new Error(message.error)); 62 } 63 } 64 } 65 66 window.addEventListener("WebChannelMessageToContent", listener, true); 67 68 window.dispatchEvent( 69 new CustomEvent("WebChannelMessageToChrome", { 70 detail: JSON.stringify({ 71 id: "profiler.firefox.com", 72 message: { type: "GET_PROFILE", requestId }, 73 }), 74 }) 75 ); 76 }) 77 } 78 79 async function runTest() { 80 try { 81 // Get the profile. 82 const profile = await getProfile(); 83 84 // Check that the profile is somewhat reasonable. It should be a gzipped 85 // profile, so we can only lightly check some properties about it, and check 86 // that it is an ArrayBuffer. 87 // 88 // After the check, modify the title of the document, so the tab title gets 89 // updated. This is an easy way to pass a message to the test script. 90 if ( 91 profile && 92 typeof profile === 'object' && 93 ( 94 // The popup injects the compressed profile as an ArrayBuffer. 95 (profile instanceof ArrayBuffer) || 96 // DevTools injects the profile as just the plain object, although 97 // maybe in the future it could also do it as a compressed profile 98 // to make this faster (bug 1581963). 99 Object.keys(profile).includes("threads") 100 ) 101 ) { 102 // The profile looks good! 103 document.title = successTitle; 104 } else { 105 // The profile doesn't look right, surface the error to the terminal. 106 dump('The gecko profile was malformed in fake-frontend.html\n'); 107 dump(`Profile: ${JSON.stringify(profile)}\n`); 108 109 // Also to the web console. 110 console.error(profile); 111 112 // Report the error to the tab title. 113 document.title = errorTitle; 114 } 115 } catch (error) { 116 // Catch any error and notify the test. 117 document.title = errorTitle; 118 dump('An error was caught in fake-frontend.html\n'); 119 dump(`${error}\n`); 120 } 121 } 122 123 runTest(); 124 </script> 125 </body> 126 </html>