mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +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:
|
- prep-build-test-flask:
|
||||||
requires:
|
requires:
|
||||||
- prep-deps
|
- prep-deps
|
||||||
- prep-build-test-metrics:
|
|
||||||
requires:
|
|
||||||
- prep-deps
|
|
||||||
- test-storybook:
|
- test-storybook:
|
||||||
requires:
|
requires:
|
||||||
- prep-deps
|
- prep-deps
|
||||||
@ -87,12 +84,6 @@ workflows:
|
|||||||
- test-e2e-firefox-snaps:
|
- test-e2e-firefox-snaps:
|
||||||
requires:
|
requires:
|
||||||
- prep-build-test-flask
|
- prep-build-test-flask
|
||||||
- test-e2e-chrome-metrics:
|
|
||||||
requires:
|
|
||||||
- prep-build-test-metrics
|
|
||||||
- test-e2e-firefox-metrics:
|
|
||||||
requires:
|
|
||||||
- prep-build-test-metrics
|
|
||||||
- test-unit:
|
- test-unit:
|
||||||
requires:
|
requires:
|
||||||
- prep-deps
|
- prep-deps
|
||||||
@ -137,8 +128,6 @@ workflows:
|
|||||||
- test-mozilla-lint-flask
|
- test-mozilla-lint-flask
|
||||||
- test-e2e-chrome
|
- test-e2e-chrome
|
||||||
- test-e2e-firefox
|
- test-e2e-firefox
|
||||||
- test-e2e-chrome-metrics
|
|
||||||
- test-e2e-firefox-metrics
|
|
||||||
- test-e2e-chrome-snaps
|
- test-e2e-chrome-snaps
|
||||||
- test-e2e-firefox-snaps
|
- test-e2e-firefox-snaps
|
||||||
- benchmark:
|
- benchmark:
|
||||||
@ -338,27 +327,6 @@ jobs:
|
|||||||
- dist-test
|
- dist-test
|
||||||
- builds-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:
|
prep-build-storybook:
|
||||||
executor: node-browsers
|
executor: node-browsers
|
||||||
steps:
|
steps:
|
||||||
@ -553,33 +521,6 @@ jobs:
|
|||||||
path: test-artifacts
|
path: test-artifacts
|
||||||
destination: 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:
|
test-e2e-firefox:
|
||||||
executor: node-browsers-medium-plus
|
executor: node-browsers-medium-plus
|
||||||
steps:
|
steps:
|
||||||
@ -607,33 +548,6 @@ jobs:
|
|||||||
path: test-artifacts
|
path: test-artifacts
|
||||||
destination: 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:
|
benchmark:
|
||||||
executor: node-browsers-medium-plus
|
executor: node-browsers-medium-plus
|
||||||
steps:
|
steps:
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import Analytics from 'analytics-node';
|
import Analytics from 'analytics-node';
|
||||||
import { SECOND } from '../../../shared/constants/time';
|
import { SECOND } from '../../../shared/constants/time';
|
||||||
|
|
||||||
const isDevOrTestEnvironment = Boolean(
|
const isDevEnvironment = Boolean(
|
||||||
process.env.METAMASK_DEBUG || process.env.IN_TEST,
|
process.env.METAMASK_DEBUG && !process.env.IN_TEST,
|
||||||
);
|
);
|
||||||
const SEGMENT_WRITE_KEY = process.env.SEGMENT_WRITE_KEY ?? null;
|
const SEGMENT_WRITE_KEY = process.env.SEGMENT_WRITE_KEY ?? null;
|
||||||
const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null;
|
const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null;
|
||||||
@ -82,7 +82,7 @@ export const createSegmentMock = (flushAt = SEGMENT_FLUSH_AT) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const segment =
|
export const segment =
|
||||||
!SEGMENT_WRITE_KEY || (isDevOrTestEnvironment && !SEGMENT_HOST)
|
!SEGMENT_WRITE_KEY || (isDevEnvironment && !SEGMENT_HOST)
|
||||||
? createSegmentMock(SEGMENT_FLUSH_AT, SEGMENT_FLUSH_INTERVAL)
|
? createSegmentMock(SEGMENT_FLUSH_AT, SEGMENT_FLUSH_INTERVAL)
|
||||||
: new Analytics(SEGMENT_WRITE_KEY, {
|
: new Analytics(SEGMENT_WRITE_KEY, {
|
||||||
host: SEGMENT_HOST,
|
host: SEGMENT_HOST,
|
||||||
|
@ -14,12 +14,11 @@
|
|||||||
"dist": "yarn build prod",
|
"dist": "yarn build prod",
|
||||||
"build": "yarn lavamoat:build",
|
"build": "yarn lavamoat:build",
|
||||||
"build:dev": "node development/build/index.js",
|
"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:chrome": "SELENIUM_BROWSER=chrome node test/e2e/benchmark.js",
|
||||||
"benchmark:firefox": "SELENIUM_BROWSER=firefox 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: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",
|
"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": "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'",
|
"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 path = require('path');
|
||||||
const sinon = require('sinon');
|
|
||||||
const BigNumber = require('bignumber.js');
|
const BigNumber = require('bignumber.js');
|
||||||
const mockttp = require('mockttp');
|
const mockttp = require('mockttp');
|
||||||
const createStaticServer = require('../../development/create-static-server');
|
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 enLocaleMessages = require('../../app/_locales/en/messages.json');
|
||||||
|
const { setupMocking } = require('./mock-e2e');
|
||||||
const Ganache = require('./ganache');
|
const Ganache = require('./ganache');
|
||||||
const FixtureServer = require('./fixture-server');
|
const FixtureServer = require('./fixture-server');
|
||||||
const { buildWebDriver } = require('./webdriver');
|
const { buildWebDriver } = require('./webdriver');
|
||||||
@ -27,7 +23,6 @@ async function withFixtures(options, testSuite) {
|
|||||||
fixtures,
|
fixtures,
|
||||||
ganacheOptions,
|
ganacheOptions,
|
||||||
driverOptions,
|
driverOptions,
|
||||||
mockSegment,
|
|
||||||
title,
|
title,
|
||||||
failOnConsoleError = true,
|
failOnConsoleError = true,
|
||||||
dappPath = undefined,
|
dappPath = undefined,
|
||||||
@ -38,11 +33,9 @@ async function withFixtures(options, testSuite) {
|
|||||||
const fixtureServer = new FixtureServer();
|
const fixtureServer = new FixtureServer();
|
||||||
const ganacheServer = new Ganache();
|
const ganacheServer = new Ganache();
|
||||||
const https = await mockttp.generateCACertificate();
|
const https = await mockttp.generateCACertificate();
|
||||||
const mockServer = mockttp.getLocal({ https });
|
const mockServer = mockttp.getLocal({ https, cors: true });
|
||||||
let secondaryGanacheServer;
|
let secondaryGanacheServer;
|
||||||
let dappServer;
|
let dappServer;
|
||||||
let segmentServer;
|
|
||||||
let segmentStub;
|
|
||||||
|
|
||||||
let webDriver;
|
let webDriver;
|
||||||
let failed = false;
|
let failed = false;
|
||||||
@ -82,17 +75,6 @@ async function withFixtures(options, testSuite) {
|
|||||||
dappServer.on('error', reject);
|
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 setupMocking(mockServer, testSpecificMock);
|
||||||
await mockServer.start(8000);
|
await mockServer.start(8000);
|
||||||
if (
|
if (
|
||||||
@ -106,7 +88,6 @@ async function withFixtures(options, testSuite) {
|
|||||||
|
|
||||||
await testSuite({
|
await testSuite({
|
||||||
driver,
|
driver,
|
||||||
segmentStub,
|
|
||||||
mockServer,
|
mockServer,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -154,9 +135,6 @@ async function withFixtures(options, testSuite) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (segmentServer) {
|
|
||||||
await segmentServer.stop();
|
|
||||||
}
|
|
||||||
await mockServer.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) {
|
async function setupMocking(server, testSpecificMock) {
|
||||||
await server.forAnyRequest().thenPassThrough();
|
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
|
await server
|
||||||
.forGet('https://gas-api.metaswap.codefi.network/networks/1/gasPrices')
|
.forGet('https://gas-api.metaswap.codefi.network/networks/1/gasPrices')
|
||||||
.thenCallback(() => {
|
.thenCallback(() => {
|
||||||
return {
|
return {
|
||||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
json: {
|
json: {
|
||||||
SafeGasPrice: '1',
|
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);
|
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(() => {
|
.thenCallback(() => {
|
||||||
return {
|
return {
|
||||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
json: {
|
json: {
|
||||||
version: 2,
|
version: 2,
|
||||||
|
Loading…
Reference in New Issue
Block a user