Capture user actions times for MV2 benchmark and generate artifacts (#15353)

* User actions benchmark and artifacts

* Lint and fix identation

* Fix lint

* Updated path

* lint

* Add user actions benchmark to pre release job

* Remove title

* Out path updated

* See if url is finally fixed

* Adding some console logs

* lint

* fix lint

* fix lint

* Updated persisting and store artifacts path

* Added MetaMask bot correct link and remove console logs

* Remove console log

* Sort Imports

* Fix lint

* Update loadAccount function and prop name for clarity to loadNewAccount

* Run yarn setup

* Fix yarn

* Update Create Account element for Create account

* Remove unnecessary step on send

Co-authored-by: Jyoti Puri <jyotipuri@gmail.com>
feature/default_network_editable
seaona 2 years ago committed by GitHub
parent 23b882449f
commit 437acdb74c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      .circleci/config.yml
  2. 3
      development/metamaskbot-build-announce.js
  3. 1
      package.json
  4. 130
      test/e2e/user-actions-benchmark.js

@ -139,6 +139,9 @@ workflows:
- benchmark: - benchmark:
requires: requires:
- prep-build-test - prep-build-test
- user-actions-benchmark:
requires:
- prep-build-test
- stats-module-load-init: - stats-module-load-init:
requires: requires:
- prep-build-test-mv3 - prep-build-test-mv3
@ -152,6 +155,7 @@ workflows:
- prep-build-ts-migration-dashboard - prep-build-ts-migration-dashboard
- prep-build-test-mv3 - prep-build-test-mv3
- benchmark - benchmark
- user-actions-benchmark
- stats-module-load-init - stats-module-load-init
- all-tests-pass - all-tests-pass
- job-publish-release: - job-publish-release:
@ -624,6 +628,32 @@ jobs:
root: . root: .
paths: paths:
- test-artifacts - test-artifacts
user-actions-benchmark:
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 ./dist
- run:
name: Move test zips to builds
command: mv ./builds-test ./builds
- run:
name: Run page load benchmark
command: yarn user-actions-benchmark:chrome --out test-artifacts/chrome/benchmark/user_actions.json --retries 2
- store_artifacts:
path: test-artifacts
destination: test-artifacts
- persist_to_workspace:
root: .
paths:
- test-artifacts
stats-module-load-init: stats-module-load-init:
executor: node-browsers-medium-plus executor: node-browsers-medium-plus

@ -107,6 +107,8 @@ async function start() {
const moduleLoadStatsLink = `<a href="${moduleLoadStatsUrl}">Module Load Stats</a>`; const moduleLoadStatsLink = `<a href="${moduleLoadStatsUrl}">Module Load Stats</a>`;
const bundleSizeStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/mv3/bundle_size.json`; const bundleSizeStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/mv3/bundle_size.json`;
const bundleSizeStatsLink = `<a href="${bundleSizeStatsUrl}">Bundle Size Stats</a>`; const bundleSizeStatsLink = `<a href="${bundleSizeStatsUrl}">Bundle Size Stats</a>`;
const userActionsStatsUrl = `${BUILD_LINK_BASE}/test-artifacts/chrome/benchmark/user_actions.json`;
const userActionsStatsLink = `<a href="${userActionsStatsUrl}">E2e Actions 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`;
@ -120,6 +122,7 @@ async function start() {
`mv3: ${moduleInitStatsUILink}`, `mv3: ${moduleInitStatsUILink}`,
`mv3: ${moduleLoadStatsLink}`, `mv3: ${moduleLoadStatsLink}`,
`mv3: ${bundleSizeStatsLink}`, `mv3: ${bundleSizeStatsLink}`,
`mv2: ${userActionsStatsLink}`,
`code coverage: ${coverageLink}`, `code coverage: ${coverageLink}`,
`storybook: ${storybookLink}`, `storybook: ${storybookLink}`,
`typescript migration: ${tsMigrationDashboardLink}`, `typescript migration: ${tsMigrationDashboardLink}`,

@ -18,6 +18,7 @@
"start:test": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' yarn build testDev", "start:test": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' yarn build testDev",
"benchmark:chrome": "SELENIUM_BROWSER=chrome node test/e2e/benchmark.js", "benchmark:chrome": "SELENIUM_BROWSER=chrome node test/e2e/benchmark.js",
"mv3:stats:chrome": "SELENIUM_BROWSER=chrome ENABLE_MV3=true node test/e2e/mv3-perf-stats/index.js", "mv3:stats:chrome": "SELENIUM_BROWSER=chrome ENABLE_MV3=true node test/e2e/mv3-perf-stats/index.js",
"user-actions-benchmark:chrome": "SELENIUM_BROWSER=chrome node test/e2e/user-actions-benchmark.js",
"benchmark:firefox": "SELENIUM_BROWSER=firefox node test/e2e/benchmark.js", "benchmark:firefox": "SELENIUM_BROWSER=firefox node test/e2e/benchmark.js",
"build:test": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' yarn build test", "build:test": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' yarn build test",
"build:test:flask": "yarn build test --build-type flask", "build:test:flask": "yarn build test --build-type flask",

@ -0,0 +1,130 @@
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 { convertToHexValue, withFixtures } = require('./helpers');
const ganacheOptions = {
accounts: [
{
secretKey:
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
balance: convertToHexValue(25000000000000000000),
},
],
};
async function loadNewAccount() {
let loadingTimes;
await withFixtures(
{
fixtures: 'imported-account',
ganacheOptions,
},
async ({ driver }) => {
await driver.navigate();
await driver.fill('#password', 'correct horse battery staple');
await driver.press('#password', driver.Key.ENTER);
await driver.clickElement('.account-menu__icon');
const timestampBeforeAction = new Date();
await driver.clickElement({ text: 'Create account', tag: 'div' });
await driver.fill('.new-account-create-form input', '2nd account');
await driver.clickElement({ text: 'Create', tag: 'button' });
await driver.waitForSelector({
css: '.currency-display-component__text',
text: '0',
});
const timestampAfterAction = new Date();
loadingTimes = timestampAfterAction - timestampBeforeAction;
},
);
return loadingTimes;
}
async function confirmTx() {
let loadingTimes;
await withFixtures(
{
fixtures: 'imported-account',
ganacheOptions,
},
async ({ driver }) => {
await driver.navigate();
await driver.fill('#password', 'correct horse battery staple');
await driver.press('#password', driver.Key.ENTER);
await driver.clickElement('[data-testid="eth-overview-send"]');
await driver.fill(
'input[placeholder="Search, public address (0x), or ENS"]',
'0x2f318C334780961FB129D2a6c30D0763d9a5C970',
);
const inputAmount = await driver.findElement('.unit-input__input');
await inputAmount.fill('1');
await driver.clickElement({ text: 'Next', tag: 'button' });
const timestampBeforeAction = new Date();
await driver.clickElement({ text: 'Confirm', tag: 'button' });
await driver.clickElement('[data-testid="home__activity-tab"]');
await driver.wait(async () => {
const confirmedTxes = await driver.findElements(
'.transaction-list__completed-transactions .transaction-list-item',
);
return confirmedTxes.length === 1;
}, 10000);
await driver.waitForSelector('.transaction-status--confirmed');
const timestampAfterAction = new Date();
loadingTimes = timestampAfterAction - timestampBeforeAction;
},
);
return loadingTimes;
}
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 = {};
results.loadNewAccount = await loadNewAccount();
results.confirmTx = await confirmTx();
const { out } = argv;
if (out) {
const outputDirectory = path.dirname(out);
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(out, JSON.stringify(results, null, 2));
} else {
console.log(JSON.stringify(results, null, 2));
}
}
main().catch((error) => {
exitWithError(error);
});
Loading…
Cancel
Save