Skip to content

Commit

Permalink
Merge branch 'develop' into 17191/onboarding-unit-tests-create-new-vault
Browse files Browse the repository at this point in the history
  • Loading branch information
tmashuang authored Apr 1, 2023
2 parents dec423b + a71a069 commit 79aae71
Show file tree
Hide file tree
Showing 60 changed files with 2,019 additions and 110 deletions.
30 changes: 30 additions & 0 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions app/scripts/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,10 @@ export function setupController(initState, initLangCode, overrides) {
if (message.name === WORKER_KEEP_ALIVE_MESSAGE) {
// To test un-comment this line and wait for 1 minute. An error should be shown on MetaMask UI.
remotePort.postMessage({ name: ACK_KEEP_ALIVE_MESSAGE });

controller.appStateController.setServiceWorkerLastActiveTime(
Date.now(),
);
}
});
}
Expand Down
7 changes: 7 additions & 0 deletions app/scripts/controllers/app-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default class AppStateController extends EventEmitter {
'0x5': true,
'0x539': true,
},
serviceWorkerLastActiveTime: 0,
});
this.timer = null;

Expand Down Expand Up @@ -362,4 +363,10 @@ export default class AppStateController extends EventEmitter {
getCurrentPopupId() {
return this.store.getState().currentPopupId;
}

setServiceWorkerLastActiveTime(serviceWorkerLastActiveTime) {
this.store.updateState({
serviceWorkerLastActiveTime,
});
}
}
41 changes: 39 additions & 2 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ import { isMain, isFlask } from '../../shared/constants/environment';
// eslint-disable-next-line import/order
import { DesktopController } from '@metamask/desktop/dist/controllers/desktop';
///: END:ONLY_INCLUDE_IN
import { ACTION_QUEUE_METRICS_E2E_TEST } from '../../shared/constants/test-flags';
import {
onMessageReceived,
checkForMultipleVersionsRunning,
Expand Down Expand Up @@ -695,6 +696,7 @@ export default class MetamaskController extends EventEmitter {
this.keyringController.memStore.subscribe((state) =>
this._onKeyringControllerUpdate(state),
);

this.keyringController.on('unlock', () => this._onUnlock());
this.keyringController.on('lock', () => this._onLock());

Expand Down Expand Up @@ -1190,6 +1192,25 @@ export default class MetamaskController extends EventEmitter {
},
);

if (isManifestV3 && globalThis.isFirstTimeProfileLoaded === false) {
const { serviceWorkerLastActiveTime } =
this.appStateController.store.getState();
const metametricsPayload = {
category: EVENT.SOURCE.SERVICE_WORKERS,
event: EVENT_NAMES.SERVICE_WORKER_RESTARTED,
properties: {
service_worker_restarted_time:
Date.now() - serviceWorkerLastActiveTime,
},
};

try {
this.metaMetricsController.trackEvent(metametricsPayload);
} catch (e) {
log.warn('Failed to track service worker restart metric:', e);
}
}

this.metamaskMiddleware = createMetamaskMiddleware({
static: {
eth_syncing: false,
Expand Down Expand Up @@ -2627,7 +2648,7 @@ export default class MetamaskController extends EventEmitter {
try {
// Automatic login via config password
const password = process.env.CONF?.PASSWORD;
if (password) {
if (password && !process.env.IN_TEST) {
await this.submitPassword(password);
}
// Automatic login via storage encryption key
Expand Down Expand Up @@ -2960,6 +2981,13 @@ export default class MetamaskController extends EventEmitter {
* @returns {} keyState
*/
async addNewAccount(accountCount) {
const isActionMetricsQueueE2ETest =
this.appStateController.store.getState()[ACTION_QUEUE_METRICS_E2E_TEST];

if (process.env.IN_TEST && isActionMetricsQueueE2ETest) {
await new Promise((resolve) => setTimeout(resolve, 5_000));
}

const [primaryKeyring] = this.keyringController.getKeyringsByType(
KeyringType.hdKeyTree,
);
Expand Down Expand Up @@ -3581,7 +3609,11 @@ export default class MetamaskController extends EventEmitter {
phishingStream.on(
'data',
createMetaRPCHandler(
{ safelistPhishingDomain: this.safelistPhishingDomain.bind(this) },
{
safelistPhishingDomain: this.safelistPhishingDomain.bind(this),
backToSafetyPhishingWarning:
this.backToSafetyPhishingWarning.bind(this),
},
phishingStream,
),
);
Expand Down Expand Up @@ -4342,6 +4374,11 @@ export default class MetamaskController extends EventEmitter {
return this.phishingController.bypass(hostname);
}

async backToSafetyPhishingWarning() {
const extensionURL = this.platform.getExtensionURL();
await this.platform.switchToAnotherURL(undefined, extensionURL);
}

/**
* Locks MetaMask
*/
Expand Down
25 changes: 20 additions & 5 deletions app/scripts/platforms/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,7 @@ export default class ExtensionPlatform {
return version;
}

openExtensionInBrowser(
route = null,
queryString = null,
keepWindowOpen = false,
) {
getExtensionURL(route = null, queryString = null) {
let extensionURL = browser.runtime.getURL('home.html');

if (route) {
Expand All @@ -92,7 +88,22 @@ export default class ExtensionPlatform {
extensionURL += `?${queryString}`;
}

return extensionURL;
}

openExtensionInBrowser(
route = null,
queryString = null,
keepWindowOpen = false,
) {
const extensionURL = this.getExtensionURL(
route,
queryString,
keepWindowOpen,
);

this.openTab({ url: extensionURL });

if (
getEnvironmentType() !== ENVIRONMENT_TYPE_BACKGROUND &&
!keepWindowOpen
Expand Down Expand Up @@ -153,6 +164,10 @@ export default class ExtensionPlatform {
return tab;
}

async switchToAnotherURL(tabId, url) {
await browser.tabs.update(tabId, { url });
}

async closeTab(tabId) {
await browser.tabs.remove(tabId);
}
Expand Down
30 changes: 30 additions & 0 deletions app/scripts/platforms/extension.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import browser from 'webextension-polyfill';
import ExtensionPlatform from './extension';

const TEST_URL =
'chrome-extension://jjlgkphpeekojaidfeknpknnimdbleaf/home.html';

jest.mock('webextension-polyfill', () => {
return {
runtime: {
getManifest: jest.fn(),
getURL: jest.fn(),
},
};
});
Expand Down Expand Up @@ -91,4 +95,30 @@ describe('extension platform', () => {
);
});
});

describe('getExtensionURL', () => {
let extensionPlatform;
beforeEach(() => {
browser.runtime.getURL.mockReturnValue(TEST_URL);
extensionPlatform = new ExtensionPlatform();
});

it('should return URL itself if no route or queryString is provided', () => {
expect(extensionPlatform.getExtensionURL()).toStrictEqual(TEST_URL);
});

it('should return URL with route when provided', () => {
const TEST_ROUTE = 'test-route';
expect(extensionPlatform.getExtensionURL(TEST_ROUTE)).toStrictEqual(
`${TEST_URL}#${TEST_ROUTE}`,
);
});

it('should return URL with queryString when provided', () => {
const QUERY_STRING = 'name=ferret';
expect(
extensionPlatform.getExtensionURL(null, QUERY_STRING),
).toStrictEqual(`${TEST_URL}?${QUERY_STRING}`);
});
});
});
7 changes: 6 additions & 1 deletion development/build/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ function getBrowserVersionMap(platforms, version) {
if (!String(buildVersion).match(/^\d+$/u)) {
throw new Error(`Invalid prerelease build version: '${buildVersion}'`);
} else if (
![BuildType.beta, BuildType.flask, BuildType.desktop].includes(buildType)
![
BuildType.beta,
BuildType.flask,
BuildType.desktop,
BuildType.mmi,
].includes(buildType)
) {
throw new Error(`Invalid prerelease build type: ${buildType}`);
}
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"build:test": "SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 PORTFOLIO_URL=http://127.0.0.1:8080 yarn build test",
"build:test:flask": "yarn build test --build-type flask",
"build:test:mv3": "ENABLE_MV3=true SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 PORTFOLIO_URL=http://127.0.0.1:8080 yarn build test",
"build:test:dev:mv3": "ENABLE_MV3=true SEGMENT_HOST='https://api.segment.io' SEGMENT_WRITE_KEY='FAKE' SENTRY_DSN_DEV=https://fake@sentry.io/0000000 PORTFOLIO_URL=http://127.0.0.1:8080 yarn build:dev testDev --apply-lavamoat=false",
"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'",
Expand All @@ -32,6 +33,7 @@
"test:unit:mocha": "node ./test/run-unit-tests.js --mocha",
"test:e2e:chrome": "SELENIUM_BROWSER=chrome node test/e2e/run-all.js",
"test:e2e:chrome:snaps": "SELENIUM_BROWSER=chrome node test/e2e/run-all.js --snaps",
"test:e2e:chrome:mv3": "SELENIUM_BROWSER=chrome node test/e2e/run-all.js --mv3",
"test:e2e:firefox": "SELENIUM_BROWSER=firefox node test/e2e/run-all.js",
"test:e2e:firefox:snaps": "SELENIUM_BROWSER=firefox node test/e2e/run-all.js --snaps",
"test:e2e:single": "node test/e2e/run-e2e-test.js",
Expand Down Expand Up @@ -375,7 +377,7 @@
"@metamask/eslint-config-nodejs": "^9.0.0",
"@metamask/eslint-config-typescript": "^9.0.1",
"@metamask/forwarder": "^1.1.0",
"@metamask/phishing-warning": "^2.0.1",
"@metamask/phishing-warning": "^2.1.0",
"@metamask/test-dapp": "^5.6.0",
"@sentry/cli": "^1.58.0",
"@storybook/addon-a11y": "^6.5.13",
Expand Down
2 changes: 2 additions & 0 deletions shared/constants/metametrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ export const EVENT_NAMES = {
ONBOARDING_WALLET_IMPORT_ATTEMPTED: 'Wallet Import Attempted',
ONBOARDING_WALLET_VIDEO_PLAY: 'SRP Intro Video Played',
ONBOARDING_TWITTER_CLICK: 'External Link Clicked',
SERVICE_WORKER_RESTARTED: 'Service Worker Restarted',
};

export const EVENT = {
Expand Down Expand Up @@ -447,6 +448,7 @@ export const EVENT = {
DAPP: 'dapp',
USER: 'user',
},
SERVICE_WORKERS: 'service_workers',
},
LOCATION: {
TOKEN_DETAILS: 'token_details',
Expand Down
1 change: 1 addition & 0 deletions shared/constants/test-flags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ACTION_QUEUE_METRICS_E2E_TEST = 'action_queue_metrics_e2e_test';
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import { memoize } from 'lodash';
import { SECOND } from '../constants/time';

/**
* Returns a function that can be used to make an HTTP request but timing out
* automatically after a desired amount of time.
*
* @param timeout - The number of milliseconds to wait until the request times
* out.
* @returns A function that, when called, returns a promise that either resolves
* to the HTTP response object or is rejected if a network error is encountered
* or the request times out.
*/
const getFetchWithTimeout = memoize((timeout = SECOND * 30) => {
if (!Number.isInteger(timeout) || timeout < 1) {
throw new Error('Must specify positive integer timeout.');
}

return async function _fetch(url, opts) {
return async function fetchWithTimeout(
url: RequestInfo,
opts?: RequestInit,
): Promise<Response> {
const abortController = new window.AbortController();
const { signal } = abortController;
const f = window.fetch(url, {
Expand All @@ -17,12 +30,9 @@ const getFetchWithTimeout = memoize((timeout = SECOND * 30) => {
const timer = setTimeout(() => abortController.abort(), timeout);

try {
const res = await f;
return await f;
} finally {
clearTimeout(timer);
return res;
} catch (e) {
clearTimeout(timer);
throw e;
}
};
});
Expand Down
Loading

0 comments on commit 79aae71

Please sign in to comment.