mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Adding artifacts (#15145)
This commit is contained in:
parent
df646a03eb
commit
45cecf385d
@ -136,6 +136,9 @@ workflows:
|
|||||||
- benchmark:
|
- benchmark:
|
||||||
requires:
|
requires:
|
||||||
- prep-build-test
|
- prep-build-test
|
||||||
|
- stats-module-load-init:
|
||||||
|
requires:
|
||||||
|
- prep-build-test-mv3
|
||||||
- job-publish-prerelease:
|
- job-publish-prerelease:
|
||||||
requires:
|
requires:
|
||||||
- prep-deps
|
- prep-deps
|
||||||
@ -143,7 +146,9 @@ workflows:
|
|||||||
- prep-build-beta
|
- prep-build-beta
|
||||||
- prep-build-flask
|
- prep-build-flask
|
||||||
- prep-build-storybook
|
- prep-build-storybook
|
||||||
|
- prep-build-test-mv3
|
||||||
- benchmark
|
- benchmark
|
||||||
|
- stats-module-load-init
|
||||||
- all-tests-pass
|
- all-tests-pass
|
||||||
- job-publish-release:
|
- job-publish-release:
|
||||||
filters:
|
filters:
|
||||||
@ -596,6 +601,40 @@ jobs:
|
|||||||
paths:
|
paths:
|
||||||
- test-artifacts
|
- test-artifacts
|
||||||
|
|
||||||
|
stats-module-load-init:
|
||||||
|
executor: node-browsers-medium-plus
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Re-Install Chrome
|
||||||
|
command: ./.circleci/scripts/chrome-install.sh
|
||||||
|
- attach_workspace:
|
||||||
|
at: .
|
||||||
|
- run:
|
||||||
|
name: Move test build to dist
|
||||||
|
command: mv ./dist-test-mv3 ./dist
|
||||||
|
- run:
|
||||||
|
name: Move test zips to builds
|
||||||
|
command: mv ./builds-test-mv3 ./builds
|
||||||
|
- run:
|
||||||
|
name: Run page load benchmark
|
||||||
|
command: |
|
||||||
|
mkdir -p test-artifacts/chrome/mv3
|
||||||
|
cp -R development/charts/flamegraph test-artifacts/chrome/mv3/initialisation
|
||||||
|
cp -R development/charts/flamegraph/chart test-artifacts/chrome/mv3/initialisation/background
|
||||||
|
cp -R development/charts/flamegraph/chart test-artifacts/chrome/mv3/initialisation/ui
|
||||||
|
cp -R development/charts/table test-artifacts/chrome/mv3/load_time
|
||||||
|
- run:
|
||||||
|
name: Run page load benchmark
|
||||||
|
command: yarn mv3:stats:chrome --out test-artifacts/chrome/mv3
|
||||||
|
- store_artifacts:
|
||||||
|
path: test-artifacts
|
||||||
|
destination: test-artifacts
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: .
|
||||||
|
paths:
|
||||||
|
- test-artifacts
|
||||||
|
|
||||||
job-publish-prerelease:
|
job-publish-prerelease:
|
||||||
executor: node-browsers
|
executor: node-browsers
|
||||||
steps:
|
steps:
|
||||||
|
@ -8,6 +8,7 @@ module.exports = {
|
|||||||
'app/vendor/**',
|
'app/vendor/**',
|
||||||
'builds/**/*',
|
'builds/**/*',
|
||||||
'development/chromereload.js',
|
'development/chromereload.js',
|
||||||
|
'development/charts/**',
|
||||||
'dist/**/*',
|
'dist/**/*',
|
||||||
'node_modules/**/*',
|
'node_modules/**/*',
|
||||||
],
|
],
|
||||||
|
170
development/charts/flamegraph/chart/index.html
Normal file
170
development/charts/flamegraph/chart/index.html
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||||
|
/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../lib/d3-flamegraph.css" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Space out content a bit */
|
||||||
|
body {
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom page header */
|
||||||
|
.header {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 15px;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make the masthead heading the same height as the navigation */
|
||||||
|
.header h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Customize container */
|
||||||
|
.container {
|
||||||
|
max-width: 990px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<title>Performance Measurements</title>
|
||||||
|
|
||||||
|
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||||
|
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header clearfix">
|
||||||
|
<nav>
|
||||||
|
<div class="pull-right">
|
||||||
|
<form class="form-inline" id="form">
|
||||||
|
<a class="btn" href="javascript: resetZoom();">Reset zoom</a>
|
||||||
|
<a class="btn" href="javascript: clear();">Clear</a>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" class="form-control" id="term" />
|
||||||
|
</div>
|
||||||
|
<a class="btn btn-primary" href="javascript: search();">Search</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<h3 class="text-muted">d3-flame-graph</h3>
|
||||||
|
</div>
|
||||||
|
<div id="chart"></div>
|
||||||
|
<hr />
|
||||||
|
<div id="details"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- D3.js -->
|
||||||
|
<script src="https://d3js.org/d3.v7.js" charset="utf-8"></script>
|
||||||
|
|
||||||
|
<!-- d3-flamegraph -->
|
||||||
|
<script type="text/javascript" src="../lib/d3-flamegraph.js"></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="../lib/d3-flamegraph-tooltip.js"
|
||||||
|
></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var chart = flamegraph()
|
||||||
|
.width(960)
|
||||||
|
.cellHeight(18)
|
||||||
|
.transitionDuration(750)
|
||||||
|
.minFrameSize(5)
|
||||||
|
.transitionEase(d3.easeCubic)
|
||||||
|
.sort(true)
|
||||||
|
//Example to sort in reverse order
|
||||||
|
//.sort(function(a,b){ return d3.descending(a.name, b.name);})
|
||||||
|
.title('')
|
||||||
|
.onClick(onClick)
|
||||||
|
.selfValue(false)
|
||||||
|
.setColorMapper((d, originalColor) =>
|
||||||
|
d.highlight ? '#6aff8f' : originalColor,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Example on how to use custom a tooltip.
|
||||||
|
var tip = flamegraph.tooltip
|
||||||
|
.defaultFlamegraphTooltip()
|
||||||
|
.text((d) => 'name: ' + d.data.name + ', value: ' + d.data.value);
|
||||||
|
chart.tooltip(tip);
|
||||||
|
|
||||||
|
var details = document.getElementById('details');
|
||||||
|
chart.setDetailsElement(details);
|
||||||
|
|
||||||
|
// Example on how to use searchById() function in flamegraph.
|
||||||
|
// To invoke this function after loading the graph itself, this function should be registered in d3 datum(data).call()
|
||||||
|
// (See d3.json invocation in this file)
|
||||||
|
function invokeFind() {
|
||||||
|
var searchId = parseInt(location.hash.substring(1), 10);
|
||||||
|
if (searchId) {
|
||||||
|
find(searchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example on how to use custom labels
|
||||||
|
// var label = function(d) {
|
||||||
|
// return "name: " + d.name + ", value: " + d.value;
|
||||||
|
// }
|
||||||
|
// chart.label(label);
|
||||||
|
|
||||||
|
// Example of how to set fixed chart height
|
||||||
|
// chart.height(540);
|
||||||
|
|
||||||
|
d3.json('stacks.json')
|
||||||
|
.then((data) => {
|
||||||
|
d3.select('#chart').datum(data).call(chart).call(invokeFind);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
return console.warn(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.getElementById('form')
|
||||||
|
.addEventListener('submit', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
search();
|
||||||
|
});
|
||||||
|
|
||||||
|
function search() {
|
||||||
|
var term = document.getElementById('term').value;
|
||||||
|
chart.search(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
function find(id) {
|
||||||
|
var elem = chart.findById(id);
|
||||||
|
if (elem) {
|
||||||
|
console.log(elem);
|
||||||
|
chart.zoomTo(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
document.getElementById('term').value = '';
|
||||||
|
chart.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetZoom() {
|
||||||
|
chart.resetZoom();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClick(d) {
|
||||||
|
console.info(`Clicked on ${d.data.name}, id: "${d.id}"`);
|
||||||
|
history.pushState({ id: d.id }, d.data.name, `#${d.id}`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
3117
development/charts/flamegraph/lib/d3-flamegraph-tooltip.js
vendored
Normal file
3117
development/charts/flamegraph/lib/d3-flamegraph-tooltip.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
46
development/charts/flamegraph/lib/d3-flamegraph.css
Normal file
46
development/charts/flamegraph/lib/d3-flamegraph.css
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
.d3-flame-graph rect {
|
||||||
|
stroke: #EEEEEE;
|
||||||
|
fill-opacity: .8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d3-flame-graph rect:hover {
|
||||||
|
stroke: #474747;
|
||||||
|
stroke-width: 0.5;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d3-flame-graph-label {
|
||||||
|
pointer-events: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: Verdana;
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
line-height: 1.5;
|
||||||
|
padding: 0 0 0;
|
||||||
|
font-weight: 400;
|
||||||
|
color: black;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d3-flame-graph .fade {
|
||||||
|
opacity: 0.6 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d3-flame-graph .title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-family: Verdana;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d3-flame-graph-tip {
|
||||||
|
background-color: black;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 5px 10px 5px 10px;
|
||||||
|
min-width: 250px;
|
||||||
|
text-align: left;
|
||||||
|
color: white;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
5719
development/charts/flamegraph/lib/d3-flamegraph.js
vendored
Normal file
5719
development/charts/flamegraph/lib/d3-flamegraph.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
67
development/charts/table/index.html
Normal file
67
development/charts/table/index.html
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script type="text/javascript" src="./jquery.min.js"></script>
|
||||||
|
<style>
|
||||||
|
table {
|
||||||
|
border: 1px solid black;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
var loadTime = [];
|
||||||
|
|
||||||
|
$.getJSON('stats.json', function (data) {
|
||||||
|
$.each(data.children, function (index, datum) {
|
||||||
|
if (datum.name) {
|
||||||
|
var tblRow =
|
||||||
|
'<tr>' +
|
||||||
|
'<td>' +
|
||||||
|
index +
|
||||||
|
'</td>' +
|
||||||
|
'<td>' +
|
||||||
|
datum.name +
|
||||||
|
'</td>' +
|
||||||
|
'<td>' +
|
||||||
|
datum.value +
|
||||||
|
'</td>' +
|
||||||
|
'</tr>';
|
||||||
|
$(tblRow).appendTo('#loaddata tbody');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$(
|
||||||
|
'<tr>' +
|
||||||
|
'<td>' +
|
||||||
|
'Total' +
|
||||||
|
'</td>' +
|
||||||
|
'<td>' +
|
||||||
|
'--' +
|
||||||
|
'</td>' +
|
||||||
|
'<td>' +
|
||||||
|
data.value +
|
||||||
|
'</td>' +
|
||||||
|
'</tr>',
|
||||||
|
).appendTo('#loaddata tbody');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="profile">
|
||||||
|
<table id="loaddata">
|
||||||
|
<thead>
|
||||||
|
<th>S.No</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>TotalTime</th>
|
||||||
|
</thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
18
development/charts/table/jquery.min.js
vendored
Normal file
18
development/charts/table/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -94,6 +94,12 @@ async function start() {
|
|||||||
// links to bundle browser builds
|
// links to bundle browser builds
|
||||||
const depVizUrl = `${BUILD_LINK_BASE}/build-artifacts/build-viz/index.html`;
|
const depVizUrl = `${BUILD_LINK_BASE}/build-artifacts/build-viz/index.html`;
|
||||||
const depVizLink = `<a href="${depVizUrl}">Build System</a>`;
|
const depVizLink = `<a href="${depVizUrl}">Build System</a>`;
|
||||||
|
const moduleInitStatsBackgroundUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/mv3/initialisation/background/index.html`;
|
||||||
|
const moduleInitStatsBackgroundLink = `<a href="${moduleInitStatsBackgroundUrl}">MV3 Background Module Init Stats</a>`;
|
||||||
|
const moduleInitStatsUIUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/mv3/initialisation/ui/index.html`;
|
||||||
|
const moduleInitStatsUILink = `<a href="${moduleInitStatsUIUrl}">MV3 UI Init Stats</a>`;
|
||||||
|
const moduleLoadStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/mv3/load_time/index.html`;
|
||||||
|
const moduleLoadStatsLink = `<a href="${moduleLoadStatsUrl}">Module Load Stats</a>`;
|
||||||
|
|
||||||
// link to artifacts
|
// link to artifacts
|
||||||
const allArtifactsUrl = `https://circleci.com/gh/MetaMask/metamask-extension/${CIRCLE_BUILD_NUM}#artifacts/containers/0`;
|
const allArtifactsUrl = `https://circleci.com/gh/MetaMask/metamask-extension/${CIRCLE_BUILD_NUM}#artifacts/containers/0`;
|
||||||
@ -103,6 +109,9 @@ async function start() {
|
|||||||
`builds (beta): ${betaBuildLinks}`,
|
`builds (beta): ${betaBuildLinks}`,
|
||||||
`builds (flask): ${flaskBuildLinks}`,
|
`builds (flask): ${flaskBuildLinks}`,
|
||||||
`build viz: ${depVizLink}`,
|
`build viz: ${depVizLink}`,
|
||||||
|
`mv3: ${moduleInitStatsBackgroundLink}`,
|
||||||
|
`mv3: ${moduleInitStatsUILink}`,
|
||||||
|
`mv3: ${moduleLoadStatsLink}`,
|
||||||
`code coverage: ${coverageLink}`,
|
`code coverage: ${coverageLink}`,
|
||||||
`storybook: ${storybookLink}`,
|
`storybook: ${storybookLink}`,
|
||||||
`<a href="${allArtifactsUrl}">all artifacts</a>`,
|
`<a href="${allArtifactsUrl}">all artifacts</a>`,
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { promises: fs, constants: fsConstants } = require('fs');
|
const { promises: fs } = require('fs');
|
||||||
const yargs = require('yargs/yargs');
|
const yargs = require('yargs/yargs');
|
||||||
const { hideBin } = require('yargs/helpers');
|
const { hideBin } = require('yargs/helpers');
|
||||||
const ttest = require('ttest');
|
const ttest = require('ttest');
|
||||||
const { retry } = require('../../development/lib/retry');
|
const { retry } = require('../../development/lib/retry');
|
||||||
const { exitWithError } = require('../../development/lib/exit-with-error');
|
const { exitWithError } = require('../../development/lib/exit-with-error');
|
||||||
|
const {
|
||||||
|
isWritable,
|
||||||
|
getFirstParentDirectoryThatExists,
|
||||||
|
} = require('../helpers/file');
|
||||||
const { withFixtures, tinyDelayMs } = require('./helpers');
|
const { withFixtures, tinyDelayMs } = require('./helpers');
|
||||||
const { PAGES } = require('./webdriver/driver');
|
const { PAGES } = require('./webdriver/driver');
|
||||||
|
|
||||||
@ -108,35 +112,6 @@ async function profilePageLoad(pages, numSamples, retries) {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function isWritable(directory) {
|
|
||||||
try {
|
|
||||||
await fs.access(directory, fsConstants.W_OK);
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
if (error.code !== 'EACCES') {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getFirstParentDirectoryThatExists(directory) {
|
|
||||||
let nextDirectory = directory;
|
|
||||||
for (;;) {
|
|
||||||
try {
|
|
||||||
await fs.access(nextDirectory, fsConstants.F_OK);
|
|
||||||
return nextDirectory;
|
|
||||||
} catch (error) {
|
|
||||||
if (error.code !== 'ENOENT') {
|
|
||||||
throw error;
|
|
||||||
} else if (nextDirectory === path.dirname(nextDirectory)) {
|
|
||||||
throw new Error('Failed to find parent directory that exists');
|
|
||||||
}
|
|
||||||
nextDirectory = path.dirname(nextDirectory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const { argv } = yargs(hideBin(process.argv)).usage(
|
const { argv } = yargs(hideBin(process.argv)).usage(
|
||||||
'$0 [options]',
|
'$0 [options]',
|
||||||
|
111
test/e2e/mv3-stats.js
Normal file
111
test/e2e/mv3-stats.js
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/* eslint-disable node/shebang */
|
||||||
|
const path = require('path');
|
||||||
|
const { promises: fs } = require('fs');
|
||||||
|
const yargs = require('yargs/yargs');
|
||||||
|
const { hideBin } = require('yargs/helpers');
|
||||||
|
|
||||||
|
const { exitWithError } = require('../../development/lib/exit-with-error');
|
||||||
|
const {
|
||||||
|
isWritable,
|
||||||
|
getFirstParentDirectoryThatExists,
|
||||||
|
} = require('../helpers/file');
|
||||||
|
const { withFixtures, tinyDelayMs } = require('./helpers');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The e2e test case is used to capture load and initialisation time statistics for extension in MV3 environment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function profilePageLoad() {
|
||||||
|
const parsedLogs = {};
|
||||||
|
try {
|
||||||
|
await withFixtures({ fixtures: 'imported-account' }, async ({ driver }) => {
|
||||||
|
await driver.delay(tinyDelayMs);
|
||||||
|
await driver.navigate();
|
||||||
|
await driver.delay(1000);
|
||||||
|
const logs = await driver.checkBrowserForLavamoatLogs();
|
||||||
|
|
||||||
|
let logString = '';
|
||||||
|
let logType = '';
|
||||||
|
|
||||||
|
logs.forEach((log) => {
|
||||||
|
if (log.indexOf('"version": 1') >= 0) {
|
||||||
|
// log end here
|
||||||
|
logString += log;
|
||||||
|
parsedLogs[logType] = JSON.parse(`{${logString}}`);
|
||||||
|
logString = '';
|
||||||
|
logType = '';
|
||||||
|
} else if (logType) {
|
||||||
|
// log string continues
|
||||||
|
logString += log;
|
||||||
|
} else if (
|
||||||
|
log.search(/"name": ".*app\/scripts\/background.js",/u) >= 0
|
||||||
|
) {
|
||||||
|
// background log starts
|
||||||
|
logString += log;
|
||||||
|
logType = 'background';
|
||||||
|
} else if (log.search(/"name": ".*app\/scripts\/ui.js",/u) >= 0) {
|
||||||
|
// ui log starts
|
||||||
|
logString += log;
|
||||||
|
logType = 'ui';
|
||||||
|
} else if (log.search(/"name": "Total"/u) >= 0) {
|
||||||
|
// load time log starts
|
||||||
|
logString += log;
|
||||||
|
logType = 'loadTime';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Error in trying to parse logs.');
|
||||||
|
}
|
||||||
|
return parsedLogs;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const { argv } = yargs(hideBin(process.argv)).usage(
|
||||||
|
'$0 [options]',
|
||||||
|
'Run a page load benchmark',
|
||||||
|
(_yargs) =>
|
||||||
|
_yargs.option('out', {
|
||||||
|
description:
|
||||||
|
'Output filename. Output printed to STDOUT of this is omitted.',
|
||||||
|
type: 'string',
|
||||||
|
normalize: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const results = await profilePageLoad();
|
||||||
|
const { out } = argv;
|
||||||
|
|
||||||
|
const logCategories = [
|
||||||
|
{ key: 'background', dirPath: 'initialisation/background/stacks.json' },
|
||||||
|
{ key: 'ui', dirPath: 'initialisation/ui/stacks.json' },
|
||||||
|
{ key: 'loadTime', dirPath: 'load_time/stats.json' },
|
||||||
|
];
|
||||||
|
|
||||||
|
if (out) {
|
||||||
|
logCategories.forEach(async ({ key, dirPath }) => {
|
||||||
|
if (results[key]) {
|
||||||
|
const outPath = `${out}/${dirPath}`;
|
||||||
|
const outputDirectory = path.dirname(outPath);
|
||||||
|
const existingParentDirectory = await getFirstParentDirectoryThatExists(
|
||||||
|
outputDirectory,
|
||||||
|
);
|
||||||
|
if (!(await isWritable(existingParentDirectory))) {
|
||||||
|
throw new Error('Specified output file directory is not writable');
|
||||||
|
}
|
||||||
|
if (outputDirectory !== existingParentDirectory) {
|
||||||
|
await fs.mkdir(outputDirectory, { recursive: true });
|
||||||
|
}
|
||||||
|
await fs.writeFile(outPath, JSON.stringify(results[key], null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log(JSON.stringify(results, null, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
exitWithError(error);
|
||||||
|
});
|
37
test/helpers/file.js
Normal file
37
test/helpers/file.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* eslint-disable node/shebang */
|
||||||
|
const path = require('path');
|
||||||
|
const { promises: fs, constants: fsConstants } = require('fs');
|
||||||
|
|
||||||
|
async function isWritable(directory) {
|
||||||
|
try {
|
||||||
|
await fs.access(directory, fsConstants.W_OK);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code !== 'EACCES') {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getFirstParentDirectoryThatExists(directory) {
|
||||||
|
let nextDirectory = directory;
|
||||||
|
for (;;) {
|
||||||
|
try {
|
||||||
|
await fs.access(nextDirectory, fsConstants.F_OK);
|
||||||
|
return nextDirectory;
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code !== 'ENOENT') {
|
||||||
|
throw error;
|
||||||
|
} else if (nextDirectory === path.dirname(nextDirectory)) {
|
||||||
|
throw new Error('Failed to find parent directory that exists');
|
||||||
|
}
|
||||||
|
nextDirectory = path.dirname(nextDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
isWritable,
|
||||||
|
getFirstParentDirectoryThatExists,
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user