github.com/hernad/nomad@v1.6.112/scripts/screenshots/src/index.js (about) 1 /** 2 * Copyright (c) HashiCorp, Inc. 3 * SPDX-License-Identifier: MPL-2.0 4 */ 5 6 const puppeteer = require("puppeteer"); 7 const { 8 capture, 9 wait, 10 error, 11 click, 12 clickJob, 13 clickTab, 14 clickMainMenu, 15 clickX 16 } = require("./utils"); 17 18 const HOST = process.env.EMBER_HOST || "http://localhost:4200"; 19 console.log(`Using host ${HOST}...`); 20 21 const ANSI_YELLOW = "\x1b[33m%s\x1b[0m"; 22 23 (async () => { 24 const startTime = Date.now(); 25 console.log("Preparing puppeteer..."); 26 27 // Create a new browser and tab 28 const browser = await puppeteer.launch({ 29 // Docker related chrome flags 30 args: [ 31 "--no-sandbox", 32 "--disable-setuid-sandbox", 33 "--disable-dev-shm-usage", 34 "--remote-debugging-port=9222", 35 ] 36 }); 37 const page = await browser.newPage(); 38 39 // Make sure the page is 4K is high-dpi scaling 40 page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 2 }); 41 console.log("Loading Nomad UI..."); 42 console.log( 43 ANSI_YELLOW, 44 "\n!! Make sure to use the everyFeature Mirage scenario !!\n" 45 ); 46 47 try { 48 await page.goto(`${HOST}/ui/`); 49 } catch (err) { 50 await error( 51 browser, 52 "Could not load the Nomad UI. Is the Ember server running?" 53 ); 54 } 55 56 // Give Mirage a chance to settle 57 console.log("Waiting for Mirage..."); 58 await wait(5000); 59 console.log("Starting capture sequence!\n"); 60 61 // DEBUG: log the URL on all navigations 62 monitorURL(page); 63 64 await capture(page, "jobs-list"); 65 66 await clickJob(page, "service"); 67 await capture(page, "job-detail-service"); 68 await page.goBack(); 69 70 await clickJob(page, "batch"); 71 await capture(page, "job-detail-batch"); 72 await page.goBack(); 73 74 await clickJob(page, "system"); 75 await capture(page, "job-detail-system"); 76 await page.goBack(); 77 78 await clickJob(page, "periodic"); 79 await capture(page, "job-detail-periodic"); 80 await click(page, "tr.job-row"); 81 await capture(page, "job-detail-periodic-child"); 82 await page.goBack(); 83 await page.goBack(); 84 85 await clickJob(page, "parameterized"); 86 await capture(page, "job-detail-parameterized"); 87 await click(page, "tr.job-row"); 88 await capture(page, "job-detail-parameterized-child"); 89 await page.goBack(); 90 await page.goBack(); 91 92 await clickJob(page, "service"); 93 94 await clickTab(page, "Definition"); 95 await capture(page, "job-detail-tab-definition"); 96 await page.click(".boxed-section .button.is-light.is-compact.pull-right"); 97 await capture(page, "job-detail-tab-definition-editing"); 98 99 await clickTab(page, "Versions"); 100 await capture(page, "job-detail-tab-versions"); 101 await page.click(".timeline-object .button.is-light.is-compact.pull-right"); 102 await capture(page, "job-detail-tab-versions-expanded"); 103 104 await clickTab(page, "Deployments"); 105 await capture(page, "job-detail-tab-deployments"); 106 await page.click(".timeline-object .button.is-light.is-compact.pull-right"); 107 await capture(page, "job-detail-tab-deployments-expanded"); 108 109 await clickTab(page, "Allocations"); 110 await capture(page, "job-detail-tab-allocations"); 111 112 await clickTab(page, "Evaluations"); 113 await capture(page, "job-detail-tab-evaluations"); 114 115 await clickMainMenu(page, "Jobs"); 116 await page.click(".toolbar-item .button.is-primary"); 117 await capture(page, "job-run-empty"); 118 // Fill in the code editor somehow 119 // Capture the plan stage 120 121 await clickMainMenu(page, "Jobs"); 122 await clickJob(page, "service"); 123 await click(page, ".task-group-row"); 124 await capture(page, "task-group"); 125 126 await clickMainMenu(page, "Jobs"); 127 await clickJob(page, "service"); 128 129 const allocCount = await page.$$eval(".allocation-row", s => s.length); 130 for (let i = 1; i <= allocCount; i++) { 131 await click(page, `.allocation-row:nth-of-type(${i}) a.is-primary`); 132 await capture(page, `allocation-${i}`); 133 await page.goBack(); 134 await wait(2000); 135 } 136 137 await click(page, ".allocation-row a.is-primary"); 138 await click(page, ".task-row"); 139 await capture(page, "task-detail"); 140 141 await clickTab(page, "Logs"); 142 await capture(page, "task-logs"); 143 144 await clickMainMenu(page, "Clients"); 145 await capture(page, "clients-list"); 146 147 const clientCount = await page.$$eval(".client-node-row", s => s.length); 148 for (let i = 1; i <= clientCount; i++) { 149 await click(page, `.client-node-row:nth-of-type(${i})`); 150 await capture(page, `client-detail-${i}`); 151 await page.goBack(); 152 await wait(500); 153 } 154 155 await clickMainMenu(page, "Servers"); 156 await capture(page, "servers-list"); 157 158 await click(page, `.server-agent-row:nth-of-type(2)`); 159 await capture(page, "server-detail"); 160 161 await clickX(page, '//a[contains(text(), "ACL Tokens")]'); 162 await capture(page, "acl-tokens"); 163 164 console.log(`All done! ${humanDuration(Date.now() - startTime)}`); 165 process.exit(); 166 })(); 167 168 async function* watchURL(page) { 169 while (true) { 170 await page.waitForNavigation(); 171 yield page.url(); 172 } 173 } 174 175 async function monitorURL(page) { 176 for await (let url of watchURL(page)) { 177 console.log(`=> ${url}`); 178 } 179 } 180 181 function humanDuration(duration) { 182 const ms = duration % 1000; 183 const s = Math.floor((duration / 1000) % 60); 184 const m = Math.floor(duration / 1000 / 60); 185 186 const fs = s < 10 ? `0${s}` : `${s}`; 187 const fms = ms < 10 ? `00${ms}` : ms < 100 ? `0${ms}` : `${ms}`; 188 189 if (m) return `${m}m ${fs}s ${fms}ms`; 190 else if (s) return `${fs}s ${fms}ms`; 191 return `${fms}ms`; 192 }