browsertime_interactive.js (3280B)
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 /* eslint-env node */ 6 7 const { logTest, logTask } = require("./utils/profiling"); 8 9 async function get_command_function(cmd, commands) { 10 /* 11 Converts a string such as `measure.start` into the actual 12 function that is found in the `commands` module. 13 14 XXX: Find a way to share this function between 15 perftest_record.js and browsertime_interactive.js 16 */ 17 if (cmd == "") { 18 throw new Error("A blank command was given."); 19 } else if (cmd.endsWith(".")) { 20 throw new Error( 21 "An extra `.` was found at the end of this command: " + cmd 22 ); 23 } 24 25 // `func` will hold the actual method that needs to be called, 26 // and the `parent_mod` is the context required to run the `func` 27 // method. Without that context, `this` becomes undefined in the browsertime 28 // classes. 29 let func = null; 30 let parent_mod = null; 31 for (let func_part of cmd.split(".")) { 32 if (func_part == "") { 33 throw new Error( 34 "An empty function part was found in the command: " + cmd 35 ); 36 } 37 38 if (func === null) { 39 parent_mod = commands; 40 func = commands[func_part]; 41 } else if (func !== undefined) { 42 parent_mod = func; 43 func = func[func_part]; 44 } else { 45 break; 46 } 47 } 48 49 if (func == undefined) { 50 throw new Error( 51 "The given command could not be found as a function: " + cmd 52 ); 53 } 54 55 return [func, parent_mod]; 56 } 57 58 module.exports = logTest( 59 "interactive browsertime test", 60 async function (context, commands) { 61 context.log.info("Starting an interactive browsertime test"); 62 let page_cycles = context.options.browsertime.page_cycles; 63 let post_startup_delay = context.options.browsertime.post_startup_delay; 64 let input_cmds = context.options.browsertime.commands; 65 66 context.log.info( 67 "Waiting for %d ms (post_startup_delay)", 68 post_startup_delay 69 ); 70 await commands.wait.byTime(post_startup_delay); 71 72 // unpack commands from python 73 let cmds = input_cmds.split(";;;"); 74 75 for (let count = 0; count < page_cycles; count++) { 76 await logTask(context, "cycle " + count, async function () { 77 context.log.info("Navigating to about:blank w/nav, count: " + count); 78 await commands.navigate("about:blank"); 79 80 let pages_visited = []; 81 for (let cmdstr of cmds) { 82 let [cmd, ...args] = cmdstr.split(":::"); 83 84 if (cmd == "measure.start") { 85 if (args[0] != "") { 86 pages_visited.push(args[0]); 87 } 88 } 89 90 let [func, parent_mod] = await get_command_function(cmd, commands); 91 92 try { 93 await func.call(parent_mod, ...args); 94 } catch (e) { 95 context.log.info( 96 `Exception found while running \`commands.${cmd}(${args})\`: ` 97 ); 98 context.log.info(e.stack); 99 } 100 } 101 102 // Log the number of pages visited for results parsing 103 context.log.info("[] metrics: pages_visited: " + pages_visited); 104 }); 105 } 106 107 context.log.info("Browsertime pageload ended."); 108 return true; 109 } 110 );