mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 09:23:21 +01:00
E2e metrics (#13904)
* remove metrics build * remove segment server from tests * enable cors * mock segment globally * metrics e2e test * running test builds * move file * destructuring
This commit is contained in:
parent
524ddcfaf4
commit
c07e477c13
@ -56,9 +56,6 @@ workflows:
|
||||
- prep-build-test-flask:
|
||||
requires:
|
||||
- prep-deps
|
||||
- prep-build-test-metrics:
|
||||
requires:
|
||||
- prep-deps
|
||||
- test-storybook:
|
||||
requires:
|
||||
- prep-deps
|
||||
@ -87,12 +84,6 @@ workflows:
|
||||
- test-e2e-firefox-snaps:
|
||||
requires:
|
||||
- prep-build-test-flask
|
||||
- test-e2e-chrome-metrics:
|
||||
requires:
|
||||
- prep-build-test-metrics
|
||||
- test-e2e-firefox-metrics:
|
||||
requires:
|
||||
- prep-build-test-metrics
|
||||
- test-unit:
|
||||
requires:
|
||||
- prep-deps
|
||||
@ -137,8 +128,6 @@ workflows:
|
||||
- test-mozilla-lint-flask
|
||||
- test-e2e-chrome
|
||||
- test-e2e-firefox
|
||||
- test-e2e-chrome-metrics
|
||||
- test-e2e-firefox-metrics
|
||||
- test-e2e-chrome-snaps
|
||||
- test-e2e-firefox-snaps
|
||||
- benchmark:
|
||||
@ -338,27 +327,6 @@ jobs:
|
||||
- dist-test
|
||||
- builds-test
|
||||
|
||||
prep-build-test-metrics:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: Build extension for testing metrics
|
||||
command: yarn build:test:metrics
|
||||
- run:
|
||||
name: Move test build to 'dist-test-metrics' to avoid conflict with production build
|
||||
command: mv ./dist ./dist-test-metrics
|
||||
- run:
|
||||
name: Move test zips to 'builds-test' to avoid conflict with production build
|
||||
command: mv ./builds ./builds-test-metrics
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- dist-test-metrics
|
||||
- builds-test-metrics
|
||||
|
||||
prep-build-storybook:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
@ -553,33 +521,6 @@ jobs:
|
||||
path: test-artifacts
|
||||
destination: test-artifacts
|
||||
|
||||
test-e2e-chrome-metrics:
|
||||
executor: node-browsers
|
||||
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-metrics ./dist
|
||||
- run:
|
||||
name: Move test zips to builds
|
||||
command: mv ./builds-test-metrics ./builds
|
||||
- run:
|
||||
name: test:e2e:chrome:metrics
|
||||
command: |
|
||||
if .circleci/scripts/test-run-e2e.sh
|
||||
then
|
||||
yarn test:e2e:chrome:metrics --retries 2
|
||||
fi
|
||||
no_output_timeout: 20m
|
||||
- store_artifacts:
|
||||
path: test-artifacts
|
||||
destination: test-artifacts
|
||||
|
||||
test-e2e-firefox:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
@ -607,33 +548,6 @@ jobs:
|
||||
path: test-artifacts
|
||||
destination: test-artifacts
|
||||
|
||||
test-e2e-firefox-metrics:
|
||||
executor: node-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install Firefox
|
||||
command: ./.circleci/scripts/firefox-install.sh
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run:
|
||||
name: Move test build to dist
|
||||
command: mv ./dist-test-metrics ./dist
|
||||
- run:
|
||||
name: Move test zips to builds
|
||||
command: mv ./builds-test-metrics ./builds
|
||||
- run:
|
||||
name: test:e2e:firefox:metrics
|
||||
command: |
|
||||
if .circleci/scripts/test-run-e2e.sh
|
||||
then
|
||||
yarn test:e2e:firefox:metrics --retries 2
|
||||
fi
|
||||
no_output_timeout: 20m
|
||||
- store_artifacts:
|
||||
path: test-artifacts
|
||||
destination: test-artifacts
|
||||
|
||||
benchmark:
|
||||
executor: node-browsers-medium-plus
|
||||
steps:
|
||||
|
@ -1,8 +1,8 @@
|
||||
import Analytics from 'analytics-node';
|
||||
import { SECOND } from '../../../shared/constants/time';
|
||||
|
||||
const isDevOrTestEnvironment = Boolean(
|
||||
process.env.METAMASK_DEBUG || process.env.IN_TEST,
|
||||
const isDevEnvironment = Boolean(
|
||||
process.env.METAMASK_DEBUG && !process.env.IN_TEST,
|
||||
);
|
||||
const SEGMENT_WRITE_KEY = process.env.SEGMENT_WRITE_KEY ?? null;
|
||||
const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null;
|
||||
@ -82,7 +82,7 @@ export const createSegmentMock = (flushAt = SEGMENT_FLUSH_AT) => {
|
||||
};
|
||||
|
||||
export const segment =
|
||||
!SEGMENT_WRITE_KEY || (isDevOrTestEnvironment && !SEGMENT_HOST)
|
||||
!SEGMENT_WRITE_KEY || (isDevEnvironment && !SEGMENT_HOST)
|
||||
? createSegmentMock(SEGMENT_FLUSH_AT, SEGMENT_FLUSH_INTERVAL)
|
||||
: new Analytics(SEGMENT_WRITE_KEY, {
|
||||
host: SEGMENT_HOST,
|
||||
|
@ -14,12 +14,11 @@
|
||||
"dist": "yarn build prod",
|
||||
"build": "yarn lavamoat:build",
|
||||
"build:dev": "node development/build/index.js",
|
||||
"start:test": "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:firefox": "SELENIUM_BROWSER=firefox node test/e2e/benchmark.js",
|
||||
"build:test": "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:metrics": "SEGMENT_HOST='http://localhost:9090' SEGMENT_WRITE_KEY='FAKE' yarn build test",
|
||||
"test": "yarn lint && yarn test:unit && yarn test:unit:jest",
|
||||
"dapp": "node development/static-server.js node_modules/@metamask/test-dapp/dist --port 8080",
|
||||
"dapp-chain": "GANACHE_ARGS='-b 2' concurrently -k -n ganache,dapp -p '[{time}][{name}]' 'yarn ganache:start' 'sleep 5 && yarn dapp'",
|
||||
|
@ -1,13 +1,9 @@
|
||||
const path = require('path');
|
||||
const sinon = require('sinon');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const mockttp = require('mockttp');
|
||||
const createStaticServer = require('../../development/create-static-server');
|
||||
const {
|
||||
createSegmentServer,
|
||||
} = require('../../development/lib/create-segment-server');
|
||||
const { setupMocking } = require('../../development/mock-e2e');
|
||||
const enLocaleMessages = require('../../app/_locales/en/messages.json');
|
||||
const { setupMocking } = require('./mock-e2e');
|
||||
const Ganache = require('./ganache');
|
||||
const FixtureServer = require('./fixture-server');
|
||||
const { buildWebDriver } = require('./webdriver');
|
||||
@ -27,7 +23,6 @@ async function withFixtures(options, testSuite) {
|
||||
fixtures,
|
||||
ganacheOptions,
|
||||
driverOptions,
|
||||
mockSegment,
|
||||
title,
|
||||
failOnConsoleError = true,
|
||||
dappPath = undefined,
|
||||
@ -38,11 +33,9 @@ async function withFixtures(options, testSuite) {
|
||||
const fixtureServer = new FixtureServer();
|
||||
const ganacheServer = new Ganache();
|
||||
const https = await mockttp.generateCACertificate();
|
||||
const mockServer = mockttp.getLocal({ https });
|
||||
const mockServer = mockttp.getLocal({ https, cors: true });
|
||||
let secondaryGanacheServer;
|
||||
let dappServer;
|
||||
let segmentServer;
|
||||
let segmentStub;
|
||||
|
||||
let webDriver;
|
||||
let failed = false;
|
||||
@ -82,17 +75,6 @@ async function withFixtures(options, testSuite) {
|
||||
dappServer.on('error', reject);
|
||||
});
|
||||
}
|
||||
if (mockSegment) {
|
||||
segmentStub = sinon.stub();
|
||||
segmentServer = createSegmentServer((_request, response, events) => {
|
||||
for (const event of events) {
|
||||
segmentStub(event);
|
||||
}
|
||||
response.statusCode = 200;
|
||||
response.end();
|
||||
});
|
||||
await segmentServer.start(9090);
|
||||
}
|
||||
await setupMocking(mockServer, testSpecificMock);
|
||||
await mockServer.start(8000);
|
||||
if (
|
||||
@ -106,7 +88,6 @@ async function withFixtures(options, testSuite) {
|
||||
|
||||
await testSuite({
|
||||
driver,
|
||||
segmentStub,
|
||||
mockServer,
|
||||
});
|
||||
|
||||
@ -154,9 +135,6 @@ async function withFixtures(options, testSuite) {
|
||||
});
|
||||
});
|
||||
}
|
||||
if (segmentServer) {
|
||||
await segmentServer.stop();
|
||||
}
|
||||
await mockServer.stop();
|
||||
}
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
const { strict: assert } = require('assert');
|
||||
const waitUntilCalled = require('../lib/wait-until-called');
|
||||
const { convertToHexValue, withFixtures, tinyDelayMs } = require('./helpers');
|
||||
|
||||
/**
|
||||
* WARNING: These tests must be run using a build created with `yarn build:test:metrics`, so that it has
|
||||
* the correct Segment host and write keys set. Otherwise this test will fail.
|
||||
*/
|
||||
describe('Segment metrics', function () {
|
||||
this.timeout(0);
|
||||
|
||||
it('should send first three Page metric events upon fullscreen page load', async function () {
|
||||
const ganacheOptions = {
|
||||
accounts: [
|
||||
{
|
||||
secretKey:
|
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
|
||||
balance: convertToHexValue(25000000000000000000),
|
||||
},
|
||||
],
|
||||
};
|
||||
await withFixtures(
|
||||
{
|
||||
fixtures: 'metrics-enabled',
|
||||
ganacheOptions,
|
||||
title: this.test.title,
|
||||
mockSegment: true,
|
||||
},
|
||||
async ({ driver, segmentStub }) => {
|
||||
const threeSegmentEventsReceived = waitUntilCalled(segmentStub, null, {
|
||||
callCount: 3,
|
||||
});
|
||||
await driver.delay(tinyDelayMs);
|
||||
await driver.navigate();
|
||||
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
|
||||
await threeSegmentEventsReceived();
|
||||
|
||||
assert.ok(segmentStub.called, 'Segment should receive metrics');
|
||||
|
||||
const firstSegmentEvent = segmentStub.getCall(0).args[0];
|
||||
assert.equal(firstSegmentEvent.name, 'Home');
|
||||
assert.equal(firstSegmentEvent.context.page.path, '/');
|
||||
|
||||
const secondSegmentEvent = segmentStub.getCall(1).args[0];
|
||||
assert.equal(secondSegmentEvent.name, 'Unlock Page');
|
||||
assert.equal(secondSegmentEvent.context.page.path, '/unlock');
|
||||
|
||||
const thirdSegmentEvent = segmentStub.getCall(2).args[0];
|
||||
assert.equal(thirdSegmentEvent.name, 'Home');
|
||||
assert.equal(thirdSegmentEvent.context.page.path, '/');
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
@ -1,24 +1,10 @@
|
||||
async function setupMocking(server, testSpecificMock) {
|
||||
await server.forAnyRequest().thenPassThrough();
|
||||
|
||||
await server
|
||||
.forOptions('https://gas-api.metaswap.codefi.network/networks/1/gasPrices')
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
'Access-Control-Allow-Headers': 'content-type,x-client-id',
|
||||
},
|
||||
statusCode: 200,
|
||||
};
|
||||
});
|
||||
|
||||
await server
|
||||
.forGet('https://gas-api.metaswap.codefi.network/networks/1/gasPrices')
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||
statusCode: 200,
|
||||
json: {
|
||||
SafeGasPrice: '1',
|
||||
@ -28,6 +14,12 @@ async function setupMocking(server, testSpecificMock) {
|
||||
};
|
||||
});
|
||||
|
||||
await server.forPost('https://api.segment.io/v1/batch').thenCallback(() => {
|
||||
return {
|
||||
statusCode: 200,
|
||||
};
|
||||
});
|
||||
|
||||
testSpecificMock(server);
|
||||
}
|
||||
|
61
test/e2e/tests/metrics.spec.js
Normal file
61
test/e2e/tests/metrics.spec.js
Normal file
@ -0,0 +1,61 @@
|
||||
const { strict: assert } = require('assert');
|
||||
const { convertToHexValue, withFixtures } = require('../helpers');
|
||||
|
||||
describe('Segment metrics', function () {
|
||||
async function mockSegment(mockServer) {
|
||||
mockServer.reset();
|
||||
await mockServer.forAnyRequest().thenPassThrough();
|
||||
return await mockServer
|
||||
.forPost('https://api.segment.io/v1/batch')
|
||||
.withJsonBodyIncluding({ batch: [{ type: 'page' }] })
|
||||
.times(3)
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
statusCode: 200,
|
||||
};
|
||||
});
|
||||
}
|
||||
const ganacheOptions = {
|
||||
accounts: [
|
||||
{
|
||||
secretKey:
|
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
|
||||
balance: convertToHexValue(25000000000000000000),
|
||||
},
|
||||
],
|
||||
};
|
||||
it('should send first three Page metric events upon fullscreen page load', async function () {
|
||||
await withFixtures(
|
||||
{
|
||||
fixtures: 'metrics-enabled',
|
||||
ganacheOptions,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver, mockServer }) => {
|
||||
const mockedEndpoints = await mockSegment(mockServer);
|
||||
await driver.navigate();
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
await driver.wait(async () => {
|
||||
const isPending = await mockedEndpoints.isPending();
|
||||
return isPending === false;
|
||||
}, 10000);
|
||||
const mockedRequests = await mockedEndpoints.getSeenRequests();
|
||||
assert.equal(mockedRequests.length, 3);
|
||||
const [firstMock, secondMock, thirdMock] = mockedRequests;
|
||||
let [mockJson] = firstMock.body.json.batch;
|
||||
let { title, path } = mockJson.context.page;
|
||||
assert.equal(title, 'Home');
|
||||
assert.equal(path, '/');
|
||||
[mockJson] = secondMock.body.json.batch;
|
||||
({ title, path } = mockJson.context.page);
|
||||
assert.equal(title, 'Unlock Page');
|
||||
assert.equal(path, '/unlock');
|
||||
[mockJson] = thirdMock.body.json.batch;
|
||||
({ title, path } = mockJson.context.page);
|
||||
assert.equal(title, 'Home');
|
||||
assert.equal(path, '/');
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
@ -10,7 +10,6 @@ describe('Phishing Detection', function () {
|
||||
)
|
||||
.thenCallback(() => {
|
||||
return {
|
||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||
statusCode: 200,
|
||||
json: {
|
||||
version: 2,
|
||||
|
Loading…
Reference in New Issue
Block a user