From 9167a688995d172fe49d48e331affcc1b58b4e73 Mon Sep 17 00:00:00 2001 From: legobeat <109787230+legobeat@users.noreply.github.com> Date: Wed, 3 May 2023 23:19:59 +0000 Subject: [PATCH 01/20] devDeps: Remove concat-cli (#6315) Doesn't seem to ever have been useful. Introduced in 69381f094e Prefer `cat`. --- package.json | 1 - yarn.lock | 45 +++------------------------------------------ 2 files changed, 3 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 4fc102c9ff2..80c2b98b6af 100644 --- a/package.json +++ b/package.json @@ -362,7 +362,6 @@ "babel-loader": "^8.2.3", "browserstack-local": "^1.5.1", "chromedriver": "^99.0.0", - "concat-cli": "4.0.0", "detox": "^19.11.0", "dotenv": "^16.0.3", "enzyme": "3.9.0", diff --git a/yarn.lock b/yarn.lock index 6425b076007..ffc4913cc2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9041,11 +9041,6 @@ camelcase-keys@^3.0.0: camelcase "^3.0.0" map-obj "^1.0.0" -camelcase@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= - camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" @@ -9465,7 +9460,7 @@ clipboardy@^2.3.0: execa "^1.0.0" is-wsl "^2.1.1" -cliui@^3.0.3, cliui@^3.2.0: +cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= @@ -9691,7 +9686,7 @@ commander@9.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-9.3.0.tgz#f619114a5a2d2054e0d9ff1b31d5ccf89255e26b" integrity sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw== -commander@^2.19.0, commander@^2.8.1, commander@^2.9.0: +commander@^2.19.0, commander@^2.8.1: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -9779,15 +9774,6 @@ compression@^1.7.1: safe-buffer "5.1.2" vary "~1.1.2" -concat-cli@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/concat-cli/-/concat-cli-4.0.0.tgz#a73a0fb0d18b25804ebe703bcc35922324dbf74d" - integrity sha1-pzoPsNGLJYBOvnA7zDWSIyTb900= - dependencies: - chalk "^1.1.1" - concat "^1.0.0" - yargs "^3.30.0" - concat-stream@^1.4.4: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" @@ -9798,13 +9784,6 @@ concat-stream@^1.4.4: readable-stream "^2.2.2" typedarray "^0.0.6" -concat@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/concat/-/concat-1.0.3.tgz#40f3353089d65467695cb1886b45edd637d8cca8" - integrity sha1-QPM1MInWVGdpXLGIa0Xt1jfYzKg= - dependencies: - commander "^2.9.0" - connect@^3.6.5: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -24775,11 +24754,6 @@ wide-align@^1.1.2, wide-align@^1.1.5: dependencies: string-width "^1.0.2 || 2 || 3 || 4" -window-size@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" - integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY= - winston-transport@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa" @@ -25097,7 +25071,7 @@ xtend@~3.0.0: resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo= -y18n@^3.2.0, y18n@^3.2.1, "y18n@^3.2.1 || ^4.0.0", y18n@^3.2.2, y18n@^4.0.0, y18n@^5.0.5: +y18n@^3.2.1, "y18n@^3.2.1 || ^4.0.0", y18n@^3.2.2, y18n@^4.0.0, y18n@^5.0.5: version "3.2.2" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== @@ -25251,19 +25225,6 @@ yargs@^17.0.0: y18n "^5.0.5" yargs-parser "^21.0.0" -yargs@^3.30.0: - version "3.32.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" - integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU= - dependencies: - camelcase "^2.0.1" - cliui "^3.0.3" - decamelize "^1.1.1" - os-locale "^1.4.0" - string-width "^1.0.1" - window-size "^0.1.4" - y18n "^3.2.0" - yargs@^7.0.2: version "7.1.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.2.tgz#63a0a5d42143879fdbb30370741374e0641d55db" From f68e629d54ea956be6288b7cb3688e95aaa2df5b Mon Sep 17 00:00:00 2001 From: Sylva Elendu Date: Thu, 4 May 2023 13:41:40 +0100 Subject: [PATCH 02/20] Refactor SendTo - extract code to render from / to addresses into separate component (#6266) * initial commit * draft * cleaned up * lint * include isBalanceZero for fromaddress * fix snapshot * resolved feedback * renaming component names * Update app/components/Views/SendFlow/AddressFrom/AddressFrom.test.tsx Co-authored-by: Ariella Vu <20778143+digiwand@users.noreply.github.com> * Update app/components/Views/SendFlow/SendTo/index.js Co-authored-by: Ariella Vu <20778143+digiwand@users.noreply.github.com> * removed redudant snapshot * rebased to main * snapshot update * removed podfile change --------- Co-authored-by: Ariella Vu <20778143+digiwand@users.noreply.github.com> --- .../SendFlow/AddressFrom/AddressFrom.test.tsx | 61 ++++ .../SendFlow/AddressFrom/AddressFrom.tsx | 108 ++++++ .../SendFlow/AddressFrom/AddressFrom.types.ts | 3 + .../__snapshots__/AddressFrom.test.tsx.snap | 316 ++++++++++++++++++ .../Views/SendFlow/AddressFrom/index.ts | 1 + .../SendFlow/AddressTo/AddressTo.test.tsx | 76 +++++ .../Views/SendFlow/AddressTo/AddressTo.tsx | 115 +++++++ .../SendFlow/AddressTo/AddressTo.types.ts | 13 + .../__snapshots__/AddressTo.test.tsx.snap | 163 +++++++++ .../Views/SendFlow/AddressTo/index.ts | 1 + .../{index.test.tsx => SendTo.test.tsx} | 2 +- ...dex.test.tsx.snap => SendTo.test.tsx.snap} | 7 - app/components/Views/SendFlow/SendTo/index.js | 291 ++++++---------- app/constants/navigation/Routes.ts | 1 + app/constants/test-ids.js | 4 + 15 files changed, 965 insertions(+), 197 deletions(-) create mode 100644 app/components/Views/SendFlow/AddressFrom/AddressFrom.test.tsx create mode 100644 app/components/Views/SendFlow/AddressFrom/AddressFrom.tsx create mode 100644 app/components/Views/SendFlow/AddressFrom/AddressFrom.types.ts create mode 100644 app/components/Views/SendFlow/AddressFrom/__snapshots__/AddressFrom.test.tsx.snap create mode 100644 app/components/Views/SendFlow/AddressFrom/index.ts create mode 100644 app/components/Views/SendFlow/AddressTo/AddressTo.test.tsx create mode 100644 app/components/Views/SendFlow/AddressTo/AddressTo.tsx create mode 100644 app/components/Views/SendFlow/AddressTo/AddressTo.types.ts create mode 100644 app/components/Views/SendFlow/AddressTo/__snapshots__/AddressTo.test.tsx.snap create mode 100644 app/components/Views/SendFlow/AddressTo/index.ts rename app/components/Views/SendFlow/SendTo/{index.test.tsx => SendTo.test.tsx} (98%) rename app/components/Views/SendFlow/SendTo/__snapshots__/{index.test.tsx.snap => SendTo.test.tsx.snap} (90%) diff --git a/app/components/Views/SendFlow/AddressFrom/AddressFrom.test.tsx b/app/components/Views/SendFlow/AddressFrom/AddressFrom.test.tsx new file mode 100644 index 00000000000..ff73aac0ef1 --- /dev/null +++ b/app/components/Views/SendFlow/AddressFrom/AddressFrom.test.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; + +import { render } from '@testing-library/react-native'; + +import Engine from '../../../../core/Engine'; +import SendFlowAddressFrom from './'; + +Engine.init({}); +jest.mock('@react-navigation/native', () => ({ + useNavigation: () => ({ + navigation: {}, + }), + createNavigatorFactory: () => ({}), +})); + +const initialState = { + settings: {}, + engine: { + backgroundState: { + AccountTrackerController: { + accounts: { + '0x0': { + balance: 200, + }, + }, + }, + PreferencesController: { + selectedAddress: '0x0', + identities: { + '0x0': { + address: '0x0', + name: 'Account 1', + }, + }, + }, + }, + }, +}; + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useSelector: jest + .fn() + .mockImplementation((callback) => callback(initialState)), +})); + +const mockStore = configureMockStore(); +const store = mockStore(initialState); + +describe('SendFlowAddressFrom', () => { + it('should render correctly', () => { + const wrapper = render( + + undefined} /> + , + ); + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/app/components/Views/SendFlow/AddressFrom/AddressFrom.tsx b/app/components/Views/SendFlow/AddressFrom/AddressFrom.tsx new file mode 100644 index 00000000000..ca526d1fcc1 --- /dev/null +++ b/app/components/Views/SendFlow/AddressFrom/AddressFrom.tsx @@ -0,0 +1,108 @@ +import React, { useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; + +import { hexToBN } from '@metamask/controller-utils'; +import { useNavigation } from '@react-navigation/native'; + +import { setSelectedAsset } from '../../../../actions/transaction'; +import Routes from '../../../../constants/navigation/Routes'; +import { + selectNetwork, + selectTicker, +} from '../../../../selectors/networkController'; +import { doENSReverseLookup } from '../../../../util/ENSUtils'; +import { renderFromWei } from '../../../../util/number'; +import { getEther, getTicker } from '../../../../util/transactions'; +import { AddressFrom } from '../../../UI/AddressInputs'; +import { SFAddressFromProps } from './AddressFrom.types'; + +const SendFlowAddressFrom = ({ + fromAccountBalanceState, +}: SFAddressFromProps) => { + const navigation = useNavigation(); + const identities = useSelector( + (state: any) => + state.engine.backgroundState.PreferencesController.identities, + ); + + const accounts = useSelector( + (state: any) => + state.engine.backgroundState.AccountTrackerController.accounts, + ); + + const network = useSelector((state: any) => selectNetwork(state)); + const ticker = useSelector(selectTicker); + + const selectedAddress = useSelector( + (state: any) => + state.engine.backgroundState.PreferencesController.selectedAddress, + ); + + const [accountAddress, setAccountAddress] = useState(selectedAddress); + const [accountName, setAccountName] = useState( + identities[selectedAddress].name, + ); + const [accountBalance, setAccountBalance] = useState(''); + + useEffect(() => { + async function getAccount() { + const ens = await doENSReverseLookup(selectedAddress, network); + const balance = `${renderFromWei( + accounts[selectedAddress].balance, + )} ${getTicker(ticker)}`; + const balanceIsZero = hexToBN(accounts[selectedAddress].balance).isZero(); + setAccountName(ens || identities[selectedAddress].name); + setAccountBalance(balance); + fromAccountBalanceState(balanceIsZero); + } + getAccount(); + }, [ + accounts, + selectedAddress, + ticker, + network, + identities, + fromAccountBalanceState, + ]); + + const dispatch = useDispatch(); + + const selectedAssetAction = (selectedAsset: any) => + dispatch(setSelectedAsset(selectedAsset)); + + const onSelectAccount = async (address: string) => { + const { name } = identities[address]; + const balance = `${renderFromWei(accounts[address].balance)} ${getTicker( + ticker, + )}`; + const ens = await doENSReverseLookup(address); + const accName = ens || name; + const balanceIsZero = hexToBN(accounts[address].balance).isZero(); + selectedAssetAction(getEther(ticker)); + setAccountAddress(address); + setAccountName(accName); + setAccountBalance(balance); + fromAccountBalanceState(balanceIsZero); + }; + + const openAccountSelector = () => { + navigation.navigate(Routes.MODAL.ROOT_MODAL_FLOW, { + screen: Routes.SHEET.ACCOUNT_SELECTOR, + params: { + isSelectOnly: true, + onSelectAccount, + }, + }); + }; + + return ( + + ); +}; + +export default SendFlowAddressFrom; diff --git a/app/components/Views/SendFlow/AddressFrom/AddressFrom.types.ts b/app/components/Views/SendFlow/AddressFrom/AddressFrom.types.ts new file mode 100644 index 00000000000..2f05a877ae2 --- /dev/null +++ b/app/components/Views/SendFlow/AddressFrom/AddressFrom.types.ts @@ -0,0 +1,3 @@ +export interface SFAddressFromProps { + fromAccountBalanceState: (value: boolean) => void; +} diff --git a/app/components/Views/SendFlow/AddressFrom/__snapshots__/AddressFrom.test.tsx.snap b/app/components/Views/SendFlow/AddressFrom/__snapshots__/AddressFrom.test.tsx.snap new file mode 100644 index 00000000000..39eaa4943df --- /dev/null +++ b/app/components/Views/SendFlow/AddressFrom/__snapshots__/AddressFrom.test.tsx.snap @@ -0,0 +1,316 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SendFlowAddressFrom should render correctly 1`] = ` + + + + From: + + + + + + + + + + + + + + + Account 1 + + + + Balance: + + + + + +  + + + + + +`; diff --git a/app/components/Views/SendFlow/AddressFrom/index.ts b/app/components/Views/SendFlow/AddressFrom/index.ts new file mode 100644 index 00000000000..b81c7b9cd14 --- /dev/null +++ b/app/components/Views/SendFlow/AddressFrom/index.ts @@ -0,0 +1 @@ +export { default } from './AddressFrom'; diff --git a/app/components/Views/SendFlow/AddressTo/AddressTo.test.tsx b/app/components/Views/SendFlow/AddressTo/AddressTo.test.tsx new file mode 100644 index 00000000000..c50db44e732 --- /dev/null +++ b/app/components/Views/SendFlow/AddressTo/AddressTo.test.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import { Provider } from 'react-redux'; +import configureMockStore from 'redux-mock-store'; + +import { render } from '@testing-library/react-native'; + +import Engine from '../../../../core/Engine'; +import SendFlowAddressTo from './'; + +Engine.init({}); +jest.mock('@react-navigation/native', () => ({ + useNavigation: () => ({ + navigation: {}, + }), + createNavigatorFactory: () => ({}), +})); + +const initialState = { + settings: {}, + engine: { + backgroundState: { + AccountTrackerController: { + accounts: { + '0x0': { + balance: 200, + }, + }, + }, + AddressBookController: { + addressBook: {}, + }, + PreferencesController: { + selectedAddress: '0x0', + identities: { + '0x0': { + address: '0x0', + name: 'Account 1', + }, + }, + }, + }, + }, +}; + +const mockStore = configureMockStore(); +const store = mockStore(initialState); + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useSelector: jest + .fn() + .mockImplementation((callback) => callback(initialState)), +})); + +describe('SendFlowAddressTo', () => { + it('should render correctly', () => { + const wrapper = render( + + undefined} + inputWidth={undefined} + confusableCollectionArray={undefined} + isFromAddressBook={undefined} + updateParentState={undefined} + onToSelectedAddressChange={undefined} + /> + , + ); + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/app/components/Views/SendFlow/AddressTo/AddressTo.tsx b/app/components/Views/SendFlow/AddressTo/AddressTo.tsx new file mode 100644 index 00000000000..af72641ba35 --- /dev/null +++ b/app/components/Views/SendFlow/AddressTo/AddressTo.tsx @@ -0,0 +1,115 @@ +import React from 'react'; +import { Alert } from 'react-native'; +import { useDispatch, useSelector } from 'react-redux'; + +import { useNavigation } from '@react-navigation/native'; + +import { strings } from '../../../../../locales/i18n'; +import { showAlert } from '../../../../actions/alert'; +import { NetworkSwitchErrorType } from '../../../../constants/error'; +import Routes from '../../../../constants/navigation/Routes'; +import Engine from '../../../../core/Engine'; +import { selectNetwork } from '../../../../selectors/networkController'; +import { handleNetworkSwitch } from '../../../../util/networks'; +import { AddressTo } from '../../../UI/AddressInputs'; +import { createQRScannerNavDetails } from '../../QRScanner'; +import { SFAddressToProps } from './AddressTo.types'; + +const SendFlowAddressTo = ({ + addressToReady, + confusableCollectionArray, + highlighted, + inputRef, + inputWidth, + isFromAddressBook, + onSubmit, + onToSelectedAddressChange, + toSelectedAddress, + toSelectedAddressName, + updateParentState, +}: SFAddressToProps) => { + const navigation = useNavigation(); + const dispatch = useDispatch(); + + const network = useSelector(selectNetwork); + + const frequentRpcList = useSelector( + (state: any) => + state.engine.backgroundState.PreferencesController.frequentRpcList, + ); + + const showAlertAction = (config: any) => dispatch(showAlert(config)); + + const onHandleNetworkSwitch = (chain_id: string) => { + try { + const { NetworkController, CurrencyRateController } = Engine.context; + const networkSwitch = handleNetworkSwitch(chain_id, frequentRpcList, { + networkController: NetworkController, + currencyRateController: CurrencyRateController, + }); + + if (!networkSwitch) return; + + showAlertAction({ + isVisible: true, + autodismiss: 5000, + content: 'clipboard-alert', + data: { msg: strings('send.warn_network_change') + network }, + }); + } catch (e: any) { + let alertMessage; + switch (e.message) { + case NetworkSwitchErrorType.missingNetworkId: + alertMessage = strings('send.network_missing_id'); + break; + default: + alertMessage = strings('send.network_not_found_description', { + chain_id, + }); + } + Alert.alert(strings('send.network_not_found_title'), alertMessage); + } + }; + + const onScan = () => { + navigation.navigate( + ...createQRScannerNavDetails({ + onScanSuccess: (meta) => { + if (meta.chain_id) { + onHandleNetworkSwitch(meta.chain_id); + } + if (meta.target_address) { + onToSelectedAddressChange(meta.target_address); + } + }, + origin: Routes.SEND_FLOW.SEND_TO, + }), + ); + }; + + const onToInputFocus = () => { + updateParentState({ highlighted: !highlighted }); + }; + const onClear = () => onToSelectedAddressChange(); + + return ( + + ); +}; + +export default SendFlowAddressTo; diff --git a/app/components/Views/SendFlow/AddressTo/AddressTo.types.ts b/app/components/Views/SendFlow/AddressTo/AddressTo.types.ts new file mode 100644 index 00000000000..aab56bd1fbe --- /dev/null +++ b/app/components/Views/SendFlow/AddressTo/AddressTo.types.ts @@ -0,0 +1,13 @@ +export interface SFAddressToProps { + addressToReady: boolean; + confusableCollectionArray: any; + highlighted: boolean; + inputRef: any; + inputWidth: any; + isFromAddressBook: any; + onSubmit: (address: string) => void; + onToSelectedAddressChange: any; + toSelectedAddress: any; + toSelectedAddressName: any; + updateParentState: any; +} diff --git a/app/components/Views/SendFlow/AddressTo/__snapshots__/AddressTo.test.tsx.snap b/app/components/Views/SendFlow/AddressTo/__snapshots__/AddressTo.test.tsx.snap new file mode 100644 index 00000000000..2af301d8711 --- /dev/null +++ b/app/components/Views/SendFlow/AddressTo/__snapshots__/AddressTo.test.tsx.snap @@ -0,0 +1,163 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SendFlowAddressTo should render correctly 1`] = ` + + + + To: + + + + + + + + +  + + + + +`; diff --git a/app/components/Views/SendFlow/AddressTo/index.ts b/app/components/Views/SendFlow/AddressTo/index.ts new file mode 100644 index 00000000000..73015feda7b --- /dev/null +++ b/app/components/Views/SendFlow/AddressTo/index.ts @@ -0,0 +1 @@ +export { default } from './AddressTo'; diff --git a/app/components/Views/SendFlow/SendTo/index.test.tsx b/app/components/Views/SendFlow/SendTo/SendTo.test.tsx similarity index 98% rename from app/components/Views/SendFlow/SendTo/index.test.tsx rename to app/components/Views/SendFlow/SendTo/SendTo.test.tsx index b303f77636f..d4a384c52b4 100644 --- a/app/components/Views/SendFlow/SendTo/index.test.tsx +++ b/app/components/Views/SendFlow/SendTo/SendTo.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { shallow } from 'enzyme'; -import SendTo from './'; +import SendTo from '.'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; diff --git a/app/components/Views/SendFlow/SendTo/__snapshots__/index.test.tsx.snap b/app/components/Views/SendFlow/SendTo/__snapshots__/SendTo.test.tsx.snap similarity index 90% rename from app/components/Views/SendFlow/SendTo/__snapshots__/index.test.tsx.snap rename to app/components/Views/SendFlow/SendTo/__snapshots__/SendTo.test.tsx.snap index 05a7be90971..45835b957a5 100644 --- a/app/components/Views/SendFlow/SendTo/__snapshots__/index.test.tsx.snap +++ b/app/components/Views/SendFlow/SendTo/__snapshots__/SendTo.test.tsx.snap @@ -2,13 +2,6 @@ exports[`SendTo should render correctly 1`] = ` true; @@ -84,10 +83,6 @@ const dummy = () => true; */ class SendFlow extends PureComponent { static propTypes = { - /** - * Map of accounts to information objects including balances - */ - accounts: PropTypes.object, /** * Map representing the address book */ @@ -156,6 +151,7 @@ class SendFlow extends PureComponent { * Boolean that indicates if the network supports buy */ isNativeTokenBuySupported: PropTypes.bool, + updateParentState: PropTypes.func, }; addressToInputRef = React.createRef(); @@ -165,8 +161,6 @@ class SendFlow extends PureComponent { balanceIsZero: false, addToAddressBookModalVisible: false, fromSelectedAddress: this.props.selectedAddress, - fromAccountName: this.props.identities[this.props.selectedAddress].name, - fromAccountBalance: undefined, toAccount: undefined, toSelectedAddressName: undefined, toSelectedAddressReady: false, @@ -190,8 +184,6 @@ class SendFlow extends PureComponent { componentDidMount = async () => { const { addressBook, - selectedAddress, - accounts, ticker, network, navigation, @@ -199,24 +191,10 @@ class SendFlow extends PureComponent { route, isPaymentRequest, } = this.props; - const { fromAccountName } = this.state; this.updateNavBar(); // For analytics navigation.setParams({ providerType, isPaymentRequest }); const networkAddressBook = addressBook[network] || {}; - const ens = await doENSReverseLookup(selectedAddress, network); - const fromAccountBalance = `${renderFromWei( - accounts[selectedAddress].balance, - )} ${getTicker(ticker)}`; - - setTimeout(() => { - this.setState({ - fromAccountName: ens || fromAccountName, - fromAccountBalance, - balanceIsZero: hexToBN(accounts[selectedAddress].balance).isZero(), - inputWidth: { width: '100%' }, - }); - }, 100); if (!Object.keys(networkAddressBook).length) { setTimeout(() => { this.addressToInputRef && @@ -243,55 +221,6 @@ class SendFlow extends PureComponent { }); }; - onSelectAccount = async (accountAddress) => { - const { ticker, accounts, identities } = this.props; - const { name } = identities[accountAddress]; - const fromAccountBalance = `${renderFromWei( - accounts[accountAddress].balance, - )} ${getTicker(ticker)}`; - const ens = await doENSReverseLookup(accountAddress); - const fromAccountName = ens || name; - // If new account doesn't have the asset - this.props.setSelectedAsset(getEther(ticker)); - this.setState({ - fromAccountName, - fromAccountBalance, - fromSelectedAddress: accountAddress, - balanceIsZero: hexToBN(accounts[accountAddress].balance).isZero(), - }); - }; - - openAccountSelector = () => { - const { navigation } = this.props; - navigation.navigate(Routes.MODAL.ROOT_MODAL_FLOW, { - screen: Routes.SHEET.ACCOUNT_SELECTOR, - params: { - isSelectOnly: true, - onSelectAccount: this.onSelectAccount, - }, - }); - }; - - /** - * This returns the address name from the address book or user accounts if the selectedAddress exist there - * @param {String} toAccount - Address input - * @returns {String | null} - Address or null if toAccount is not in the addressBook or identities array - */ - getAddressNameFromBookOrIdentities = (toAccount) => { - if (!toAccount) return; - - const { addressBook, network, identities } = this.props; - const networkAddressBook = addressBook[network] || {}; - - const checksummedAddress = toChecksumAddress(toAccount); - - return networkAddressBook[checksummedAddress] - ? networkAddressBook[checksummedAddress].name - : identities[checksummedAddress] - ? identities[checksummedAddress].name - : null; - }; - isAddressSaved = () => { const { toAccount } = this.state; const { addressBook, network, identities } = this.props; @@ -302,71 +231,6 @@ class SendFlow extends PureComponent { ); }; - /** - * This set to the state all the information - * that come from validating an ENS or address - * @param {*} toSelectedAddress - The address or the ens writted on the destination input - */ - validateAddressOrENSFromInput = async (toAccount) => { - const { network, addressBook, identities, chainId } = this.props; - const { - addressError, - toEnsName, - addressReady, - toEnsAddress, - addToAddressToAddressBook, - toAddressName, - errorContinue, - isOnlyWarning, - confusableCollection, - } = await validateAddressOrENS({ - toAccount, - network, - addressBook, - identities, - chainId, - }); - - this.setState({ - addressError, - toEnsName, - toSelectedAddressReady: addressReady, - toEnsAddressResolved: toEnsAddress, - addToAddressToAddressBook, - toSelectedAddressName: toAddressName, - errorContinue, - isOnlyWarning, - confusableCollection, - }); - }; - - onToSelectedAddressChange = (toAccount) => { - const addressName = this.getAddressNameFromBookOrIdentities(toAccount); - - /** - * If the address is from addressBook or identities - * then validation is not necessary since it was already validated - */ - if (addressName) { - this.setState({ - toAccount, - toSelectedAddressReady: true, - isFromAddressBook: true, - toSelectedAddressName: addressName, - }); - } else { - this.validateAddressOrENSFromInput(toAccount); - /** - * Because validateAddressOrENSFromInput is an asynchronous function - * we are setting the state here synchronously, so it does not block the UI - * */ - this.setState({ - toAccount, - isFromAddressBook: false, - }); - } - }; - validateToAddress = () => { const { toAccount, toEnsAddressResolved } = this.state; let addressError; @@ -381,10 +245,6 @@ class SendFlow extends PureComponent { return addressError; }; - onToClear = () => { - this.onToSelectedAddressChange(); - }; - onChangeAlias = (alias) => { this.setState({ alias }); }; @@ -438,22 +298,6 @@ class SendFlow extends PureComponent { } }; - onScan = () => { - this.props.navigation.navigate( - ...createQRScannerNavDetails({ - onScanSuccess: (meta) => { - if (meta.chain_id) { - this.handleNetworkSwitch(meta.chain_id); - } - if (meta.target_address) { - this.onToSelectedAddressChange(meta.target_address); - } - }, - origin: Routes.SEND_FLOW.SEND_TO, - }), - ); - }; - onTransactionDirectionSet = async () => { const { setRecipient, navigation, providerType, addRecent } = this.props; const { @@ -461,13 +305,13 @@ class SendFlow extends PureComponent { toAccount, toEnsName, toSelectedAddressName, - fromAccountName, toEnsAddressResolved, } = this.state; if (!this.isAddressSaved()) { const addressError = this.validateToAddress(); if (addressError) return; } + const toAddress = toEnsAddressResolved || toAccount; addRecent(toAddress); setRecipient( @@ -475,7 +319,6 @@ class SendFlow extends PureComponent { toAddress, toEnsName, toSelectedAddressName, - fromAccountName, ); InteractionManager.runAfterInteractions(() => { Analytics.trackEventWithParameters( @@ -594,19 +437,98 @@ class SendFlow extends PureComponent { addressError ); + updateParentState = (state) => { + this.setState({ ...state }); + }; + + fromAccountBalanceState = (value) => { + this.setState({ balanceIsZero: value }); + }; + + getAddressNameFromBookOrIdentities = (toAccount) => { + const { addressBook, identities, network } = this.props; + if (!toAccount) return; + + const networkAddressBook = addressBook[network] || {}; + + const checksummedAddress = toChecksumAddress(toAccount); + + return networkAddressBook[checksummedAddress] + ? networkAddressBook[checksummedAddress].name + : identities[checksummedAddress] + ? identities[checksummedAddress].name + : null; + }; + + validateAddressOrENSFromInput = async (toAccount) => { + const { addressBook, identities, chainId, network } = this.props; + const { + addressError, + toEnsName, + addressReady, + toEnsAddress, + addToAddressToAddressBook, + toAddressName, + errorContinue, + isOnlyWarning, + confusableCollection, + } = await validateAddressOrENS({ + toAccount, + network, + addressBook, + identities, + chainId, + }); + + this.setState({ + addressError, + toEnsName, + toSelectedAddressReady: addressReady, + toEnsAddressResolved: toEnsAddress, + addToAddressToAddressBook, + toSelectedAddressName: toAddressName, + errorContinue, + isOnlyWarning, + confusableCollection, + }); + }; + + onToSelectedAddressChange = (toAccount) => { + const addressName = this.getAddressNameFromBookOrIdentities(toAccount); + + /** + * If the address is from addressBook or identities + * then validation is not necessary since it was already validated + */ + if (addressName) { + this.setState({ + toAccount, + toSelectedAddressReady: true, + isFromAddressBook: true, + toSelectedAddressName: addressName, + }); + } else { + this.validateAddressOrENSFromInput(toAccount); + /** + * Because validateAddressOrENSFromInput is an asynchronous function + * we are setting the state here synchronously, so it does not block the UI + * */ + this.setState({ + toAccount, + isFromAddressBook: false, + }); + } + }; + render = () => { const { ticker, addressBook, network } = this.props; const { - fromSelectedAddress, - fromAccountName, - fromAccountBalance, toAccount, toSelectedAddressReady, toSelectedAddressName, addToAddressToAddressBook, addressError, balanceIsZero, - toInputHighlighted, inputWidth, errorContinue, isOnlyWarning, @@ -614,6 +536,7 @@ class SendFlow extends PureComponent { isFromAddressBook, toEnsAddressResolved, } = this.state; + const colors = this.context.colors || mockTheme.colors; const styles = createStyles(colors); @@ -639,29 +562,23 @@ class SendFlow extends PureComponent { {...generateTestId(Platform, SEND_SCREEN_ID)} > - - @@ -687,10 +604,7 @@ class SendFlow extends PureComponent { {addressError && addressError !== CONTACT_ALREADY_SAVED && ( - + + {!errorContinue && ( ({ - accounts: state.engine.backgroundState.AccountTrackerController.accounts, addressBook: state.engine.backgroundState.AddressBookController.addressBook, chainId: selectChainId(state), selectedAddress: diff --git a/app/constants/navigation/Routes.ts b/app/constants/navigation/Routes.ts index 0914aa9a15e..044d1b0d388 100644 --- a/app/constants/navigation/Routes.ts +++ b/app/constants/navigation/Routes.ts @@ -45,6 +45,7 @@ const Routes = { }, SEND_FLOW: { SEND_TO: 'SendTo', + AMOUNT: 'Amount', }, ACCOUNT_BACKUP: { STEP_1_B: 'AccountBackupStep1B', diff --git a/app/constants/test-ids.js b/app/constants/test-ids.js index 572b8e1f63d..421fcf81980 100644 --- a/app/constants/test-ids.js +++ b/app/constants/test-ids.js @@ -58,6 +58,10 @@ export const WHATS_NEW_MODAL_GOT_IT_BUTTON_ID = 'whats-new-modal-got-it-button'; export const INPUT_NETWORK_NAME = 'input-network-name'; export const ADDRESS_BOOK_NEXT_BUTTON = 'address-book-next-button'; +export const NO_ETH_MESSAGE = 'no-eth-message'; +export const SEND_SCREEN = 'send-screen'; +export const ADDRESS_ERROR = 'address-error'; +export const ADD_ADDRESS_BUTTON_ID = 'add-address-button'; // Design System test ids export const CELL_DISPLAY_TEST_ID = 'cell-display'; From a601d3abbe102a78bcfd4900021cda13e2c0eb30 Mon Sep 17 00:00:00 2001 From: Pedro Pablo Aste Kompen Date: Thu, 4 May 2023 09:14:21 -0400 Subject: [PATCH 03/20] On-ramp: Add redux-thunk, refactor successful order handler (#6257) --- .../FiatOnRampAggregator/Views/Checkout.tsx | 101 +-------------- .../containers/ApplePayButton.tsx | 78 +++--------- .../hooks/useHandleSuccessfulOrder.ts | 118 ++++++++++++++++++ .../hooks/useInAppBrowser.ts | 70 ++--------- .../UI/FiatOnRampAggregator/index.tsx | 24 +++- .../UI/FiatOnRampAggregator/utils/index.ts | 8 +- app/components/hooks/useThunkDispatch.ts | 11 ++ app/store/index.js | 5 +- package.json | 1 + yarn.lock | 5 + 10 files changed, 192 insertions(+), 229 deletions(-) create mode 100644 app/components/UI/FiatOnRampAggregator/hooks/useHandleSuccessfulOrder.ts create mode 100644 app/components/hooks/useThunkDispatch.ts diff --git a/app/components/UI/FiatOnRampAggregator/Views/Checkout.tsx b/app/components/UI/FiatOnRampAggregator/Views/Checkout.tsx index 47aeee70091..25a6f9cf073 100644 --- a/app/components/UI/FiatOnRampAggregator/Views/Checkout.tsx +++ b/app/components/UI/FiatOnRampAggregator/Views/Checkout.tsx @@ -1,40 +1,32 @@ import React, { useCallback, useEffect, useState } from 'react'; import { View } from 'react-native'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { parseUrl } from 'query-string'; import { WebView, WebViewNavigation } from 'react-native-webview'; import { useNavigation } from '@react-navigation/native'; -import { CryptoCurrency, Order, Provider } from '@consensys/on-ramp-sdk'; +import { Provider } from '@consensys/on-ramp-sdk'; import { baseStyles } from '../../../../styles/common'; import { useTheme } from '../../../../util/theme'; import { getFiatOnRampAggNavbar } from '../../Navbar'; -import { NATIVE_ADDRESS } from '../../../../constants/on-ramp'; import { useFiatOnRampSDK, SDK } from '../sdk'; import { addFiatCustomIdData, - addFiatOrder, - FiatOrder, removeFiatCustomIdData, } from '../../../../reducers/fiatOrders'; import { CustomIdData } from '../../../../reducers/fiatOrders/types'; -import Engine from '../../../../core/Engine'; -import { toLowerCaseEquals } from '../../../../util/general'; import { createNavigationDetails, useParams, } from '../../../../util/navigation/navUtils'; -import { hexToBN } from '../../../../util/number'; -import { protectWalletModalVisible } from '../../../../actions/user'; import { aggregatorOrderToFiatOrder } from '../orderProcessor/aggregator'; import { createCustomOrderIdData } from '../orderProcessor/customOrderId'; -import { getNotificationDetails } from '..'; -import NotificationManager from '../../../../core/NotificationManager'; import ScreenLayout from '../components/ScreenLayout'; import ErrorView from '../components/ErrorView'; import ErrorViewWithReporting from '../components/ErrorViewWithReporting'; import useAnalytics from '../hooks/useAnalytics'; import { strings } from '../../../../../locales/i18n'; import Routes from '../../../../constants/navigation/Routes'; +import useHandleSuccessfulOrder from '../hooks/useHandleSuccessfulOrder'; interface CheckoutParams { url: string; @@ -58,10 +50,7 @@ const CheckoutWebView = () => { const navigation = useNavigation(); const params = useParams(); const { colors } = useTheme(); - const accounts = useSelector( - (state: any) => - state.engine.backgroundState.AccountTrackerController.accounts, - ); + const handleSuccessfulOrder = useHandleSuccessfulOrder(); const { url: uri, customOrderId, provider } = params; @@ -97,88 +86,6 @@ const CheckoutWebView = () => { dispatch(addFiatCustomIdData(customOrderIdData)); }, [customOrderId, dispatch, selectedAddress, selectedChainId]); - const addTokenToTokensController = useCallback( - async (token: CryptoCurrency) => { - if (!token) return; - - const { address, symbol, decimals, network, name } = token; - const chainId = network?.chainId; - - if ( - Number(chainId) !== Number(selectedChainId) || - address === NATIVE_ADDRESS - ) { - return; - } - - // @ts-expect-error Engine context typing - const { TokensController } = Engine.context; - - if ( - !TokensController.state.tokens.includes((t: any) => - toLowerCaseEquals(t.address, address), - ) - ) { - await TokensController.addToken(address, symbol, decimals, null, name); - } - }, - [selectedChainId], - ); - - const handleAddFiatOrder = useCallback( - (order) => { - dispatch(addFiatOrder(order)); - }, - [dispatch], - ); - - const handleDispatchUserWalletProtection = useCallback(() => { - dispatch(protectWalletModalVisible()); - }, [dispatch]); - - const handleSuccessfulOrder = useCallback( - async (order) => { - // add the order to the redux global store - handleAddFiatOrder(order); - // register the token automatically - await addTokenToTokensController((order as any)?.data?.cryptoCurrency); - - // prompt user to protect his/her wallet - handleDispatchUserWalletProtection(); - // close the checkout webview - // @ts-expect-error navigation prop mismatch - navigation.dangerouslyGetParent()?.pop(); - NotificationManager.showSimpleNotification( - getNotificationDetails(order as any), - ); - trackEvent('ONRAMP_PURCHASE_SUBMITTED', { - provider_onramp: ((order as FiatOrder)?.data as Order)?.provider?.name, - payment_method_id: ((order as FiatOrder)?.data as Order)?.paymentMethod - ?.id, - currency_source: ((order as FiatOrder)?.data as Order)?.fiatCurrency - .symbol, - currency_destination: ((order as FiatOrder)?.data as Order) - ?.cryptoCurrency.symbol, - chain_id_destination: selectedChainId, - order_type: (order as FiatOrder)?.orderType, - is_apple_pay: false, - has_zero_native_balance: accounts[selectedAddress]?.balance - ? (hexToBN(accounts[selectedAddress].balance) as any)?.isZero?.() - : undefined, - }); - }, - [ - accounts, - addTokenToTokensController, - handleAddFiatOrder, - handleDispatchUserWalletProtection, - navigation, - selectedAddress, - selectedChainId, - trackEvent, - ], - ); - const handleNavigationStateChange = async (navState: WebViewNavigation) => { if ( !isRedirectionHandled && diff --git a/app/components/UI/FiatOnRampAggregator/containers/ApplePayButton.tsx b/app/components/UI/FiatOnRampAggregator/containers/ApplePayButton.tsx index 1108f1580ee..20e40e87f60 100644 --- a/app/components/UI/FiatOnRampAggregator/containers/ApplePayButton.tsx +++ b/app/components/UI/FiatOnRampAggregator/containers/ApplePayButton.tsx @@ -1,24 +1,19 @@ import React, { useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigation } from '@react-navigation/native'; -import { Order, QuoteResponse } from '@consensys/on-ramp-sdk'; -import { protectWalletModalNotVisible } from '../../../../actions/user'; +import { QuoteResponse } from '@consensys/on-ramp-sdk'; import { addAuthenticationUrl, - addFiatOrder, FiatOrder, } from '../../../../reducers/fiatOrders'; import ApplePayButtonComponent from '../components/ApplePayButton'; import useApplePay, { ABORTED } from '../hooks/useApplePay'; -import useAnalytics from '../hooks/useAnalytics'; import Logger from '../../../../util/Logger'; import { strings } from '../../../../../locales/i18n'; import { setLockTime } from '../../../../actions/settings'; import { aggregatorOrderToFiatOrder } from '../orderProcessor/aggregator'; -import { getNotificationDetails } from '..'; import NotificationManager from '../../../../core/NotificationManager'; -import { hexToBN } from '../../../../util/number'; import { useFiatOnRampSDK } from '../sdk'; +import useHandleSuccessfulOrder from '../hooks/useHandleSuccessfulOrder'; function buildAuthenticationUrl(url: string, redirectUrl: string) { const urlObject = new URL(url); @@ -36,66 +31,13 @@ const ApplePayButton = ({ quote: QuoteResponse; label: string; }) => { - const navigation = useNavigation(); - const dispatch = useDispatch(); - const trackEvent = useAnalytics(); const { selectedAddress, selectedChainId, callbackBaseUrl } = useFiatOnRampSDK(); - const accounts = useSelector( - (state: any) => - state.engine.backgroundState.AccountTrackerController.accounts, - ); - + const dispatch = useDispatch(); const [pay] = useApplePay(quote); + const handleSuccessfulOrder = useHandleSuccessfulOrder(); const lockTime = useSelector((state: any) => state.settings.lockTime); - const addOrder = useCallback( - (order) => dispatch(addFiatOrder(order)), - [dispatch], - ); - const protectWalletModalVisible = useCallback( - () => dispatch(protectWalletModalNotVisible()), - [dispatch], - ); - - const handleSuccessfulOrder = useCallback( - (order) => { - const fiatOrder: FiatOrder = { - ...aggregatorOrderToFiatOrder(order), - network: selectedChainId, - account: selectedAddress, - }; - addOrder(fiatOrder); - // @ts-expect-error pop is not defined - navigation.dangerouslyGetParent()?.pop(); - protectWalletModalVisible(); - NotificationManager.showSimpleNotification( - getNotificationDetails(fiatOrder), - ); - trackEvent('ONRAMP_PURCHASE_SUBMITTED', { - provider_onramp: (fiatOrder?.data as Order)?.provider?.name, - payment_method_id: (fiatOrder?.data as Order)?.paymentMethod?.id, - currency_source: (fiatOrder?.data as Order)?.fiatCurrency.symbol, - currency_destination: (fiatOrder?.data as Order)?.cryptoCurrency.symbol, - chain_id_destination: selectedChainId, - is_apple_pay: true, - order_type: fiatOrder.orderType, - has_zero_native_balance: accounts[selectedAddress]?.balance - ? (hexToBN(accounts[selectedAddress].balance) as any)?.isZero?.() - : undefined, - }); - }, - [ - accounts, - addOrder, - selectedChainId, - navigation, - protectWalletModalVisible, - selectedAddress, - trackEvent, - ], - ); - const handlePress = useCallback(async () => { const prevLockTime = lockTime; dispatch(setLockTime(-1)); @@ -109,8 +51,14 @@ const ApplePayButton = ({ ); dispatch(addAuthenticationUrl(authenticationUrl)); } - - handleSuccessfulOrder(paymentResult.order); + if (paymentResult.order) { + const fiatOrder: FiatOrder = { + ...aggregatorOrderToFiatOrder(paymentResult.order), + network: selectedChainId, + account: selectedAddress, + }; + handleSuccessfulOrder(fiatOrder, { isApplePay: true }); + } } } catch (error: any) { NotificationManager.showSimpleNotification({ @@ -130,6 +78,8 @@ const ApplePayButton = ({ dispatch, pay, callbackBaseUrl, + selectedChainId, + selectedAddress, handleSuccessfulOrder, quote.crypto?.symbol, ]); diff --git a/app/components/UI/FiatOnRampAggregator/hooks/useHandleSuccessfulOrder.ts b/app/components/UI/FiatOnRampAggregator/hooks/useHandleSuccessfulOrder.ts new file mode 100644 index 00000000000..f4c680f303a --- /dev/null +++ b/app/components/UI/FiatOnRampAggregator/hooks/useHandleSuccessfulOrder.ts @@ -0,0 +1,118 @@ +import { CryptoCurrency, Order } from '@consensys/on-ramp-sdk'; +import { hexToBN } from '@metamask/controller-utils'; +import { useNavigation } from '@react-navigation/native'; +import { useCallback } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { getNotificationDetails } from '..'; +import { protectWalletModalVisible } from '../../../../actions/user'; +import { NATIVE_ADDRESS } from '../../../../constants/on-ramp'; +import Engine from '../../../../core/Engine'; +import NotificationManager from '../../../../core/NotificationManager'; +import { addFiatOrder, FiatOrder } from '../../../../reducers/fiatOrders'; +import { toLowerCaseEquals } from '../../../../util/general'; +import useThunkDispatch from '../../../hooks/useThunkDispatch'; +import { useFiatOnRampSDK } from '../sdk'; +import { stateHasOrder } from '../utils'; +import useAnalytics from './useAnalytics'; + +function useHandleSuccessfulOrder() { + const { selectedChainId, selectedAddress } = useFiatOnRampSDK(); + const navigation = useNavigation(); + const dispatch = useDispatch(); + const dispatchThunk = useThunkDispatch(); + const trackEvent = useAnalytics(); + const accounts = useSelector( + (state: any) => + state.engine.backgroundState.AccountTrackerController.accounts, + ); + + const addTokenToTokensController = useCallback( + async (token: CryptoCurrency) => { + if (!token) return; + + const { address, symbol, decimals, network, name } = token; + const chainId = network?.chainId; + + if ( + Number(chainId) !== Number(selectedChainId) || + address === NATIVE_ADDRESS + ) { + return; + } + + const { TokensController } = Engine.context; + + if ( + !TokensController.state.tokens.includes((t: any) => + toLowerCaseEquals(t.address, address), + ) + ) { + await TokensController.addToken(address, symbol, decimals, null, name); + } + }, + [selectedChainId], + ); + + const handleDispatchUserWalletProtection = useCallback(() => { + dispatch(protectWalletModalVisible()); + }, [dispatch]); + + const handleAddFiatOrder = useCallback( + (order) => { + dispatch(addFiatOrder(order)); + }, + [dispatch], + ); + + const handleSuccessfulOrder = useCallback( + async ( + order: FiatOrder, + params?: { + isApplePay?: boolean; + }, + ) => { + await addTokenToTokensController((order as any)?.data?.cryptoCurrency); + handleDispatchUserWalletProtection(); + // @ts-expect-error navigation prop mismatch + navigation.dangerouslyGetParent()?.pop(); + + dispatchThunk((_, getState) => { + const state = getState(); + if (stateHasOrder(state, order)) { + return; + } + handleAddFiatOrder(order); + NotificationManager.showSimpleNotification( + getNotificationDetails(order as any), + ); + trackEvent('ONRAMP_PURCHASE_SUBMITTED', { + provider_onramp: (order?.data as Order)?.provider?.name, + payment_method_id: (order?.data as Order)?.paymentMethod?.id, + currency_source: (order?.data as Order)?.fiatCurrency.symbol, + currency_destination: (order?.data as Order)?.cryptoCurrency.symbol, + chain_id_destination: selectedChainId, + order_type: order?.orderType, + is_apple_pay: Boolean(params?.isApplePay), + has_zero_native_balance: accounts[selectedAddress]?.balance + ? (hexToBN(accounts[selectedAddress].balance) as any)?.isZero?.() + : undefined, + }); + }); + }, + [ + accounts, + addTokenToTokensController, + dispatchThunk, + handleAddFiatOrder, + handleDispatchUserWalletProtection, + navigation, + selectedAddress, + selectedChainId, + trackEvent, + ], + ); + + return handleSuccessfulOrder; +} + +export default useHandleSuccessfulOrder; diff --git a/app/components/UI/FiatOnRampAggregator/hooks/useInAppBrowser.ts b/app/components/UI/FiatOnRampAggregator/hooks/useInAppBrowser.ts index 2b0e7b04829..cc2c58a92a3 100644 --- a/app/components/UI/FiatOnRampAggregator/hooks/useInAppBrowser.ts +++ b/app/components/UI/FiatOnRampAggregator/hooks/useInAppBrowser.ts @@ -2,8 +2,7 @@ import { useCallback } from 'react'; import { Linking } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; import InAppBrowser from 'react-native-inappbrowser-reborn'; -import { useNavigation } from '@react-navigation/native'; -import { Order, OrderStatusEnum, Provider } from '@consensys/on-ramp-sdk'; +import { OrderStatusEnum, Provider } from '@consensys/on-ramp-sdk'; import BuyAction from '@consensys/on-ramp-sdk/dist/regions/BuyAction'; import useAnalytics from './useAnalytics'; import { callbackBaseDeeplink, SDK, useFiatOnRampSDK } from '../sdk'; @@ -11,16 +10,12 @@ import { createCustomOrderIdData } from '../orderProcessor/customOrderId'; import { aggregatorOrderToFiatOrder } from '../orderProcessor/aggregator'; import { addFiatCustomIdData, - addFiatOrder, FiatOrder, removeFiatCustomIdData, } from '../../../../reducers/fiatOrders'; import { setLockTime } from '../../../../actions/settings'; -import { getNotificationDetails } from '..'; -import { protectWalletModalVisible } from '../../../../actions/user'; -import NotificationManager from '../../../../core/NotificationManager'; -import { hexToBN } from '../../../../util/number'; import Logger from '../../../../util/Logger'; +import useHandleSuccessfulOrder from './useHandleSuccessfulOrder'; export default function useInAppBrowser() { const { @@ -29,60 +24,11 @@ export default function useInAppBrowser() { selectedAsset, selectedChainId, } = useFiatOnRampSDK(); - const navigation = useNavigation(); + const dispatch = useDispatch(); const trackEvent = useAnalytics(); const lockTime = useSelector((state: any) => state.settings.lockTime); - const accounts = useSelector( - (state: any) => - state.engine.backgroundState.AccountTrackerController.accounts, - ); - - const handleSuccessfulOrder = useCallback( - (order: Order) => { - const transformedOrder: FiatOrder = { - ...aggregatorOrderToFiatOrder(order), - account: selectedAddress, - network: selectedChainId, - }; - - // add the order to the redux global store - dispatch(addFiatOrder(transformedOrder)); - - // prompt user to protect his/her wallet - dispatch(protectWalletModalVisible()); - // close the checkout webview - // @ts-expect-error navigation prop mismatch - navigation.dangerouslyGetParent()?.pop(); - NotificationManager.showSimpleNotification( - getNotificationDetails(transformedOrder), - ); - trackEvent('ONRAMP_PURCHASE_SUBMITTED', { - provider_onramp: ((transformedOrder as FiatOrder)?.data as Order) - ?.provider?.name, - payment_method_id: ((transformedOrder as FiatOrder)?.data as Order) - ?.paymentMethod?.id, - currency_source: ((transformedOrder as FiatOrder)?.data as Order) - ?.fiatCurrency.symbol, - currency_destination: ((transformedOrder as FiatOrder)?.data as Order) - ?.cryptoCurrency.symbol, - chain_id_destination: selectedChainId, - is_apple_pay: false, - order_type: (transformedOrder as FiatOrder)?.orderType, - has_zero_native_balance: accounts[selectedAddress]?.balance - ? (hexToBN(accounts[selectedAddress].balance) as any)?.isZero?.() - : undefined, - }); - }, - [ - accounts, - dispatch, - navigation, - selectedAddress, - selectedChainId, - trackEvent, - ], - ); + const handleSuccessfulOrder = useHandleSuccessfulOrder(); const renderInAppBrowser = useCallback( async ( @@ -154,7 +100,13 @@ export default function useInAppBrowser() { return; } - handleSuccessfulOrder(order); + const transformedOrder: FiatOrder = { + ...aggregatorOrderToFiatOrder(order), + account: selectedAddress, + network: selectedChainId, + }; + + handleSuccessfulOrder(transformedOrder); } catch (error) { Logger.error(error as Error, { message: diff --git a/app/components/UI/FiatOnRampAggregator/index.tsx b/app/components/UI/FiatOnRampAggregator/index.tsx index c71c2943da3..55a9198ca07 100644 --- a/app/components/UI/FiatOnRampAggregator/index.tsx +++ b/app/components/UI/FiatOnRampAggregator/index.tsx @@ -2,6 +2,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { InteractionManager, StyleSheet, View } from 'react-native'; import React, { useCallback } from 'react'; import WebView from 'react-native-webview'; +import { Order } from '@consensys/on-ramp-sdk'; import AppConstants from '../../../core/AppConstants'; import { MetaMetricsEvents } from '../../../core/Analytics'; @@ -21,15 +22,16 @@ import { removeAuthenticationUrl, } from '../../../reducers/fiatOrders'; import useInterval from '../../hooks/useInterval'; +import useThunkDispatch, { ThunkAction } from '../../hooks/useThunkDispatch'; import processOrder from './orderProcessor'; import processCustomOrderIdData from './orderProcessor/customOrderId'; import { aggregatorOrderToFiatOrder } from './orderProcessor/aggregator'; import { trackEvent } from './hooks/useAnalytics'; -import { Order } from '@consensys/on-ramp-sdk'; import { AnalyticsEvents } from './types'; import { CustomIdData } from '../../../reducers/fiatOrders/types'; import { callbackBaseUrl } from '../FiatOnRampAggregator/sdk'; import useFetchOnRampNetworks from './hooks/useFetchOnRampNetworks'; +import { stateHasOrder } from './utils'; const POLLING_FREQUENCY = AppConstants.FIAT_ORDERS.POLLING_FREQUENCY; const NOTIFICATION_DURATION = 5000; @@ -215,10 +217,12 @@ async function processCustomOrderId( dispatchUpdateFiatCustomIdData, dispatchRemoveFiatCustomIdData, dispatchAddFiatOrder, + dispatchThunk, }: { dispatchUpdateFiatCustomIdData: (updatedCustomIdData: CustomIdData) => void; dispatchRemoveFiatCustomIdData: (customOrderIdData: CustomIdData) => void; dispatchAddFiatOrder: (fiatOrder: FiatOrder) => void; + dispatchThunk: (thunk: ThunkAction) => void; }, ) { const [customOrderId, fiatOrderResponse] = await processCustomOrderIdData( @@ -227,11 +231,17 @@ async function processCustomOrderId( if (fiatOrderResponse) { const fiatOrder = aggregatorOrderToFiatOrder(fiatOrderResponse); - dispatchAddFiatOrder(fiatOrder); - InteractionManager.runAfterInteractions(() => { - NotificationManager.showSimpleNotification( - getNotificationDetails(fiatOrder), - ); + dispatchThunk((_, getState) => { + const state = getState(); + if (stateHasOrder(state, fiatOrder)) { + return; + } + dispatchAddFiatOrder(fiatOrder); + InteractionManager.runAfterInteractions(() => { + NotificationManager.showSimpleNotification( + getNotificationDetails(fiatOrder), + ); + }); }); dispatchRemoveFiatCustomIdData(customOrderIdData); } else if (customOrderId.expired) { @@ -251,6 +261,7 @@ const styles = StyleSheet.create({ function FiatOrders() { useFetchOnRampNetworks(); const dispatch = useDispatch(); + const dispatchThunk = useThunkDispatch(); const pendingOrders = useSelector(getPendingOrders); const customOrderIds = useSelector(getCustomOrderIds); const authenticationUrls = useSelector(getAuthenticationUrls); @@ -293,6 +304,7 @@ function FiatOrders() { dispatchUpdateFiatCustomIdData, dispatchRemoveFiatCustomIdData, dispatchAddFiatOrder, + dispatchThunk, }), ), ); diff --git a/app/components/UI/FiatOnRampAggregator/utils/index.ts b/app/components/UI/FiatOnRampAggregator/utils/index.ts index 84cf8808d7d..917d504bc83 100644 --- a/app/components/UI/FiatOnRampAggregator/utils/index.ts +++ b/app/components/UI/FiatOnRampAggregator/utils/index.ts @@ -1,11 +1,12 @@ import { AggregatorNetwork } from '@consensys/on-ramp-sdk/dist/API'; import { Order } from '@consensys/on-ramp-sdk'; -import { FiatOrder } from '../../../../reducers/fiatOrders'; import { renderFromTokenMinimalUnit, renderNumber, toTokenMinimalUnit, } from '../../../../util/number'; +import { getOrders, FiatOrder } from '../../../../reducers/fiatOrders'; +import { RootState } from '../../../../reducers/fiatOrders/types'; const isOverAnHour = (minutes: number) => minutes > 59; @@ -148,3 +149,8 @@ export function getOrderAmount(order: FiatOrder) { } return amount; } + +export function stateHasOrder(state: RootState, order: FiatOrder) { + const orders = getOrders(state); + return orders.some((o) => o.id === order.id); +} diff --git a/app/components/hooks/useThunkDispatch.ts b/app/components/hooks/useThunkDispatch.ts new file mode 100644 index 00000000000..fec5952ee0d --- /dev/null +++ b/app/components/hooks/useThunkDispatch.ts @@ -0,0 +1,11 @@ +import { useDispatch } from 'react-redux'; +import { store } from '../../store'; +type Dispatch = typeof store.dispatch; +type GetState = typeof store.getState; + +export type ThunkAction = (dispatch: Dispatch, getState: GetState) => void; + +function useThunkDispatch() { + return useDispatch<(thunkAction: ThunkAction) => void>(); +} +export default useThunkDispatch; diff --git a/app/store/index.js b/app/store/index.js index 9ea596c37b1..8c8cc421efd 100644 --- a/app/store/index.js +++ b/app/store/index.js @@ -1,4 +1,5 @@ -import { createStore } from 'redux'; +import { applyMiddleware, createStore } from 'redux'; +import thunk from 'redux-thunk'; import { persistStore, persistReducer, @@ -123,7 +124,7 @@ const persistConfig = { const pReducer = persistReducer(persistConfig, rootReducer); -export const store = createStore(pReducer); +export const store = createStore(pReducer, undefined, applyMiddleware(thunk)); /** * Initialize services after persist is completed diff --git a/package.json b/package.json index 80c2b98b6af..20b864e3db6 100644 --- a/package.json +++ b/package.json @@ -306,6 +306,7 @@ "redux-mock-store": "1.5.4", "redux-persist": "6.0.0", "redux-persist-filesystem-storage": "^3.0.0", + "redux-thunk": "^2.4.2", "reselect": "^4.0.0", "rn-fetch-blob": "^0.12.0", "socket.io-client": "^4.5.3", diff --git a/yarn.lock b/yarn.lock index ffc4913cc2a..ffa2251f6ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21340,6 +21340,11 @@ redux-persist@6.0.0: resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8" integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ== +redux-thunk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b" + integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q== + redux@4.1.1, redux@^4.0.0, redux@^4.0.5: version "4.1.1" resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.1.tgz#76f1c439bb42043f985fbd9bf21990e60bd67f47" From c249e1f3949f4ba517ca23ab0511b67c6ef1b9ed Mon Sep 17 00:00:00 2001 From: Cal Leung Date: Thu, 4 May 2023 11:30:21 -0700 Subject: [PATCH 04/20] Fix missing handler on mandatory modal (#6309) --- .../components/Modals/ModalMandatory/ModalMandatory.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/component-library/components/Modals/ModalMandatory/ModalMandatory.tsx b/app/component-library/components/Modals/ModalMandatory/ModalMandatory.tsx index 3bfb445be03..a0ad536554e 100644 --- a/app/component-library/components/Modals/ModalMandatory/ModalMandatory.tsx +++ b/app/component-library/components/Modals/ModalMandatory/ModalMandatory.tsx @@ -234,7 +234,7 @@ const ModalMandatory = ({ route }: MandatoryModalProps) => { activeOpacity={1} {...generateTestId(Platform, TERMS_OF_USE_CHECKBOX_ICON_ID)} > - + {checkboxText} Date: Thu, 4 May 2023 16:33:24 -0400 Subject: [PATCH 05/20] feature(on-ramp): add development environment to onramp-sdk (#6325) --- .../UI/FiatOnRampAggregator/sdk/index.tsx | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/app/components/UI/FiatOnRampAggregator/sdk/index.tsx b/app/components/UI/FiatOnRampAggregator/sdk/index.tsx index 95cd27bfa87..57eac67260f 100644 --- a/app/components/UI/FiatOnRampAggregator/sdk/index.tsx +++ b/app/components/UI/FiatOnRampAggregator/sdk/index.tsx @@ -33,6 +33,33 @@ import I18n, { I18nEvents } from '../../../../../locales/i18n'; import Device from '../../../../util/device'; import useActivationKeys from '../hooks/useActivationKeys'; +const isDevelopment = process.env.NODE_ENV !== 'production'; +const isInternalBuild = process.env.ONRAMP_INTERNAL_BUILD === 'true'; +const isDevelopmentOrInternalBuild = isDevelopment || isInternalBuild; + +let environment = Environment.Production; +if (isInternalBuild) { + environment = Environment.Staging; +} else if (isDevelopment) { + environment = Environment.Development; +} + +let context = Context.Mobile; +if (Device.isAndroid()) { + context = Context.MobileAndroid; +} else if (Device.isIos()) { + context = Context.MobileIOS; +} + +export const SDK = OnRampSdk.create(environment, context, { + verbose: isDevelopment, + locale: I18n.locale, +}); + +I18nEvents.addListener('localeChanged', (locale) => { + SDK.setLocale(locale); +}); + interface OnRampSDKConfig { POLLING_INTERVAL: number; POLLING_INTERVAL_HIGHLIGHT: number; @@ -74,30 +101,6 @@ interface IProviderProps { children?: React.ReactNode | undefined; } -const isDevelopment = process.env.NODE_ENV !== 'production'; -const isInternalBuild = process.env.ONRAMP_INTERNAL_BUILD === 'true'; -const isDevelopmentOrInternalBuild = isDevelopment || isInternalBuild; - -const CONTEXT = Device.isAndroid() - ? Context.MobileAndroid - : Device.isIos() - ? Context.MobileIOS - : Context.Mobile; -const VERBOSE_SDK = isDevelopment; - -export const SDK = OnRampSdk.create( - isDevelopmentOrInternalBuild ? Environment.Staging : Environment.Production, - CONTEXT, - { - verbose: VERBOSE_SDK, - locale: I18n.locale, - }, -); - -I18nEvents.addListener('localeChanged', (locale) => { - SDK.setLocale(locale); -}); - export const callbackBaseUrl = isDevelopment ? 'https://on-ramp.metaswap-dev.codefi.network/regions/fake-callback' : 'https://on-ramp-content.metaswap.codefi.network/regions/fake-callback'; From 360f8b7018f76d2c2911702e4f34a67c3c4748c4 Mon Sep 17 00:00:00 2001 From: Pedro Pablo Aste Kompen Date: Thu, 4 May 2023 18:24:01 -0400 Subject: [PATCH 06/20] On-ramp: fix missing network name (#6340) --- app/components/UI/FiatOnRampAggregator/Views/AmountToBuy.tsx | 4 +++- locales/languages/en.json | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/components/UI/FiatOnRampAggregator/Views/AmountToBuy.tsx b/app/components/UI/FiatOnRampAggregator/Views/AmountToBuy.tsx index 4bd1abbf398..65152f27ae5 100644 --- a/app/components/UI/FiatOnRampAggregator/Views/AmountToBuy.tsx +++ b/app/components/UI/FiatOnRampAggregator/Views/AmountToBuy.tsx @@ -663,7 +663,9 @@ const AmountToBuy = () => { description={strings( 'fiat_on_ramp_aggregator.no_tokens_available', { - network: NETWORKS_NAMES[selectedChainId], + network: + NETWORKS_NAMES[selectedChainId] || + strings('fiat_on_ramp_aggregator.this_network'), region: selectedRegion?.name, }, )} diff --git a/locales/languages/en.json b/locales/languages/en.json index 6a86ee45a33..c257e403365 100644 --- a/locales/languages/en.json +++ b/locales/languages/en.json @@ -1841,6 +1841,7 @@ "webview_received_error": "WebView received error status code: {{code}}", "no_tokens_available_title": "No Tokens Available", "no_tokens_available": "There are currently no tokens available to purchase on {{network}} with the selected payment method.", + "this_network": "this network", "change_payment_method": "Change payment method", "try_different_region": "Try a different region", "return_home": "Return to Home Screen", From 9c1883978ffb389191826c145cde43c21448fbf5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 May 2023 16:28:34 -0600 Subject: [PATCH 07/20] 6.5.0 (#6241) * 6.5.0 * fix(on-ramp): Add thunk to handle buy crypto deeplink (#6248) * [FIX] Detox: wallet-tests.spec.js (#6250) * fix wallet-tests.spec.js * add collectible json * updated collectible data for bitrise wallet * fix: invalid title error (#6280) * Update Network Badge to use Badge component of component library (#6254) * Show unsupported token for network when watching tokens (#6258) * [FIX] - Upgrading with deprecated test network selected (#6269) * add migrations to handle deprecated networks * use enums, const instead of strings --------- Co-authored-by: CW * [FIX] Patch assets-controller to not use BigInt (#6305) * Patch assets-controller to not use BigInt * Update to use public link Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com> * Update to spell out React Native Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> * Update to spell out React Native Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --------- Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com> Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> * build 1104 (#6310) * update changelog --------- Co-authored-by: metamaskbot Co-authored-by: Pedro Pablo Aste Kompen Co-authored-by: Chris Wilcox Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com> Co-authored-by: tommasini <46944231+tommasini@users.noreply.github.com> Co-authored-by: Cal Leung Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com> Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> Co-authored-by: sethkfman --- CHANGELOG.md | 27 ++ android/app/build.gradle | 4 +- .../Tokens/__snapshots__/index.test.tsx.snap | 364 +++++++++++++++++- app/components/UI/Tokens/index.tsx | 13 +- app/components/UI/WebsiteIcon/index.js | 12 +- app/constants/error.ts | 4 + app/core/DeeplinkManager.js | 16 +- app/core/RPCMethods/RPCMethodMiddleware.ts | 13 +- app/store/index.js | 2 +- app/store/migrations.js | 20 +- bitrise.yml | 4 +- e2e/resources/collectibles.json | 6 + e2e/specs/wallet-tests.spec.js | 22 +- ios/MetaMask.xcodeproj/project.pbxproj | 16 +- package.json | 3 +- .../@metamask+assets-controllers+4.0.0.patch | 38 +- wdio/helpers/Accounts.js | 1 - 17 files changed, 510 insertions(+), 55 deletions(-) create mode 100644 e2e/resources/collectibles.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 639d6fb58a2..3ab51e57c83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,33 @@ ## Current Main Branch +## 6.5.0 - May 4, 2023 +- [#5743](https://github.com/MetaMask/metamask-mobile/pull/5743): [FEATURE] On-ramp: Add buy-crypto deeplink +- [#6201](https://github.com/MetaMask/metamask-mobile/pull/6201): [FIX] [SDK] Missing redirect breaking backward compatibility +- [#6232](https://github.com/MetaMask/metamask-mobile/pull/6232): [FIX] bottom margin for detecting end of the page +- [#6166](https://github.com/MetaMask/metamask-mobile/pull/6166): [FEATURE] trigger walletconnect modal using approval controller +- [#6223](https://github.com/MetaMask/metamask-mobile/pull/6223): [IMPROVEMENT] Update to Node.js v16 +- [#6051](https://github.com/MetaMask/metamask-mobile/pull/6051): [FEATURE] Total balance and portfolio button changed +- [#6156](https://github.com/MetaMask/metamask-mobile/pull/6156): [IMPROVEMENT] On-ramp: Use dynamic list of networks +- [#6145](https://github.com/MetaMask/metamask-mobile/pull/6145): [IMPROVEMENT] Synced and optimized icons +- [#6138](https://github.com/MetaMask/metamask-mobile/pull/6138): [FEATURE] On-ramp: Add orderProcessor exponential backoff for orders +- [#6139](https://github.com/MetaMask/metamask-mobile/pull/6139): [FEATURE] On-ramp: Add same amount rendering as the order details to the order list +- [#6189](https://github.com/MetaMask/metamask-mobile/pull/6189): [FEATURE] On-ramp: Remove hiding the provider modal when quotes refresh +- [#6216](https://github.com/MetaMask/metamask-mobile/pull/6216): [IMPROVEMENT] account icon matches user's preferred identicon +- [#5956](https://github.com/MetaMask/metamask-mobile/pull/5956): [IMPROVEMENT] Show token symbol in verify contract details +- [#5458](https://github.com/MetaMask/metamask-mobile/pull/5458): [IMPROVEMENT] Support sepolia network +- [#6185](https://github.com/MetaMask/metamask-mobile/pull/6185): [FIX] remove pubnub package and associated sync with extension code +- [#6181](https://github.com/MetaMask/metamask-mobile/pull/6181): [IMPROVEMENT] Componentize Header Component +- [#6153](https://github.com/MetaMask/metamask-mobile/pull/6153): [IMPROVEMENT] On-ramp: Refactor order selector by id +- [#6044](https://github.com/MetaMask/metamask-mobile/pull/6044): [IMPROVEMENT] Componentize Badge and Badge Wrapper +- [#6180](https://github.com/MetaMask/metamask-mobile/pull/6180): [IMPROVEMENT] Componentized Overlay Component +- [#6173](https://github.com/MetaMask/metamask-mobile/pull/6173): [REFACTOR] Auto Lock section +- [#6174](https://github.com/MetaMask/metamask-mobile/pull/6174): [IMPROVEMENT] Update Tab bar styles +- [#6056](https://github.com/MetaMask/metamask-mobile/pull/6056): [IMPROVEMENT] Show Identicon for unknown token and if token icon is unknown +- [#6076](https://github.com/MetaMask/metamask-mobile/pull/6076): [BUGFIX] Fixes WalletConnect deep links (wc:// schema) not working properly +- [#6157](https://github.com/MetaMask/metamask-mobile/pull/6157): [REFACTOR] Change Password setting +- [#5718](https://github.com/MetaMask/metamask-mobile/pull/5718): [FIX] Nonce Too Low for Approve Transaction + ## 6.4.0 - Apr 20, 2023 - [#6144](https://github.com/MetaMask/metamask-mobile/pull/6144): [FEATURE] New Crowdin translations by Github Action - [#6143](https://github.com/MetaMask/metamask-mobile/pull/6143): [UPDATE] Crowdin token to use METAMASKBOT_CROWDIN_TOKEN diff --git a/android/app/build.gradle b/android/app/build.gradle index 37c58900775..53af1d1fba4 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -159,8 +159,8 @@ android { applicationId "io.metamask" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1100 - versionName "6.4.0" + versionCode 1104 + versionName "6.5.0" multiDexEnabled true testBuildType System.getProperty('testBuildType', 'debug') missingDimensionStrategy "minReactNative", "minReactNative46" diff --git a/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap b/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap index 669a0db79a9..d7be9f83a92 100644 --- a/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap +++ b/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap @@ -560,7 +560,57 @@ exports[`Tokens should hide zero balance tokens when setting is on 1`] = ` ], } } - /> + > + + + + + + + > + + + + + + + > + + + + + + + > + + + + + + + > + + + + + + + > + + + + + + + > + + + + + + = ({ tokens }) => { const { colors, themeAppearance } = useTheme(); @@ -276,11 +277,13 @@ const Tokens: React.FC = ({ tokens }) => { balance={secondaryBalance} > + } > {asset.isETH ? ( diff --git a/app/components/UI/WebsiteIcon/index.js b/app/components/UI/WebsiteIcon/index.js index cfde080c528..23b594926f3 100644 --- a/app/components/UI/WebsiteIcon/index.js +++ b/app/components/UI/WebsiteIcon/index.js @@ -86,10 +86,14 @@ export default class WebsiteIcon extends PureComponent { const colors = this.context.colors || mockTheme.colors; const styles = createStyles(colors); const apiLogoUrl = { uri: icon || this.getIconUrl(url) }; - const title = - typeof this.props.title === 'string' - ? this.props.title.substr(0, 1) - : getHost(url).substr(0, 1); + let title = this.props.title; + + if (title !== undefined) { + title = + typeof this.props.title === 'string' + ? this.props.title.substr(0, 1) + : getHost(url).substr(0, 1); + } if (renderIconUrlError && title) { return ( diff --git a/app/constants/error.ts b/app/constants/error.ts index 13ecdc02902..f31c53001b5 100644 --- a/app/constants/error.ts +++ b/app/constants/error.ts @@ -48,3 +48,7 @@ export const VAULT_BACKUP_FAILED_UNDEFINED = 'Unable to backup vault as it is undefined'; export const VAULT_FAILED_TO_GET_VAULT_FROM_BACKUP = 'getVaultFromBackup failed to retrieve vault'; + +// RPCMethodMiddleware +export const TOKEN_NOT_SUPPORTED_FOR_NETWORK = + 'This token is not supported on this network'; diff --git a/app/core/DeeplinkManager.js b/app/core/DeeplinkManager.js index ce72cb177ea..5d786c21b06 100644 --- a/app/core/DeeplinkManager.js +++ b/app/core/DeeplinkManager.js @@ -24,7 +24,8 @@ import SDKConnect from '../core/SDKConnect/SDKConnect'; import Routes from '../constants/navigation/Routes'; import Minimizer from 'react-native-minimizer'; import { getAddress } from '../util/address'; -import { allowedToBuy } from '../components/UI/FiatOnRampAggregator'; +import { chainIdSelector, getRampNetworks } from '../reducers/fiatOrders'; +import { isNetworkBuySupported } from '../components/UI/FiatOnRampAggregator/utils'; class DeeplinkManager { constructor({ navigation, frequentRpcList, dispatch, network }) { @@ -188,10 +189,15 @@ class DeeplinkManager { } _handleBuyCrypto() { - // Do nothing for now if use is not in a supported network - if (allowedToBuy(this.network)) { - this.navigation.navigate(Routes.FIAT_ON_RAMP_AGGREGATOR.ID); - } + this.dispatch((_, getState) => { + const state = getState(); + // Do nothing for now if use is not in a supported network + if ( + isNetworkBuySupported(chainIdSelector(state), getRampNetworks(state)) + ) { + this.navigation.navigate(Routes.FIAT_ON_RAMP_AGGREGATOR.ID); + } + }); } parse(url, { browserCallBack, origin, onHandled }) { diff --git a/app/core/RPCMethods/RPCMethodMiddleware.ts b/app/core/RPCMethods/RPCMethodMiddleware.ts index 99aded917e6..f953a124dbc 100644 --- a/app/core/RPCMethods/RPCMethodMiddleware.ts +++ b/app/core/RPCMethods/RPCMethodMiddleware.ts @@ -20,6 +20,8 @@ import setOnboardingWizardStep from '../../actions/wizard'; import { v1 as random } from 'uuid'; import { getPermittedAccounts } from '../Permissions'; import AppConstants from '../AppConstants.js'; +import { isSmartContractAddress } from '../../util/transactions'; +import { TOKEN_NOT_SUPPORTED_FOR_NETWORK } from '../../constants/error'; const Engine = ImportedEngine as any; let appVersion = ''; @@ -617,10 +619,19 @@ export const getRpcMethodMiddleware = ({ type, }, } = req; - const { TokensController } = Engine.context; + const { TokensController, NetworkController } = Engine.context; + const { chainId } = NetworkController.state?.providerConfig || {}; checkTabActive(); try { + // Check if token exists on wallet's active network. + const isTokenOnNetwork = await isSmartContractAddress( + address, + chainId, + ); + if (!isTokenOnNetwork) { + throw new Error(TOKEN_NOT_SUPPORTED_FOR_NETWORK); + } const permittedAccounts = await getPermittedAccounts(hostname); // This should return the current active account on the Dapp. const selectedAddress = diff --git a/app/store/index.js b/app/store/index.js index 8c8cc421efd..91a2e2a433f 100644 --- a/app/store/index.js +++ b/app/store/index.js @@ -1,11 +1,11 @@ import { applyMiddleware, createStore } from 'redux'; -import thunk from 'redux-thunk'; import { persistStore, persistReducer, createMigrate, createTransform, } from 'redux-persist'; +import thunk from 'redux-thunk'; import AsyncStorage from '@react-native-async-storage/async-storage'; import FilesystemStorage from 'redux-persist-filesystem-storage'; import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2'; diff --git a/app/store/migrations.js b/app/store/migrations.js index c7dafc31db0..3c9ff690cb4 100644 --- a/app/store/migrations.js +++ b/app/store/migrations.js @@ -11,6 +11,7 @@ import { DENIED, EXPLORED, } from '../constants/storage'; +import { GOERLI } from '../../app/constants/network'; export const migrations = { // Needed after https://github.com/MetaMask/controllers/pull/152 @@ -63,7 +64,7 @@ export const migrations = { // If the current network does not have a chainId, switch to testnet. state.engine.backgroundState.NetworkController.provider = { ticker: 'ETH', - type: 'goerli', + type: GOERLI, }; } return state; @@ -91,7 +92,7 @@ export const migrations = { // If the current network does not have a chainId, switch to testnet. state.engine.backgroundState.NetworkController.provider = { ticker: 'ETH', - type: 'goerli', + type: GOERLI, chainId: NetworksChainId.goerli, }; } @@ -390,6 +391,19 @@ export const migrations = { return state; }, + 15: (state) => { + const chainId = + state.engine.backgroundState.NetworkController.providerConfig.chainId; + // Deprecate rinkeby, ropsten and Kovan, any user that is on those we fallback to goerli + if (chainId === '4' || chainId === '3' || chainId === '42') { + state.engine.backgroundState.NetworkController.providerConfig = { + chainId: NetworksChainId.goerli, + ticker: 'GoerliETH', + type: GOERLI, + }; + } + return state; + }, }; -export const version = 14; +export const version = 15; diff --git a/bitrise.yml b/bitrise.yml index f0cce505828..d83e174f815 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -620,10 +620,10 @@ app: PROJECT_LOCATION_IOS: ios - opts: is_expand: false - VERSION_NAME: 6.4.0 + VERSION_NAME: 6.5.0 - opts: is_expand: false - VERSION_NUMBER: 1100 + VERSION_NUMBER: 1104 - opts: is_expand: false ANDROID_APK_LINK: '' diff --git a/e2e/resources/collectibles.json b/e2e/resources/collectibles.json new file mode 100644 index 00000000000..cff686786cb --- /dev/null +++ b/e2e/resources/collectibles.json @@ -0,0 +1,6 @@ +{ + "erc1155tokenAddress": "0x306d717D109e0995e0f56027Eb93D9C1d5686dE1", + "erc1155tokenID": "179", + "erc1155collectionName": "Refinable721", + "erc1155tokenName": "Refinable721 #179" +} diff --git a/e2e/specs/wallet-tests.spec.js b/e2e/specs/wallet-tests.spec.js index 720a488461b..f338bdbbde9 100644 --- a/e2e/specs/wallet-tests.spec.js +++ b/e2e/specs/wallet-tests.spec.js @@ -1,20 +1,17 @@ 'use strict'; import TestHelpers from '../helpers'; - import WalletView from '../pages/WalletView'; import AccountListView from '../pages/AccountListView'; import ImportAccountView from '../pages/ImportAccountView'; - import DrawerView from '../pages/Drawer/DrawerView'; - import AddCustomTokenView from '../pages/AddCustomTokenView'; import ImportTokensView from '../pages/ImportTokensView'; - import NetworkListModal from '../pages/modals/NetworkListModal'; import RequestPaymentModal from '../pages/modals/RequestPaymentModal'; import NetworkEducationModal from '../pages/modals/NetworkEducationModal'; import { importWalletWithRecoveryPhrase } from '../viewHelper'; import Accounts from '../../wdio/helpers/Accounts'; +import Collectibles from '../resources/collectibles.json'; describe('Wallet Tests', () => { const GOERLI = 'Goerli Test Network'; @@ -24,9 +21,7 @@ describe('Wallet Tests', () => { // I should NEVER hold any eth or token const TEST_PRIVATE_KEY = 'cbfd798afcfd1fd8ecc48cbecb6dc7e876543395640b758a90e11d986e758ad1'; - const COLLECTIBLE_CONTRACT_ADDRESS = - '0x306d717D109e0995e0f56027Eb93D9C1d5686dE1'; - const COLLECTIBLE_IDENTIFIER = '179'; + const BLT_TOKEN_ADDRESS = '0x107c4504cd79c5d2696ea0030a8dd4e92601b82e'; const validAccount = Accounts.getValidAccount(); @@ -86,6 +81,7 @@ describe('Wallet Tests', () => { await RequestPaymentModal.isPublicAddressCorrect(validAccount.address); await RequestPaymentModal.closeRequestModal(); + await WalletView.isVisible(); }); @@ -124,18 +120,18 @@ describe('Wallet Tests', () => { await WalletView.tapImportNFTButton(); await AddCustomTokenView.isVisible(); - await AddCustomTokenView.typeInNFTAddress(COLLECTIBLE_CONTRACT_ADDRESS); - await AddCustomTokenView.typeInNFTIdentifier(COLLECTIBLE_IDENTIFIER); + await AddCustomTokenView.typeInNFTAddress(Collectibles.erc1155tokenAddress); + await AddCustomTokenView.typeInNFTIdentifier(Collectibles.erc1155tokenID); await WalletView.isVisible(); // Wait for asset to load await TestHelpers.delay(3000); - await WalletView.isNFTVisibleInWallet('Refinable721'); - // Tap on Crypto Kitty - await WalletView.tapOnNFTInWallet('Refinable721'); + await WalletView.isNFTVisibleInWallet(Collectibles.erc1155collectionName); + // Tap on Collectible + await WalletView.tapOnNFTInWallet(Collectibles.erc1155collectionName); - await WalletView.isNFTNameVisible('Refinable721 #179'); + await WalletView.isNFTNameVisible(Collectibles.erc1155tokenName); await WalletView.scrollUpOnNFTsTab(); }); diff --git a/ios/MetaMask.xcodeproj/project.pbxproj b/ios/MetaMask.xcodeproj/project.pbxproj index 9841bdbb271..e9423193bb2 100644 --- a/ios/MetaMask.xcodeproj/project.pbxproj +++ b/ios/MetaMask.xcodeproj/project.pbxproj @@ -1132,7 +1132,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMaskDebug.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1100; + CURRENT_PROJECT_VERSION = 1104; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 48XVW22RCG; @@ -1168,7 +1168,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 6.4.0; + MARKETING_VERSION = 6.5.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "$(inherited)", @@ -1199,7 +1199,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1100; + CURRENT_PROJECT_VERSION = 1104; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 48XVW22RCG; ENABLE_BITCODE = NO; @@ -1235,7 +1235,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 6.4.0; + MARKETING_VERSION = 6.5.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "$(inherited)", @@ -1345,7 +1345,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMaskDebug.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1100; + CURRENT_PROJECT_VERSION = 1104; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 48XVW22RCG; @@ -1381,7 +1381,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 6.4.0; + MARKETING_VERSION = 6.5.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "$(inherited)", @@ -1412,7 +1412,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1100; + CURRENT_PROJECT_VERSION = 1104; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 48XVW22RCG; ENABLE_BITCODE = NO; @@ -1448,7 +1448,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 6.4.0; + MARKETING_VERSION = 6.5.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "$(inherited)", diff --git a/package.json b/package.json index 20b864e3db6..51dd0759c6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask", - "version": "6.4.0", + "version": "6.5.0", "private": true, "scripts": { "audit:ci": "./scripts/yarn-audit.sh", @@ -137,6 +137,7 @@ "@eth-optimism/contracts": "0.0.0-2021919175625", "@ethereumjs/common": "^2.3.1", "@ethereumjs/tx": "^3.2.1", + "@ethersproject/abi": "^5.7.0", "@exodus/react-native-payments": "git+https://github.com/MetaMask/react-native-payments.git#dbc8cbbed570892d2fea5e3d183bf243e062c1e5", "@keystonehq/bc-ur-registry-eth": "^0.7.7", "@keystonehq/metamask-airgapped-keyring": "^0.3.0", diff --git a/patches/@metamask+assets-controllers+4.0.0.patch b/patches/@metamask+assets-controllers+4.0.0.patch index d9917a56783..c0dbfc04147 100644 --- a/patches/@metamask+assets-controllers+4.0.0.patch +++ b/patches/@metamask+assets-controllers+4.0.0.patch @@ -24,10 +24,25 @@ index 332c87d..c110f41 100644 * Enumerate assets assigned to an owner. * diff --git a/node_modules/@metamask/assets-controllers/dist/Standards/ERC20Standard.js b/node_modules/@metamask/assets-controllers/dist/Standards/ERC20Standard.js -index 9ddbc28..acdc28a 100644 +index 9ddbc28..2d12e33 100644 --- a/node_modules/@metamask/assets-controllers/dist/Standards/ERC20Standard.js +++ b/node_modules/@metamask/assets-controllers/dist/Standards/ERC20Standard.js -@@ -57,6 +57,27 @@ class ERC20Standard { +@@ -13,7 +13,13 @@ exports.ERC20Standard = void 0; + const contracts_1 = require("@ethersproject/contracts"); + const metamask_eth_abis_1 = require("@metamask/metamask-eth-abis"); + const ethereumjs_util_1 = require("ethereumjs-util"); +-const abi_utils_1 = require("@metamask/abi-utils"); ++ ++// Revert to use @ethersproject/abi to fix BigInt compatibility issue ++// Issue reported here - https://github.com/MetaMask/metamask-mobile/issues/6307 ++// TODO - Remove patch once app is upgraded to React Native 0.71.6 ++// const abi_utils_1 = require("@metamask/abi-utils"); ++const ethers_project_abi = require('@ethersproject/abi'); ++ + const controller_utils_1 = require("@metamask/controller-utils"); + const utils_1 = require("@metamask/utils"); + const assetsUtil_1 = require("../assetsUtil"); +@@ -57,6 +63,27 @@ class ERC20Standard { } }); } @@ -55,6 +70,25 @@ index 9ddbc28..acdc28a 100644 /** * Query for symbol for a given ERC20 asset. * +@@ -68,10 +95,16 @@ class ERC20Standard { + // Signature for calling `symbol()` + const payload = { to: address, data: '0x95d89b41' }; + const result = yield this.provider.call(payload); +- (0, utils_1.assertIsStrictHexString)(result); ++ ++ // TODO - Remove patch once app is upgraded to RN 0.71.6 ++ // (0, utils_1.assertIsStrictHexString)(result); ++ + // Parse as string - treat empty string as failure + try { +- const decoded = (0, abi_utils_1.decodeSingle)('string', result); ++ // TODO - Remove patch once app is upgraded to React Native 0.71.6 ++ const decoded = ethers_project_abi.abiCoder.decode(['string'], result)[0]; ++ // const decoded = (0, abi_utils_1.decodeSingle)('string', result); ++ + if ((decoded === null || decoded === void 0 ? void 0 : decoded.length) > 0) { + return decoded; + } diff --git a/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.js b/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.js index 4ed4990..da18116 100644 --- a/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.js diff --git a/wdio/helpers/Accounts.js b/wdio/helpers/Accounts.js index c7b072a8027..ffddf1ac6b6 100644 --- a/wdio/helpers/Accounts.js +++ b/wdio/helpers/Accounts.js @@ -3,7 +3,6 @@ const INCORRECT_SECRET_RECOVERY_PHRASE = 'gain lemon refuse sunny identify diesel hand endless first involve wink size'; const CORRECT_PASSWORD = `12345678`; const SHORT_PASSWORD = `1234567`; - const INCORRECT_PASSWORD = `12345679`; class Accounts { From c92c7b5ca865ce5ba153e8af952bdff74e307e92 Mon Sep 17 00:00:00 2001 From: MetaMask Bot <37885440+metamaskbot@users.noreply.github.com> Date: Thu, 4 May 2023 20:52:00 -0230 Subject: [PATCH 08/20] New Crowdin translations by Github Action (#6208) * New Crowdin translations by Github Action * PR update * Revert "PR update" This reverts commit 39e533a5903782494c3b011dbce491adfad509da. --------- Co-authored-by: metamaskbot Co-authored-by: sethkfman --- locales/languages/de.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/el.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/es.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/fr.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/hi.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/id.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/ja.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/ko.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/pt.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/ru.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/tl.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/tr.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/vi.json | 58 +++++++++++++++++++++++++++++++++++++-- locales/languages/zh.json | 58 +++++++++++++++++++++++++++++++++++++-- 14 files changed, 784 insertions(+), 28 deletions(-) diff --git a/locales/languages/de.json b/locales/languages/de.json index 3976bcec3e4..a63a3f79fa8 100644 --- a/locales/languages/de.json +++ b/locales/languages/de.json @@ -108,6 +108,37 @@ "content": "Suchen Sie nach Seiten oder geben Sie eine URL ein, wenn Sie wissen, wohin sie wollen." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Erstellen Ihres Wallets ...", "subtitle": "Das sollte nicht lang dauern" @@ -800,7 +831,30 @@ "buy_description": "Krypto mit Bargeld kaufen", "swap_description": "Zwischen Tokens tauschen", "send_description": "Krypto an ein beliebiges Konto senden", - "receive_description": "Krypto erhalten" + "receive_description": "Krypto erhalten", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Kontodetails", @@ -1222,7 +1276,6 @@ "add_other_network_here": "hier entdecken.", "you_can": "Sie können aber auch", "add_network": "weitere Netzwerke manuell hinzufügen.", - "deprecated_network_msg": "Aufgrund der Protokolländerungen von Ethereum: Rinkeby, Ropsten, Kovan funktionieren die Testnetzwerke möglicherweise nicht mehr so zuverlässig und werden bald veraltet sein.", "select_network": "Netzwerk wählen" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView erhielt Fehler-Statuscode: {{code}}", "no_tokens_available_title": "Keine Token verfügbar", "no_tokens_available": "Derzeit gibt es keine Kryptowährungen, die in {{network}} in der {{region}} gekauft werden können.", + "this_network": "this network", "change_payment_method": "Zahlungsmethode ändern", "try_different_region": "Andere Region ausprobieren", "return_home": "Zur Startseite zurückkehren", diff --git a/locales/languages/el.json b/locales/languages/el.json index 653d45f41e5..e39461b364c 100644 --- a/locales/languages/el.json +++ b/locales/languages/el.json @@ -108,6 +108,37 @@ "content": "Ψάξτε για ιστοσελίδες ή πληκτρολογήστε ένα URL εάν γνωρίζετε τον προορισμό σας." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Δημιουργούμε το πορτοφόλι σας...", "subtitle": "Δεν θα πάρει πολύ" @@ -800,7 +831,30 @@ "buy_description": "Αγοράστε κρυπτονομίσματα με μετρητά", "swap_description": "Ανταλλαγή μεταξύ tokens", "send_description": "Στείλτε κρυπτονομίσματα σε οποιονδήποτε λογαριασμό", - "receive_description": "Λάβετε κρυπτονομίσματα" + "receive_description": "Λάβετε κρυπτονομίσματα", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Λεπτομέρειες Λογαριασμού", @@ -1222,7 +1276,6 @@ "add_other_network_here": "εδώ.", "you_can": "Ή μπορείτε", "add_network": "να προσθέσετε περισσότερα δίκτυα χειροκίνητα.", - "deprecated_network_msg": "Λόγω των αλλαγών στο πρωτόκολλο του Ethereum: τα δοκιμαστικά δίκτυα Rinkeby, Ropsten, Kovan μπορεί να μη λειτουργούν και τόσο αξιόπιστα και θα καταργηθούν σύντομα.", "select_network": "Επιλέξτε ένα δίκτυο" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "Το WebView έλαβε έναν κωδικό κατάστασης σφάλματος: {{code}}", "no_tokens_available_title": "Κανένα διαθέσιμο Token", "no_tokens_available": "Δεν υπάρχουν προς το παρόν διαθέσιμα token για αγορά στο {{network}} με την επιλεγμένη μέθοδο πληρωμής.", + "this_network": "this network", "change_payment_method": "Αλλάξτε μέθοδο πληρωμής", "try_different_region": "Δοκιμάστε μια άλλη περιοχή", "return_home": "Επιστροφή στην Αρχική Σελίδα", diff --git a/locales/languages/es.json b/locales/languages/es.json index ba643aac79b..e9b10bd9378 100644 --- a/locales/languages/es.json +++ b/locales/languages/es.json @@ -108,6 +108,37 @@ "content": "Busque los sitios o escriba una dirección URL si sabe adónde va." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Creando su cartera…", "subtitle": "Este proceso no debería tardar mucho" @@ -800,7 +831,30 @@ "buy_description": "Comprar criptomonedas con efectivo", "swap_description": "Intercambiar entre tokens", "send_description": "Enviar criptomonedas a cualquier cuenta", - "receive_description": "Recibir criptomonedas" + "receive_description": "Recibir criptomonedas", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Detalles de la cuenta", @@ -1222,7 +1276,6 @@ "add_other_network_here": "aquí.", "you_can": "O puede", "add_network": "agregar más redes manualmente.", - "deprecated_network_msg": "Debido a los cambios de protocolo de Ethereum: es posible que las redes de prueba de Rinkeby, Ropsten y Kovan no funcionen de manera tan confiable y queden obsoletas pronto.", "select_network": "Seleccionar una red" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView recibió un código de estado de error: {{code}}", "no_tokens_available_title": "No hay tokens disponibles", "no_tokens_available": "En este momento no hay tokens disponibles para comprar en {{network}} con el método de pago seleccionado.", + "this_network": "this network", "change_payment_method": "Cambiar el método de pago", "try_different_region": "Pruebe una región distinta", "return_home": "Volver a la pantalla de inicio", diff --git a/locales/languages/fr.json b/locales/languages/fr.json index b38fad43b03..9015a658a83 100644 --- a/locales/languages/fr.json +++ b/locales/languages/fr.json @@ -108,6 +108,37 @@ "content": "Recherchez des sites, ou saisissez une URL si vous connaissez l’adresse." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Création de votre portefeuille…", "subtitle": "Cela ne devrait prendre que quelques instants." @@ -800,7 +831,30 @@ "buy_description": "Acheter des crypto-actifs en payant en espèces", "swap_description": "Échange de jetons", "send_description": "Envoyer des crypto-actifs vers n’importe quel compte", - "receive_description": "Recevoir des crypto-actifs" + "receive_description": "Recevoir des crypto-actifs", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Détails du compte", @@ -1222,7 +1276,6 @@ "add_other_network_here": "ici.", "you_can": "Ou vous pouvez", "add_network": "ajouter manuellement d’autres réseaux.", - "deprecated_network_msg": "En raison des changements apportés au protocole d’Ethereum, les réseaux testnet Rinkeby, Ropsten et Kovan peuvent ne pas fonctionner d’une manière aussi fiable qu’auparavant et deviendront bientôt obsolètes.", "select_network": "Sélectionner un réseau" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView a reçu le code d’erreur : {{code}}", "no_tokens_available_title": "Aucun jeton disponible", "no_tokens_available": "Il n'y a actuellement aucun jeton que vous pouvez acheter sur {{network}} en utilisant le moyen de paiement sélectionné.", + "this_network": "this network", "change_payment_method": "Changer de mode de paiement", "try_different_region": "Essayez une autre région", "return_home": "Retour à l’écran d’accueil", diff --git a/locales/languages/hi.json b/locales/languages/hi.json index 4a8f1d9eb93..9b287b2b77f 100644 --- a/locales/languages/hi.json +++ b/locales/languages/hi.json @@ -108,6 +108,37 @@ "content": "अगर आप जानते हैं कि आप कहां जा रहे हैं, साइट को खोजें, या कोई URL टाइप करें।" } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "आपका वॉलेट बनाया जा रहा है...", "subtitle": "इसमें ज्यादा समय नहीं लगना चाहिए" @@ -800,7 +831,30 @@ "buy_description": "नकद के साथ क्रिप्टो खरीदें", "swap_description": "टोकन के बीच विनिमय", "send_description": "किसी भी खाते में क्रिप्टो भेजें", - "receive_description": "क्रिप्टो प्राप्त करें" + "receive_description": "क्रिप्टो प्राप्त करें", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "अकाउंट का विवरण", @@ -1222,7 +1276,6 @@ "add_other_network_here": "यहां।", "you_can": "या आप", "add_network": "मैन्युअल रूप से अधिक नेटवर्क जोड़ें।", - "deprecated_network_msg": "Ethereum प्रोटोकॉल परिवर्तनों के कारण: Rinkeby, Ropsten, Kovan टेस्ट नेटवर्क मज़बूती से काम करने में असमर्थ हो सकते हैं और जल्द ही अप्रचलित हो जाएंगे।", "select_network": "एक नेटवर्क चुनें" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView को त्रुटि का स्टेटस कोड प्राप्त हुआ: {{code}}", "no_tokens_available_title": "कोई टोकन उपलब्ध नहीं है", "no_tokens_available": "चयनित भुगतान विधि के साथ {{network}} पर खरीदने के लिए फिलहाल कोई टोकन उपलब्ध नहीं हैं।", + "this_network": "this network", "change_payment_method": "भुगतान का तरीका बदलें", "try_different_region": "कोई दूसरा क्षेत्र आज़माएं", "return_home": "होम स्क्रीन पर लौटें", diff --git a/locales/languages/id.json b/locales/languages/id.json index 5d4ec70976b..e8e6605af7d 100644 --- a/locales/languages/id.json +++ b/locales/languages/id.json @@ -108,6 +108,37 @@ "content": "Telusuri situs, atau ketikkan URL jika Anda mengetahui tujuan Anda." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Membuat dompet Anda...", "subtitle": "Tidak perlu menunggu lama" @@ -800,7 +831,30 @@ "buy_description": "Beli kripto dengan uang tunai", "swap_description": "Pertukaran antar token", "send_description": "Kirim kripto ke akun mana pun", - "receive_description": "Terima kripto" + "receive_description": "Terima kripto", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Detail Akun", @@ -1222,7 +1276,6 @@ "add_other_network_here": "di sini.", "you_can": "Atau Anda dapat", "add_network": "menambahkan lebih banyak jaringan secara manual.", - "deprecated_network_msg": "Sehubungan dengan perubahan protokol Ethereum: jaringan uji Rinkeby, Ropsten, Kovan mungkin tidak dapat beroperasi dengan baik dan akan segera dihentikan.", "select_network": "Pilih jaringan" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView menerima kode status galat: {{code}}", "no_tokens_available_title": "Token Tidak Tersedia", "no_tokens_available": "Saat ini tidak ada token yang tersedia untuk dibeli di {{network}} dengan metode pembayaran yang dipilih.", + "this_network": "this network", "change_payment_method": "Ubah metode pembayaran", "try_different_region": "Coba wilayah lain", "return_home": "Kembali ke Layar Beranda", diff --git a/locales/languages/ja.json b/locales/languages/ja.json index d4c4842e59e..a23127bbf42 100644 --- a/locales/languages/ja.json +++ b/locales/languages/ja.json @@ -108,6 +108,37 @@ "content": "サイトを検索するか、アクセス先がわかっている場合はURLを入力します。" } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "ウォレットを作成中...", "subtitle": "少しだけお待ちください" @@ -800,7 +831,30 @@ "buy_description": "現金で仮想通貨を購入します", "swap_description": "トークン同士を交換します", "send_description": "仮想通貨を任意のアカウントに送金します", - "receive_description": "仮想通貨を受け取ります" + "receive_description": "仮想通貨を受け取ります", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "アカウント詳細", @@ -1222,7 +1276,6 @@ "add_other_network_here": "こちらから検出できます。", "you_can": "または", "add_network": "他のネットワークを手動で追加できます。", - "deprecated_network_msg": "Ethereum のプロトコル変更のため: Rinkeby、Ropsten、Kovan テストネットワークは動作が安定しない可能性があり、近いうちに非推奨になります。", "select_network": "ネットワークを選択" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView がエラーステータスコード {{code}} を受信しました", "no_tokens_available_title": "利用可能なトークンがありません", "no_tokens_available": "現在{{network}}に選択した支払方法で購入可能なトークンがありません。", + "this_network": "this network", "change_payment_method": "支払方法を変更", "try_different_region": "他の地域を試す", "return_home": "ホーム画面に戻る", diff --git a/locales/languages/ko.json b/locales/languages/ko.json index d2bf1697365..44b689372f2 100644 --- a/locales/languages/ko.json +++ b/locales/languages/ko.json @@ -108,6 +108,37 @@ "content": "사이트를 검색하거나 URL을 입력하세요." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "지갑 생성 중...", "subtitle": "오래 걸리지 않을 것입니다" @@ -800,7 +831,30 @@ "buy_description": "현금으로 암호화폐 구입", "swap_description": "토큰 간 교환", "send_description": "원하는 계정에 암호화폐 보내기", - "receive_description": "암호화폐 수령" + "receive_description": "암호화폐 수령", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "계정 상세 내역", @@ -1222,7 +1276,6 @@ "add_other_network_here": "여기에서 확인하세요.", "you_can": "또는 다음을 확인하세요:", "add_network": "네트워크를 직접 추가할 수도 있습니다.", - "deprecated_network_msg": "이더리움 프로토콜 변경으로 인해 Rinkeby, Ropsten, Kovan 테스트 네트워크가 안정적으로 작동하지 않을 수 있습니다. 해당 네트워크는 곧 사용이 중단될 예정입니다.", "select_network": "네트워크 선택" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView 수신 오류 코드: {{code}}", "no_tokens_available_title": "사용 가능한 토큰 없음", "no_tokens_available": "현재 {{network}}에서 선택한 결제 방식으로 구매할 수 있는 토큰이 없습니다.", + "this_network": "this network", "change_payment_method": "결제 방법 변경", "try_different_region": "다른 지역을 시도하세요", "return_home": "홈 화면으로 돌아가기", diff --git a/locales/languages/pt.json b/locales/languages/pt.json index c21db3fb14c..362ba92dc75 100644 --- a/locales/languages/pt.json +++ b/locales/languages/pt.json @@ -108,6 +108,37 @@ "content": "Pesquise por sites ou digite um URL caso saiba para onde quer ir." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Criando sua carteira...", "subtitle": "Não deve demorar muito" @@ -800,7 +831,30 @@ "buy_description": "Compre criptomoedas com dinheiro", "swap_description": "Faça câmbio entre tokens", "send_description": "Envie criptomoedas para qualquer conta", - "receive_description": "Receba criptomoedas" + "receive_description": "Receba criptomoedas", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Detalhes da conta", @@ -1222,7 +1276,6 @@ "add_other_network_here": "aqui.", "you_can": "Ou você pode", "add_network": "adicionar mais redes manualmente.", - "deprecated_network_msg": "Devido às mudanças de protocolo do Ethereum, as redes de teste Rinkeby, Ropsten e Kovan podem não funcionar com a mesma confiança e serão descontinuadas em breve.", "select_network": "Selecione uma rede" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "O WebView recebeu o código de status de erro: {{code}}", "no_tokens_available_title": "Nenhum token disponível", "no_tokens_available": "No momento, não há tokens disponíveis para compra em {{network}} com a forma de pagamento selecionada.", + "this_network": "this network", "change_payment_method": "Alterar método de pagamento", "try_different_region": "Tente uma região diferente", "return_home": "Voltar à tela inicial", diff --git a/locales/languages/ru.json b/locales/languages/ru.json index 68b01963476..4a239f941ef 100644 --- a/locales/languages/ru.json +++ b/locales/languages/ru.json @@ -108,6 +108,37 @@ "content": "Найдите сайты или введите URL-адрес, если знаете, куда направляетесь." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Создание кошелька...", "subtitle": "Это не займет много времени" @@ -800,7 +831,30 @@ "buy_description": "Покупайте криптовалюту за наличные", "swap_description": "Обменивайте одни токены на другие", "send_description": "Отправляйте криптовалюту на любой счет", - "receive_description": "Получайте криптовалюту" + "receive_description": "Получайте криптовалюту", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Реквизиты счета", @@ -1222,7 +1276,6 @@ "add_other_network_here": "здесь.", "you_can": "Или вы можете", "add_network": "добавить другие сети вручную.", - "deprecated_network_msg": "Из-за изменений протокола Ethereum: тестовые сети Rinkeby, Ropsten, Kovan могут работать не так надежно и скоро будут признаны устаревшими.", "select_network": "Выбрать сеть" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView получил код состояния ошибки: {{code}}", "no_tokens_available_title": "Нет доступных токенов", "no_tokens_available": "В настоящее время нет токенов, доступных для покупки в {{network}} в {{region}}", + "this_network": "this network", "change_payment_method": "Изменить способ оплаты", "try_different_region": "Попробуйте другой регион", "return_home": "Назад на главный экран", diff --git a/locales/languages/tl.json b/locales/languages/tl.json index 5b26324e588..bc8baba6d73 100644 --- a/locales/languages/tl.json +++ b/locales/languages/tl.json @@ -108,6 +108,37 @@ "content": "Maghanap ng site o mag-type ng URL kung alam mo kung saan ka pupunta." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Ginagawa ang iyong wallet...", "subtitle": "Hindi ito aabutin nang matagal" @@ -800,7 +831,30 @@ "buy_description": "Bumili ng crypto gamit ang cash", "swap_description": "Palitan sa pagitan ng mga token", "send_description": "Magpadala ng crypto sa anumang account", - "receive_description": "Tumanggap ng crypto" + "receive_description": "Tumanggap ng crypto", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Mga Detalye ng Account", @@ -1222,7 +1276,6 @@ "add_other_network_here": "dito.", "you_can": "O maaari kang", "add_network": "magdagdag pa ng mga network nang manu-mano.", - "deprecated_network_msg": "Dahil sa mga pagbabago ng protokol ng Ethereum: ang mga test network na Rinkeby, Ropsten, at Kovan ay maaaring hindi gumana tulad ng maaasahan at malapit nang itigil ang paggamit.", "select_network": "Pumili ng network" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "Ang WebView ay nakatanggap ng error status code: {{code}}", "no_tokens_available_title": "Walang Available na Token", "no_tokens_available": "Kasalukuyang walang mga token na available upang bilhin sa {{network}} gamit ang napiling paraan ng pagbabayad.", + "this_network": "this network", "change_payment_method": "Baguhin ang paraan ng pagbabayad", "try_different_region": "Subukan ang ibang rehiyon", "return_home": "Bumalik sa Home Screen", diff --git a/locales/languages/tr.json b/locales/languages/tr.json index 4e41217bfe3..346e9764bfd 100644 --- a/locales/languages/tr.json +++ b/locales/languages/tr.json @@ -108,6 +108,37 @@ "content": "Siteleri arayabilir veya nereye yönlendirildiğinizi biliyorsanız bir URL adresi girebilirsiniz." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Cüzdanınız oluşturuluyor...", "subtitle": "Bu işlem uzun sürmeyecektir" @@ -800,7 +831,30 @@ "buy_description": "Nakit ile kripto satın alın", "swap_description": "Tokenler arasında takas yapın", "send_description": "Dilediğin hesaba kripto gönderin", - "receive_description": "Kripto alın" + "receive_description": "Kripto alın", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Hesap Bilgileri", @@ -1222,7 +1276,6 @@ "add_other_network_here": "Burada daha fazla ağ keşfedebilirsiniz.", "you_can": "Veya", "add_network": "manuel olarak daha fazla ekleyebilirsiniz.", - "deprecated_network_msg": "Ethereum'da yaşanan protokol değişikliklerinden dolayı: Rinkeby, Ropsten, Kovan test ağları güvenilir bir şekilde çalışmayabilir ve yakında kullanım dışı olacak.", "select_network": "Bir ağ seçin" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView şu hata durum kodunu aldı: {{code}}", "no_tokens_available_title": "Token Yok", "no_tokens_available": "Şu anda {{network}} üzerinde seçili ödeme yöntemi ile mevcut token bulunmamaktadır.", + "this_network": "this network", "change_payment_method": "Ödeme yöntemini değiştir", "try_different_region": "Farklı bir bölge deneyin", "return_home": "Ana Ekrana Geri Dön", diff --git a/locales/languages/vi.json b/locales/languages/vi.json index 3031b060875..4423a62163a 100644 --- a/locales/languages/vi.json +++ b/locales/languages/vi.json @@ -108,6 +108,37 @@ "content": "Tìm kiếm trang web hoặc gõ địa chỉ URL nếu bạn biết trang web bạn muốn đến." } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "Đang tạo ví của bạn...", "subtitle": "Sẽ không tốn nhiều thời gian" @@ -800,7 +831,30 @@ "buy_description": "Mua tiền mã hóa bằng tiền", "swap_description": "Chuyển đổi giữa các token", "send_description": "Gửi tiền mã hóa đến bất kỳ tài khoản nào", - "receive_description": "Nhận tiền mã hóa" + "receive_description": "Nhận tiền mã hóa", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "Chi tiết tài khoản", @@ -1222,7 +1276,6 @@ "add_other_network_here": "tại đây.", "you_can": "Hoặc bạn có thể", "add_network": "thêm thủ công các mạng khác.", - "deprecated_network_msg": "Do những thay đổi trong giao thức của Ethereum: các mạng thử nghiệm Rinkeby, Ropsten, Kovan có thể không hoạt động đáng tin cậy và sẽ sớm bị ngừng sử dụng.", "select_network": "Chọn mạng" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView đã nhận được mã trạng thái lỗi: {{code}}", "no_tokens_available_title": "Hiện không có token nào", "no_tokens_available": "Hiện không có token nào để mua trên {{network}} bằng phương thức thanh toán đã chọn.", + "this_network": "this network", "change_payment_method": "Thay đổi phương thức thanh toán", "try_different_region": "Hãy thử một khu vực khác", "return_home": "Quay lại Màn hình chính", diff --git a/locales/languages/zh.json b/locales/languages/zh.json index 443d5f392cd..4fc905998a4 100644 --- a/locales/languages/zh.json +++ b/locales/languages/zh.json @@ -108,6 +108,37 @@ "content": "搜索站点;如果您知道要前往的目的地,键入 URL。" } }, + "onboarding_wizard_new": { + "coachmark": { + "action_back": "No thanks", + "action_next": "Take the tour", + "progress_next": "Got it" + }, + "step1": { + "title": "Welcome to your wallet!", + "content1": "On the blockchain, you need a wallet (and maybe some ETH). So let’s take a look at how to use your MetaMask wallet." + }, + "step2": { + "title": "Your accounts", + "content1": "This is your account and unique public address (0x...). Create more accounts by tapping the arrow icon." + }, + "step3": { + "title": "Managing your account", + "content1": "Edit your account name, view transactions on Etherscan, share your public key, and see your private key by tapping this icon" + }, + "step4": { + "title": "Using your wallet", + "content1": "Buy, send, swap, and receive assets by tapping this icon" + }, + "step5": { + "title": "Exploring web3", + "content1": "Open the browser by tapping this icon" + }, + "step6": { + "title": "Using the browser", + "content1": "Search for sites by keyword or enter a URL. Have fun out there! " + } + }, "create_wallet": { "title": "正在创建您的钱包...", "subtitle": "这应该不需要很长时间" @@ -800,7 +831,30 @@ "buy_description": "用现金购买加密货币", "swap_description": "代币之间的兑换", "send_description": "向任何账户发送加密货币", - "receive_description": "接收加密货币" + "receive_description": "接收加密货币", + "chart_time_period": { + "1d": "Today", + "7d": "Past 7 days", + "1w": "Past week", + "1m": "Past month", + "3m": "Past 3 months", + "1y": "Past year", + "3y": "Past 3 years" + }, + "chart_time_period_navigation": { + "1d": "1D", + "7d": "7D", + "1w": "1W", + "1m": "1M", + "3m": "3M", + "1y": "1Y", + "3y": "3Y" + }, + "your_balance": "Your balance", + "unable_to_load_balance": "Unable to load your balance", + "about": "About", + "activity": "{{symbol}} activity", + "disclaimer": "Market data is provided by one or more third-party data sources, including CoinGecko. Such third-party content is provided solely for informational purposes and should not be treated as advice to buy, sell, or use any particular asset. MetaMask does not suggest the use of this content for any particular purpose and is not responsible for its accuracy." }, "account_details": { "title": "账户详细信息", @@ -1222,7 +1276,6 @@ "add_other_network_here": "这里。", "you_can": "或者您可以", "add_network": "手动添加更多网络。", - "deprecated_network_msg": "由于以太坊的协议有变化:Rinkeby、Ropsten、Kovan测试网络可能无法可靠地工作,很快就会被弃用。", "select_network": "选择网络" }, "select": { @@ -1788,6 +1841,7 @@ "webview_received_error": "WebView收到错误状态代码:{{code}}", "no_tokens_available_title": "无可用代币", "no_tokens_available": "当前{{network}}上没有可用的代币,无法使用所选支付方式购买。", + "this_network": "this network", "change_payment_method": "更改付款方式", "try_different_region": "请尝试其他区域", "return_home": "返回主屏幕", From 33bb4fcac627e78d61c48af9b5cef67c8fb38506 Mon Sep 17 00:00:00 2001 From: yande <110056475+Andepande@users.noreply.github.com> Date: Fri, 5 May 2023 00:22:38 +0100 Subject: [PATCH 09/20] Stabilise E2e Android tests on pipeline (#6341) * Modify actions bar function and small tidy ups * Commit working Smoke tests * Small changes to tests * Small fixes * hide Keyboard * Fiz sendtoken browserStack * fix sendToken and CreateWalletAccount * add smoke tag to lockreset * wait for no thanks button to exists * increase wait time for term of use modal. * fix wallet displayed step * add time interval to waitFor on no thanks button * add time interval for waitForDisplayed * Add check for terms of use modal loading delay * Update common-steps.js Alter CreateWalletTest to also wait for terms of use text * Add double tap * update tags --------- Co-authored-by: Curtis --- .../Accounts/CreatingWalletAccount.feature | 3 +- .../Accounts/ImportingAccount.feature | 2 +- ...portedAccountAfterConnectingToDapp.feature | 7 +- .../BrowserFlow/RevokingSingleAccount.feature | 4 +- .../Onboarding/CreateNewWallet.feature | 6 +- wdio/features/Onboarding/ImportWallet.feature | 44 ++++++++-- .../Onboarding/ImportWalletRegression.feature | 53 ------------ .../Onboarding/OnboardingCarousel.feature | 10 +-- wdio/features/Onboarding/TermsOfUse.feature | 8 +- .../SecurityAndPrivacy/DeleteWallet.feature | 2 +- wdio/features/Wallet/ExploringWizard.feature | 38 ++++----- .../features/Wallet/ImportCustomToken.feature | 1 - wdio/features/Wallet/LockResetWallet.feature | 4 +- wdio/features/Wallet/SendToken.feature | 83 ++++++++----------- wdio/helpers/Selectors.js | 2 +- wdio/screen-objects/AccountListComponent.js | 2 +- wdio/screen-objects/CommonScreen.js | 10 +++ .../EnableSecurityChecksScreen.js | 2 + wdio/screen-objects/Modals/TabBarModal.js | 4 +- wdio/screen-objects/Modals/TermOfUseScreen.js | 15 ++++ .../Onboarding/OnboardingCarousel.js | 9 +- wdio/screen-objects/TokenOverviewScreen.js | 4 +- wdio/screen-objects/WalletMainScreen.js | 20 ++--- wdio/step-definitions/common-steps.js | 24 ++++-- .../create-new-wallet-account.steps.js | 3 +- .../import-wallet-via-private-key.steps.js | 1 + wdio/step-definitions/onboarding.steps.js | 8 +- wdio/step-definitions/send-flow.steps.js | 6 ++ wdio/step-definitions/wallet-view.steps.js | 1 + 29 files changed, 196 insertions(+), 180 deletions(-) delete mode 100644 wdio/features/Onboarding/ImportWalletRegression.feature diff --git a/wdio/features/Accounts/CreatingWalletAccount.feature b/wdio/features/Accounts/CreatingWalletAccount.feature index fbf7ac543f6..262ce5c847e 100644 --- a/wdio/features/Accounts/CreatingWalletAccount.feature +++ b/wdio/features/Accounts/CreatingWalletAccount.feature @@ -14,5 +14,4 @@ Feature: Creating account in wallet When I tap on the Identicon Then the account list should be visible When I tap on Create a new account - Then A new account is created - And I am on the new account + Then I am on the new account diff --git a/wdio/features/Accounts/ImportingAccount.feature b/wdio/features/Accounts/ImportingAccount.feature index 5ddbdb40ab6..14957c4f29b 100644 --- a/wdio/features/Accounts/ImportingAccount.feature +++ b/wdio/features/Accounts/ImportingAccount.feature @@ -1,5 +1,5 @@ @androidApp -@smoke +@regression Feature: Importing account in wallet Scenario: Import wallet diff --git a/wdio/features/BrowserFlow/RemovingImportedAccountAfterConnectingToDapp.feature b/wdio/features/BrowserFlow/RemovingImportedAccountAfterConnectingToDapp.feature index fadaa6174e6..1c342c46633 100644 --- a/wdio/features/BrowserFlow/RemovingImportedAccountAfterConnectingToDapp.feature +++ b/wdio/features/BrowserFlow/RemovingImportedAccountAfterConnectingToDapp.feature @@ -1,5 +1,6 @@ -@androidApp -@regression +@androidApp +@smoke + Feature: Importing account via private then revoking permissions Scenario: Import wallet @@ -11,7 +12,7 @@ Feature: Importing account via private then revoking permissions Scenario: User grants permission to a sushiswap to access one of their accounts When I navigate to the browser - # When I tap on button with text "Wallet" + # When I tap on button with text "Wallet" And I navigate to "https://app.sushi.com/swap" Then the connect modal should be displayed And I connect my active wallet to the dapp diff --git a/wdio/features/BrowserFlow/RevokingSingleAccount.feature b/wdio/features/BrowserFlow/RevokingSingleAccount.feature index 0589a7ca10b..3db0e9163ad 100644 --- a/wdio/features/BrowserFlow/RevokingSingleAccount.feature +++ b/wdio/features/BrowserFlow/RevokingSingleAccount.feature @@ -1,6 +1,6 @@ -@androidApp +@androidApp @regression -Feature: Permission system in MetaMask Mobile +Feature: Revoking access to a dapp while connected to one account. Scenario: Import wallet Given the app displayed the splash animation diff --git a/wdio/features/Onboarding/CreateNewWallet.feature b/wdio/features/Onboarding/CreateNewWallet.feature index 4cf9cf0ffa3..f7469c6df39 100644 --- a/wdio/features/Onboarding/CreateNewWallet.feature +++ b/wdio/features/Onboarding/CreateNewWallet.feature @@ -1,12 +1,12 @@ @androidApp -@smoke +@regression Feature: New wallet flow Scenario: Onboarding New walllet - User opens the app for first time and creates a new wallet. + User opens the app for first time and creates a new wallet. Given the Welcome Screen is displayed When I tap "Get started" - Then "Wallet setup" is displayed + Then Wallet setup screen is displayed When On Wallet Setup Screen I tap "Create a new wallet" And On Wallet Setup Screen I tap "Agree" And Terms of Use is displayed diff --git a/wdio/features/Onboarding/ImportWallet.feature b/wdio/features/Onboarding/ImportWallet.feature index 9e0ccf5b2ca..7e45e487685 100644 --- a/wdio/features/Onboarding/ImportWallet.feature +++ b/wdio/features/Onboarding/ImportWallet.feature @@ -1,14 +1,12 @@ @androidApp -@smoke +@regression Feature: Import Wallet - Users can use the app to import an existing wallet or create a new one. + Users can use the app to import an existing wallet or create a new one. - Scenario Outline: Import Wallet - Manual input SR - After a user completes the onboarding process then they are presented - with the option to create a new wallet and back it up. + Scenario: Get Started Given the Welcome Screen is displayed When I tap "Get started" - Then "Wallet setup" is displayed + Then Wallet setup screen is displayed When I tap "Import using Secret Recovery Phrase" Then "Help us improve MetaMask" is displayed When I tap "I agree" @@ -16,12 +14,40 @@ Feature: Import Wallet And I agree to terms And Terms of Use is not displayed Then "Import from seed" is displayed + + Scenario Outline: Password Strength + When I type in new password field + Then password strength is displayed + Examples: + | password | strength | + | metapass1 | Password strength: Weak | + | Metapass12345 | Password strength: Good | + | Metapass12345!@ | Password strength: Strong | + + Scenario Outline: Password Matching + When I type in confirm password field + Then green check mark is displayed + Examples: + | password | + | Metapass12345!@ | + + Scenario Outline: Invalid SRP + When I type in SRP field + And I tap "Import" + Then device alert is displayed + And I tap Yes on alert + + Examples: + | invalid_SRP | error | + | fold media south not valid secret recovery phrase pause cloth just raven | Invalid Secret Recovery Phrase | + | fold media south add since false relax immense pause cloth just | Secret Recovery Phrases contain 12, 15, 18, 21, or 24 words | + + Scenario Outline: Import Wallet When I type in SRP field - And I type in new password field And I type in confirm password field And I tap "Import" And I tap No Thanks on the Enable security check screen Then "Welcome to your new wallet!" is displayed Examples: - | SRP | password | - | fold media south add since false relax immense pause cloth just raven | metapass1 | + | SRP | password | + | fold media south add since false relax immense pause cloth just raven | Metapass12345!@ | diff --git a/wdio/features/Onboarding/ImportWalletRegression.feature b/wdio/features/Onboarding/ImportWalletRegression.feature deleted file mode 100644 index 2bc04fa60ee..00000000000 --- a/wdio/features/Onboarding/ImportWalletRegression.feature +++ /dev/null @@ -1,53 +0,0 @@ -@androidApp -@regression -Feature: Import Wallet Regression - Users can use the app to import an existing wallet or create a new one. - - Scenario: Get Started - Given the Welcome Screen is displayed - When I tap "Get started" - Then "Wallet setup" is displayed - When I tap "Import using Secret Recovery Phrase" - Then "Help us improve MetaMask" is displayed - When I tap "I agree" - And Terms of Use is displayed - And I agree to terms - And Terms of Use is not displayed - Then "Import from seed" is displayed - - Scenario Outline: Password Strength - When I type in new password field - Then password strength is displayed - Examples: - | password | strength | - | metapass1 | Password strength: Weak | - | Metapass12345 | Password strength: Good | - | Metapass12345!@ | Password strength: Strong | - - Scenario Outline: Password Matching - When I type in confirm password field - Then green check mark is displayed - Examples: - | password | - | Metapass12345!@ | - - Scenario Outline: Invalid SRP - When I type in SRP field - And I tap "Import" - Then device alert is displayed - And I tap Yes on alert - - Examples: - | invalid_SRP | error | - | fold media south not valid secret recovery phrase pause cloth just raven | Invalid Secret Recovery Phrase | - | fold media south add since false relax immense pause cloth just | Secret Recovery Phrases contain 12, 15, 18, 21, or 24 words | - - Scenario Outline: Import Wallet - When I type in SRP field - And I type in confirm password field - And I tap "Import" - And I tap No Thanks on the Enable security check screen - Then "Welcome to your new wallet!" is displayed - Examples: - | SRP | password | - | fold media south add since false relax immense pause cloth just raven | Metapass12345!@ | diff --git a/wdio/features/Onboarding/OnboardingCarousel.feature b/wdio/features/Onboarding/OnboardingCarousel.feature index f95558259e1..8c7f07894ff 100644 --- a/wdio/features/Onboarding/OnboardingCarousel.feature +++ b/wdio/features/Onboarding/OnboardingCarousel.feature @@ -4,8 +4,8 @@ Feature: Onboarding Users can install MetaMask mobile app from the device app store and read the onboarding carousel Scenario: New app install setup on a mobile device - This is the onboarding process after a new user installs the mobile app - and launches the app for the first time. + This is the onboarding process after a new user installs the mobile app + and launches the app for the first time. Given the app displayed the splash animation And the splash animation disappears And the Welcome Screen is displayed @@ -15,7 +15,5 @@ Feature: Onboarding Then "Your gateway to web3" carousel item is displayed When I swipe left on the carousel And I tap "Get started" - Then "Wallet setup" is displayed - And "Import an existing wallet or create a new one" is displayed - And "Import using Secret Recovery Phrase" is displayed - And "Create a new wallet" is displayed + Then Wallet setup screen is displayed + diff --git a/wdio/features/Onboarding/TermsOfUse.feature b/wdio/features/Onboarding/TermsOfUse.feature index 85021b292aa..17f083d454f 100644 --- a/wdio/features/Onboarding/TermsOfUse.feature +++ b/wdio/features/Onboarding/TermsOfUse.feature @@ -1,4 +1,4 @@ -@androidApp +@androidApp @regression Feature: Terms of Use @@ -6,7 +6,7 @@ Feature: Terms of Use Given the app displayed the splash animation And the Welcome Screen is displayed When I tap "Get started" - Then "Wallet setup" is displayed + Then Wallet setup screen is displayed When I tap "Import using Secret Recovery Phrase" Then "Help us improve MetaMask" is displayed When I tap "I agree" @@ -19,7 +19,7 @@ Feature: Terms of Use And the splash animation disappears Then the Welcome Screen is displayed When I tap "Get started" - Then "Wallet setup" is displayed + Then Wallet setup screen is displayed When I tap "Import using Secret Recovery Phrase" Then Terms of Use is displayed @@ -34,6 +34,6 @@ Feature: Terms of Use And the splash animation disappears Then the Welcome Screen is displayed When I tap "Get started" - Then "Wallet setup" is displayed + Then Wallet setup screen is displayed When I tap "Import using Secret Recovery Phrase" Then Terms of Use is not displayed diff --git a/wdio/features/SecurityAndPrivacy/DeleteWallet.feature b/wdio/features/SecurityAndPrivacy/DeleteWallet.feature index 6aea89cf9e5..88b039b94cf 100644 --- a/wdio/features/SecurityAndPrivacy/DeleteWallet.feature +++ b/wdio/features/SecurityAndPrivacy/DeleteWallet.feature @@ -17,4 +17,4 @@ Feature: This feature deletes the wallet from the Security and Privacy View And I tap I understand, continue on Delete wallet modal And I type "delete" on Delete wallet modal permanently And I tap Delete my wallet on Delete wallet modal permanently - Then "Wallet setup" is displayed + Then Wallet setup screen is displayed diff --git a/wdio/features/Wallet/ExploringWizard.feature b/wdio/features/Wallet/ExploringWizard.feature index b751efb04fc..db064c12ce9 100644 --- a/wdio/features/Wallet/ExploringWizard.feature +++ b/wdio/features/Wallet/ExploringWizard.feature @@ -13,10 +13,10 @@ Feature: Exploring wizard When On the onboarding wizard I tap on "Got it" button Then the tutorial modal heading should read "Edit Account Name" And there should be an explanation about adding a nickname to your account. - #When I tap and hold on the account Name - #Then I should be able to edit the account Name - #When I enter "Big Bank" for account name - #Then the account nickname should read "Big Bank" + When I tap and hold on the account Name + Then I should be able to edit the account Name + When I enter "Big Bank" for account name + Then the account nickname should read "Big Bank" When On the onboarding wizard I tap on "Got it" button Then the tutorial modal heading should read "Main Menu" And there should be an explanation of the what exists within the main menu. @@ -36,18 +36,18 @@ Feature: Exploring wizard Then the onboarding wizard is no longer visible And I close the Whats New modal - # Scenario: A user should be able to tap the Skip button - # Given the app displayed the splash animation - # And I have imported my wallet - # And I tap No Thanks on the Enable security check screen - # And the onboarding wizard is visible on wallet view - # When On the onboarding wizard I tap on "Take a Tour" button - # Then the tutorial modal heading should read "Your Accounts" - # And there should be an explanation of the accounts functionality. - # When On the onboarding wizard I tap on "Got it" button - # Then the tutorial modal heading should read "Edit Account Name" - # And there should be an explanation about adding a nickname to your account. - # When On the onboarding wizard I tap on "Skip" button - # Then the onboarding wizard is no longer visible - # And the "Skip" button is no longer visible - # And I close the Whats New modal +# Scenario: A user should be able to tap the Skip button +# Given the app displayed the splash animation +# And I have imported my wallet +# And I tap No Thanks on the Enable security check screen +# And the onboarding wizard is visible on wallet view +# When On the onboarding wizard I tap on "Take a Tour" button +# Then the tutorial modal heading should read "Your Accounts" +# And there should be an explanation of the accounts functionality. +# When On the onboarding wizard I tap on "Got it" button +# Then the tutorial modal heading should read "Edit Account Name" +# And there should be an explanation about adding a nickname to your account. +# When On the onboarding wizard I tap on "Skip" button +# Then the onboarding wizard is no longer visible +# And the "Skip" button is no longer visible +# And I close the Whats New modal diff --git a/wdio/features/Wallet/ImportCustomToken.feature b/wdio/features/Wallet/ImportCustomToken.feature index 125563e78a6..1af44ba0159 100644 --- a/wdio/features/Wallet/ImportCustomToken.feature +++ b/wdio/features/Wallet/ImportCustomToken.feature @@ -1,5 +1,4 @@ @androidApp -@smoke Feature: Adding a custom token to your wallet Scenario: Import wallet diff --git a/wdio/features/Wallet/LockResetWallet.feature b/wdio/features/Wallet/LockResetWallet.feature index fc37c4a7cf5..9c8d2861a8a 100644 --- a/wdio/features/Wallet/LockResetWallet.feature +++ b/wdio/features/Wallet/LockResetWallet.feature @@ -1,5 +1,5 @@ @androidApp -@regression +@smoke Feature: Lock and Reset Wallet Scenario: Import account @@ -24,4 +24,4 @@ Feature: Lock and Reset Wallet And I tap I understand, continue on Delete wallet modal And I type "delete" on Delete wallet modal permanently And I tap Delete my wallet on Delete wallet modal permanently - Then "Wallet setup" is displayed + Then Wallet setup screen is displayed diff --git a/wdio/features/Wallet/SendToken.feature b/wdio/features/Wallet/SendToken.feature index c6143405906..bb8906b5751 100644 --- a/wdio/features/Wallet/SendToken.feature +++ b/wdio/features/Wallet/SendToken.feature @@ -1,5 +1,5 @@ @androidApp -@smoke +@regression Feature: Sending Native and ERC Tokens Scenario: Import wallet @@ -10,75 +10,62 @@ Feature: Sending Native and ERC Tokens And I close the Whats New modal Then I am on the wallet view - Scenario Outline: Adding AVAX testnet to my networks list - Given I tap on the navbar network title button - And I tap on the Add a Network button - And I tap on the "CUSTOM NETWORKS" tab - And I type "" into Network name field - And I type "" into the RPC url field - And I type "" into the Chain ID field - And I type "" into the Network symbol field - When I tap on the Add button - And I tap on Got it in the network education modal - Then I see "" visible in the top navigation bar - Examples: - | Network | rpcUrl | ChainID | Symbol | - | AVAX Fuji | https://api.avax-test.network/ext/C/rpc | 43113 | AVAX | - - Scenario Outline: Import Custom AVAX Fuji Token + Scenario Outline: Import ChainLink Token Given I tap on the navbar network title button And I tap on on Networks list to switch + And I tap on Got it in the network education modal + Then I see "" visible in the top navigation bar When I tap Import Tokens - And I type into token Address field + And I type into token Address field Then The Token Symbol is displayed When I tap on the Import button Then I should see "Imported Token" toast message Examples: - | NETWORK | TOKENADDRESS | - | AVAX Fuji | 0x5425890298aed601595a70AB815c96711a31Bc65 | + | NETWORK | TOKEN_ADDRESS | + | Sepolia Test Network | 0x779877A7B0D9E8603169DdbD7836e478b4624789 | - Scenario Outline: A user can send native tokens to an Address via the wallet view send button - Given I see "" visible in the top navigation bar - And On the Main Wallet view I tap on the Send Action + Scenario Outline: A user can send ERC-20 tokens to an Address via token overview screen + Given I am on the wallet view + When I tap Token containing text "" + Then I am taken to the token overview screen + When I tap button Send on Token screen view And I enter address "
" in the sender's input box - When I tap button "Next" on Send To view - Then I proceed to the amount view - When I type amount "" into amount input field + And I tap button "Next" on Send To view + And I type amount "" into amount input field And I tap button "Next" on the Amount view Then I should be taken to the transaction confirmation view - And the token being sent is visible + And the token being sent is visible And the token amount to be sent is visible - When I tap button Send on Confirm Amount view - And Sending token takes me to main wallet view + When I tap button "Send" on Confirm Amount view + # Then the transaction is submitted with Transaction Complete! toast appearing + And I am taken to the token overview screen + Examples: - | NETWORK | TOKEN | AMOUNT | Address | - | AVAX Fuji | AVAX | 0.005 | 0x2990079bcdEe240329a520d2444386FC119da21a | + | TOKEN_NAME | TOKEN_SYMBOL | AMOUNT | Address | + | ChainLink Token | LINK | 0.002 | 0x2990079bcdEe240329a520d2444386FC119da21a | - Scenario Outline: A user can send ERC-20 tokens to an Address via token overview screen - Given I am on the wallet view - And I see "" visible in the top navigation bar - When I tap Token containing text "" - Then I am taken to the token overview screen - When I tap button Send on Token screen view + Scenario Outline: A user can send native tokens to an Address via the wallet view send button + When I tap back from the Token overview page + And On the Main Wallet view I tap on the Send Action And I enter address "
" in the sender's input box - And I tap button "Next" on Send To view - And I type amount "" into amount input field + When I tap button "Next" on Send To view + Then I proceed to the amount view + When I type amount "" into amount input field And I tap button "Next" on the Amount view Then I should be taken to the transaction confirmation view And the token being sent is visible And the token amount to be sent is visible - When I tap button Send on Confirm Amount view - Then I am taken to the token overview screen - + When I tap button "Send" on Confirm Amount view + # Then the transaction is submitted with Transaction Complete! toast appearing + And Sending token takes me to main wallet view Examples: - | NETWORK | TOKEN | AMOUNT | Address | - | AVAX Fuji | USDC | 0.002 | 0x2990079bcdEe240329a520d2444386FC119da21a | + | TOKEN | AMOUNT | Address | + | SepoliaETH | 0.002 | 0x2990079bcdEe240329a520d2444386FC119da21a | Scenario Outline: A user tries to send an invalid amount - Given I tap back from the Token overview page - And I am on the wallet view + When I am on the wallet view And On the Main Wallet view I tap on the Send Action And I enter address "
" in the sender's input box When I tap button "Next" on Send To view @@ -86,5 +73,5 @@ Feature: Sending Native and ERC Tokens And I tap button "Next" on the Amount view Then "Insufficient funds" is visible Examples: - | NETWORK | TOKEN | AMOUNT | Address | - | AVAX Fuji | 1 USDC | 121212121212121212121 | 0x2990079bcdEe240329a520d2444386FC119da21a | + | AMOUNT | Address | + | 25 | 0x2990079bcdEe240329a520d2444386FC119da21a | diff --git a/wdio/helpers/Selectors.js b/wdio/helpers/Selectors.js index e643b41a479..f79005c4d22 100644 --- a/wdio/helpers/Selectors.js +++ b/wdio/helpers/Selectors.js @@ -18,7 +18,7 @@ class Selectors { } } - static async getElementsByPlatform(id) { + static async getXpathByContentDesc(id) { return driver.$$(`//*[@content-desc='${id}']`); } diff --git a/wdio/screen-objects/AccountListComponent.js b/wdio/screen-objects/AccountListComponent.js index 6a95450085d..1aa1b3582ff 100644 --- a/wdio/screen-objects/AccountListComponent.js +++ b/wdio/screen-objects/AccountListComponent.js @@ -21,7 +21,7 @@ class AccountListComponent { } get accountsListed() { - return Selectors.getElementsByPlatform(CELL_TITLE_TEST_ID); + return Selectors.getXpathByContentDesc(CELL_TITLE_TEST_ID); } async tapCreateAccountButton() { diff --git a/wdio/screen-objects/CommonScreen.js b/wdio/screen-objects/CommonScreen.js index 0e5f5a39367..052bb4bf61d 100644 --- a/wdio/screen-objects/CommonScreen.js +++ b/wdio/screen-objects/CommonScreen.js @@ -1,6 +1,7 @@ import Selectors from '../helpers/Selectors'; import Gestures from '../helpers/Gestures'; import { ANDROID_PROGRESS_BAR, TOAST_ID } from './testIDs/Common.testIds'; +import { NOTIFICATION_TITLE } from './testIDs/Components/Notification.testIds'; class CommonScreen { get toast() { @@ -11,6 +12,10 @@ class CommonScreen { return Selectors.getElementByCss(ANDROID_PROGRESS_BAR); } + get TokenNotificationTitle() { + return Selectors.getElementByPlatform(NOTIFICATION_TITLE); + } + async waitForToastToDisplay() { const element = await this.toast; await element.waitForExist(); @@ -44,6 +49,11 @@ class CommonScreen { // Taps text that contains the string await Gestures.tapByTextContaining(text); } + + async checkNoNotification() { + const notification = await this.TokenNotificationTitle; + await notification.waitForExist({reverse: true}) + } } export default new CommonScreen(); diff --git a/wdio/screen-objects/EnableSecurityChecksScreen.js b/wdio/screen-objects/EnableSecurityChecksScreen.js index b0668da9749..ceae5d7eefa 100644 --- a/wdio/screen-objects/EnableSecurityChecksScreen.js +++ b/wdio/screen-objects/EnableSecurityChecksScreen.js @@ -18,6 +18,8 @@ class EnableAutomaticSecurityChecksScreen { } async tapNoThanksButton() { + const element = await this.noThanksButton; + await element.waitForExist(1500); await Gestures.waitAndTap(this.noThanksButton); } diff --git a/wdio/screen-objects/Modals/TabBarModal.js b/wdio/screen-objects/Modals/TabBarModal.js index dbff4736c21..b8307875c0b 100644 --- a/wdio/screen-objects/Modals/TabBarModal.js +++ b/wdio/screen-objects/Modals/TabBarModal.js @@ -39,7 +39,9 @@ class TabBarModal { } async tapActionButton() { - await Gestures.waitAndTap(this.actionButton); + const actionButton = await this.actionButton + await actionButton.waitForExist(); + await Gestures.longPress(actionButton, 500); } } diff --git a/wdio/screen-objects/Modals/TermOfUseScreen.js b/wdio/screen-objects/Modals/TermOfUseScreen.js index 63a7f695ad7..70b3ed2e811 100644 --- a/wdio/screen-objects/Modals/TermOfUseScreen.js +++ b/wdio/screen-objects/Modals/TermOfUseScreen.js @@ -36,6 +36,11 @@ class TermOfUseScreen { await container.waitForDisplayed(); } + async textIsDisplayed() { + const termsText = await Selectors.getXpathElementByTextContains('Last Updated') + await termsText.waitForDisplayed(); + } + async isNotDisplayed() { const container = await this.container; await container.waitForExist({ reverse: true}); @@ -52,6 +57,16 @@ class TermOfUseScreen { await driver.pause(500); } + async acceptIsEnabled() { + const element = await this.acceptButton; + return element.isEnabled(); + } + + async isCheckBoxChecked() { + const element = await this.checkbox; + return element.isEnabled(); + } + async tapAcceptButton() { await Gestures.tap(this.acceptButton); } diff --git a/wdio/screen-objects/Onboarding/OnboardingCarousel.js b/wdio/screen-objects/Onboarding/OnboardingCarousel.js index 914b9499dba..3f4bc9ff245 100644 --- a/wdio/screen-objects/Onboarding/OnboardingCarousel.js +++ b/wdio/screen-objects/Onboarding/OnboardingCarousel.js @@ -31,8 +31,15 @@ class WelcomeScreen { async waitForSplashAnimationToDisplay() { const elem = await this.splashScreenMetamaskAnimationId; - await elem.waitForExist(); + const getStartedElem = await this.getStartedButton; + try { + await elem.waitForExist(); + } catch (error) { + console.log(`Splash screen animation element '${this.splashScreenMetamaskAnimationId}' not found`) + await getStartedElem.waitForExist(); + } } + async waitForSplashAnimationToNotExit() { const elem = await this.splashScreenMetamaskAnimationId; diff --git a/wdio/screen-objects/TokenOverviewScreen.js b/wdio/screen-objects/TokenOverviewScreen.js index 83b6a10f4f7..df8282562fd 100644 --- a/wdio/screen-objects/TokenOverviewScreen.js +++ b/wdio/screen-objects/TokenOverviewScreen.js @@ -20,7 +20,9 @@ class TokenOverviewScreen { } async tapBackButton() { - await Gestures.waitAndTap(this.backButtonTokenOverview); + const element = await this.backButtonTokenOverview; + await element.waitForDisplayed(); + await Gestures.waitAndTap(element); } async isTokenOverviewVisible() { diff --git a/wdio/screen-objects/WalletMainScreen.js b/wdio/screen-objects/WalletMainScreen.js index 030bfc2e0b0..efa5a79aeb7 100644 --- a/wdio/screen-objects/WalletMainScreen.js +++ b/wdio/screen-objects/WalletMainScreen.js @@ -1,6 +1,6 @@ import Selectors from '../helpers/Selectors'; import Gestures from '../helpers/Gestures.js'; -import {WALLET_CONTAINER_ID} from './testIDs/Screens/WalletScreen-testIds.js'; +import { WALLET_CONTAINER_ID } from './testIDs/Screens/WalletScreen-testIds.js'; import { ONBOARDING_WIZARD_STEP_1_CONTAINER_ID, ONBOARDING_WIZARD_STEP_1_NO_THANKS_ID, @@ -23,11 +23,11 @@ import { WALLET_VIEW_BURGER_ICON_ID, } from './testIDs/Screens/WalletView.testIds'; -import {DRAWER_VIEW_SETTINGS_TEXT_ID} from './testIDs/Screens/DrawerView.testIds'; +import { DRAWER_VIEW_SETTINGS_TEXT_ID } from './testIDs/Screens/DrawerView.testIds'; -import {NOTIFICATION_TITLE} from './testIDs/Components/Notification.testIds'; -import {TAB_BAR_WALLET_BUTTON} from './testIDs/Components/TabBar.testIds'; -import {BACK_BUTTON_SIMPLE_WEBVIEW} from './testIDs/Components/SimpleWebView.testIds'; +import { NOTIFICATION_TITLE } from './testIDs/Components/Notification.testIds'; +import { TAB_BAR_WALLET_BUTTON } from './testIDs/Components/TabBar.testIds'; +import { BACK_BUTTON_SIMPLE_WEBVIEW } from './testIDs/Components/SimpleWebView.testIds'; class WalletMainScreen { get wizardContainer() { @@ -152,7 +152,7 @@ class WalletMainScreen { } async tapImportNFTButton() { - await Gestures.swipe({x: 100, y: 500}, {x: 100, y: 10}); + await Gestures.swipe({ x: 100, y: 500 }, { x: 100, y: 10 }); await Gestures.waitAndTap(this.ImportNFT); } @@ -190,7 +190,7 @@ class WalletMainScreen { async isTokenTextVisible(token) { const tokenText = await Selectors.getXpathElementByTextContains(token); await expect(tokenText).toBeDisplayed(); - await tokenText.waitForExist({reverse: true}); + await tokenText.waitForExist({ reverse: true }); } async isOnboardingWizardVisible() { @@ -199,13 +199,13 @@ class WalletMainScreen { async isMainWalletViewVisible() { const element = await this.mainWalletView; - await element.waitForDisplayed(); + await element.waitForDisplayed(2500); } async waitForNotificationToDisplayed() { const element = await this.TokenNotificationTitle; await element.waitForDisplayed(); - await element.waitForExist({reverse: true}); + await element.waitForExist({ reverse: true }); } async isToastNotificationDisplayed() { @@ -213,7 +213,7 @@ class WalletMainScreen { await element.waitForDisplayed(); expect(await element.getText()).toContain('Transaction'); expect(await element.getText()).toContain('Complete!'); - await element.waitForExist({reverse: true}); + await element.waitForExist({ reverse: true }); } async isNetworkNavbarTitle(text) { diff --git a/wdio/step-definitions/common-steps.js b/wdio/step-definitions/common-steps.js index 53272b553a7..458bb6bb713 100644 --- a/wdio/step-definitions/common-steps.js +++ b/wdio/step-definitions/common-steps.js @@ -1,4 +1,4 @@ -import {Given, Then, When} from '@wdio/cucumber-framework'; +import { Given, Then, When } from '@wdio/cucumber-framework'; import Accounts from '../helpers/Accounts'; import WelcomeScreen from '../screen-objects/Onboarding/OnboardingCarousel'; import OnboardingScreen from '../screen-objects/Onboarding/OnboardingScreen'; @@ -13,7 +13,7 @@ import SkipAccountSecurityModal from '../screen-objects/Modals/SkipAccountSecuri import OnboardingWizardModal from '../screen-objects/Modals/OnboardingWizardModal.js'; import LoginScreen from '../screen-objects/LoginScreen'; import TermOfUseScreen from '../screen-objects/Modals/TermOfUseScreen'; -import WhatsNewModal from "../screen-objects/Modals/WhatsNewModal"; +import WhatsNewModal from '../screen-objects/Modals/WhatsNewModal'; Then(/^the Welcome Screen is displayed$/, async () => { await WelcomeScreen.waitForScreenToDisplay(); @@ -29,6 +29,7 @@ Given(/^the splash animation disappears$/, async () => { Then(/^Terms of Use is displayed$/, async () => { await TermOfUseScreen.isDisplayed(); + await TermOfUseScreen.textIsDisplayed(); }); When(/^I agree to terms$/, async () => { @@ -51,11 +52,15 @@ Given(/^I have imported my wallet$/, async () => { await MetaMetricsScreen.isScreenTitleVisible(); await MetaMetricsScreen.tapIAgreeButton(); await TermOfUseScreen.isDisplayed(); - await driver.pause(5000); + await TermOfUseScreen.textIsDisplayed(); await TermOfUseScreen.tapAgreeCheckBox(); await TermOfUseScreen.tapScrollEndButton(); - await driver.pause(); - await TermOfUseScreen.tapAcceptButton(); + if (!await TermOfUseScreen.isCheckBoxChecked()){ + await TermOfUseScreen.tapAgreeCheckBox(); + await TermOfUseScreen.tapAcceptButton(); + } else { + await TermOfUseScreen.tapAcceptButton(); + } await ImportFromSeedScreen.isScreenTitleVisible(); await ImportFromSeedScreen.typeSecretRecoveryPhrase(validAccount.seedPhrase); await ImportFromSeedScreen.typeNewPassword(validAccount.password); @@ -117,7 +122,7 @@ Given(/^I tap No thanks on the onboarding welcome tutorial/, async () => { }); Then(/^"([^"]*)?" is visible/, async (text) => { - const timeout = 1000; + const timeout = 2500; await driver.pause(timeout); await CommonScreen.isTextDisplayed(text); }); @@ -134,6 +139,12 @@ Then(/^"([^"]*)?" is not displayed/, async (text) => { await CommonScreen.isTextElementNotDisplayed(text); }); +Then(/^"([^"]*)?" is displayed/, async (text) => { + const timeout = 1000; + await driver.pause(timeout); + await CommonScreen.isTextDisplayed(text); +}); + Then(/^Sending token takes me to main wallet view/, async () => { const timeout = 1000; await driver.pause(timeout); @@ -186,6 +197,7 @@ When(/^I unlock wallet with (.*)$/, async (password) => { Then( /^I tap (.*) "([^"]*)?" on (.*) (.*) view/, async (elementType, button, screen, type) => { + await CommonScreen.checkNoNotification(); // Notification appears a little late and inteferes with clicking function await CommonScreen.tapOnText(button); }, ); diff --git a/wdio/step-definitions/create-new-wallet-account.steps.js b/wdio/step-definitions/create-new-wallet-account.steps.js index 09e782a15ec..a2f29f9e2b4 100644 --- a/wdio/step-definitions/create-new-wallet-account.steps.js +++ b/wdio/step-definitions/create-new-wallet-account.steps.js @@ -17,6 +17,5 @@ When(/^A new account is created/, async () => { Then(/^I am on the new account/, async () => { await WalletMainScreen.tapIdenticon(); - await AccountListComponent.isComponentNotDisplayed(); - await WalletAccountModal.isAccountNameLabelEqualTo('Account 2'); + await WalletAccountModal.isAccountNameLabelEqualTo('Account 2'); // this could be better. This stemp could be a bit more dynmic }); diff --git a/wdio/step-definitions/import-wallet-via-private-key.steps.js b/wdio/step-definitions/import-wallet-via-private-key.steps.js index 48bf9e53709..c4e26cf87ce 100644 --- a/wdio/step-definitions/import-wallet-via-private-key.steps.js +++ b/wdio/step-definitions/import-wallet-via-private-key.steps.js @@ -31,6 +31,7 @@ Then(/^The account is imported/, async () => { }); Then(/^I should see an error (.*)/, async (errorMessage) => { + await driver.pause(1000); await ImportAccountScreen.isAlertTextVisible(errorMessage); await driver.acceptAlert(); }); diff --git a/wdio/step-definitions/onboarding.steps.js b/wdio/step-definitions/onboarding.steps.js index 48d0eab2926..c020b5c522a 100644 --- a/wdio/step-definitions/onboarding.steps.js +++ b/wdio/step-definitions/onboarding.steps.js @@ -16,9 +16,6 @@ Then(/^"([^"]*)?" is displayed/, async (text) => { await WelcomeScreen.waitForSplashAnimationToDisplay(); await WelcomeScreen.waitForSplashAnimationToNotExit(); break; - case 'Wallet setup': - await OnboardingScreen.isScreenTitleVisible(); - break; case 'Import an existing wallet or create a new one': await OnboardingScreen.isScreenDescriptionVisible(); break; @@ -91,6 +88,11 @@ When(/^I tap "([^"]*)"/, async (text) => { } }); +Then(/^Wallet setup screen is displayed/, async () => { + // await driver.pause(3000); + await OnboardingScreen.isScreenTitleVisible(); +}); + When(/^I type (.*) in SRP field/, async (text) => { await ImportFromSeedScreen.typeSecretRecoveryPhrase(text); }); diff --git a/wdio/step-definitions/send-flow.steps.js b/wdio/step-definitions/send-flow.steps.js index db810eb9c83..0a76720c5fa 100644 --- a/wdio/step-definitions/send-flow.steps.js +++ b/wdio/step-definitions/send-flow.steps.js @@ -6,6 +6,7 @@ import AmountScreen from '../screen-objects/AmountScreen'; import WalletMainScreen from '../screen-objects/WalletMainScreen'; import TokenOverviewScreen from '../screen-objects/TokenOverviewScreen'; import TransactionConfirmScreen from '../screen-objects/TransactionConfirmScreen'; +import CommonScreen from '../screen-objects/CommonScreen'; Then(/^On the Address book modal Cancel button is enabled/, async () => { await AddressBookModal.isCancelButtonEnabled(); @@ -30,7 +31,9 @@ Then(/^I tap the Save button/, async () => { Given( /^I enter address "([^"]*)?" in the sender's input box/, async (address) => { + await CommonScreen.checkNoNotification(); // Notification appears a little late and inteferes with clicking function await SendScreen.typeAddressInSendAddressField(address); + await driver.hideKeyboard(); }, ); @@ -104,11 +107,13 @@ Then( /^I enter invalid address "([^"]*)?" into senders input field/, async (address) => { await SendScreen.typeAddressInSendAddressField(address); + await driver.hideKeyboard(); }, ); Then(/^I type amount "([^"]*)?" into amount input field/, async (amount) => { await AmountScreen.enterAmount(amount); + await driver.hideKeyboard(); }); Then( @@ -124,6 +129,7 @@ Then(/^I am taken to the token overview screen/, async () => { Then(/^I tap back from the Token overview page/, async () => { await TokenOverviewScreen.tapBackButton(); + await TokenOverviewScreen.tapBackButton();// Double tap seems to work best on BS }); When(/^I tap button Send on Token screen view$/, async () => { diff --git a/wdio/step-definitions/wallet-view.steps.js b/wdio/step-definitions/wallet-view.steps.js index 6490eec7021..bb143e4539f 100644 --- a/wdio/step-definitions/wallet-view.steps.js +++ b/wdio/step-definitions/wallet-view.steps.js @@ -77,6 +77,7 @@ Then(/^Wallet view is displayed$/, async () => { }); Given(/^On the Main Wallet view I tap on the Send Action$/, async () => { + await CommonScreen.checkNoNotification(); await TabBarModal.tapActionButton(); await WalletActionModal.tapSendButton(); }); From 373e4781947e434e63ac795d7e2a9a5abed9cea9 Mon Sep 17 00:00:00 2001 From: Curtis David Date: Thu, 4 May 2023 19:23:14 -0400 Subject: [PATCH 10/20] [DETOX] Only Run tests with the "smoke" tag in the describe block (#6338) * add tags to test describe block. * add regression tags to describe block * create methods for Smoke & Regression * update bitrise.yml * fix lint * update changelog --- README.md | 5 + bitrise.yml | 2 +- e2e/specs/add-custom-rpc.spec.js | 3 +- e2e/specs/addressbook-tests.spec.js | 3 +- e2e/specs/browser-tests.spec.js | 3 +- .../confirmations/advanced-gas-fees.spec.js | 4 +- e2e/specs/confirmations/send-eth-flow.spec.js | 3 +- .../send-multisig-address-ios.spec.js | 4 +- e2e/specs/deeplinks.spec.js | 3 +- e2e/specs/delete-wallet.spec.js | 246 ++++++++-------- e2e/specs/onboarding-wizard-opt-in.spec.js | 264 +++++++++--------- .../permission-system-delete-wallet.spec.js | 179 ++++++------ ...n-system-removing-imported-account.spec.js | 210 +++++++------- ...ssion-system-revoke-single-account.spec.js | 3 +- ...-system-revoking-multiple-accounts.spec.js | 162 +++++------ e2e/specs/request-token-flow.spec.js | 4 +- e2e/specs/send-ERC-token.spec.js | 4 +- e2e/specs/start-exploring.spec.js | 3 +- e2e/specs/wallet-tests.spec.js | 4 +- e2e/tags.js | 8 + 20 files changed, 584 insertions(+), 533 deletions(-) create mode 100644 e2e/tags.js diff --git a/README.md b/README.md index 389292fe0e8..8747c91ee82 100644 --- a/README.md +++ b/README.md @@ -246,7 +246,12 @@ If you have already built the application for Detox and want to run a specific t ```bash yarn test:e2e:ios:debug:single e2e/specs/TEST_NAME.spec.js ``` +To run tests associated with a certain tag, you can do so using the `--testNamePattern` flag. For example: +```bash +yarn test:e2e:ios:debug --testNamePattern="Smoke" +``` +This runs all tests that are tagged "Smoke" ##### Android All android tests live within the wdio/feature folder. diff --git a/bitrise.yml b/bitrise.yml index d83e174f815..be639dde2d9 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -220,7 +220,7 @@ workflows: - content: |- #!/usr/bin/env bash node -v - METAMASK_ENVIRONMENT='production' yarn test:e2e:ios + METAMASK_ENVIRONMENT='production' yarn test:e2e:ios --testNamePattern='Smoke' title: Detox Build & Test is_always_run: false - custom-test-results-export@1: diff --git a/e2e/specs/add-custom-rpc.spec.js b/e2e/specs/add-custom-rpc.spec.js index 624ff21dba6..0923d20479b 100644 --- a/e2e/specs/add-custom-rpc.spec.js +++ b/e2e/specs/add-custom-rpc.spec.js @@ -1,5 +1,6 @@ 'use strict'; import TestHelpers from '../helpers'; +import { Regression } from '../tags'; import OnboardingView from '../pages/Onboarding/OnboardingView'; import OnboardingCarouselView from '../pages/Onboarding/OnboardingCarouselView'; @@ -28,7 +29,7 @@ const XDAI_URL = 'https://rpc.gnosischain.com'; const MAINNET = 'Ethereum Main Network'; const PASSWORD = '12345678'; -describe('Custom RPC Tests', () => { +describe(Regression('Custom RPC Tests'), () => { beforeEach(() => { jest.setTimeout(170000); }); diff --git a/e2e/specs/addressbook-tests.spec.js b/e2e/specs/addressbook-tests.spec.js index df3b8e4b812..904f0530977 100644 --- a/e2e/specs/addressbook-tests.spec.js +++ b/e2e/specs/addressbook-tests.spec.js @@ -1,4 +1,5 @@ 'use strict'; +import { Smoke } from '../tags'; import OnboardingView from '../pages/Onboarding/OnboardingView'; import OnboardingCarouselView from '../pages/Onboarding/OnboardingCarouselView'; import ProtectYourWalletView from '../pages/Onboarding/ProtectYourWalletView'; @@ -31,7 +32,7 @@ const MYTH_ADDRESS = '0x1FDb169Ef12954F20A15852980e1F0C122BfC1D6'; const MEMO = 'Test adding ENS'; const PASSWORD = '12345678'; -describe('Addressbook Tests', () => { +describe(Smoke('Addressbook Tests'), () => { beforeEach(() => { jest.setTimeout(150000); }); diff --git a/e2e/specs/browser-tests.spec.js b/e2e/specs/browser-tests.spec.js index 8b9bb249b67..1cc2e49f42d 100644 --- a/e2e/specs/browser-tests.spec.js +++ b/e2e/specs/browser-tests.spec.js @@ -1,5 +1,6 @@ 'use strict'; import TestHelpers from '../helpers'; +import { Smoke } from '../tags'; import OnboardingView from '../pages/Onboarding/OnboardingView'; import OnboardingCarouselView from '../pages/Onboarding/OnboardingCarouselView'; @@ -26,7 +27,7 @@ const PASSWORD = '12345678'; const PHISHING_SITE = 'http://www.empowr.com/FanFeed/Home.aspx'; const INVALID_URL = 'https://quackquakc.easq'; -describe('Browser Tests', () => { +describe(Smoke('Browser Tests'), () => { beforeEach(() => { jest.setTimeout(150000); }); diff --git a/e2e/specs/confirmations/advanced-gas-fees.spec.js b/e2e/specs/confirmations/advanced-gas-fees.spec.js index d1deb380d97..e92b6ee6b67 100644 --- a/e2e/specs/confirmations/advanced-gas-fees.spec.js +++ b/e2e/specs/confirmations/advanced-gas-fees.spec.js @@ -1,4 +1,6 @@ 'use strict'; +import { Smoke } from '../../tags'; + import WalletView from '../../pages/WalletView'; import SendView from '../../pages/SendView'; import AmountView from '../../pages/AmountView'; @@ -12,7 +14,7 @@ import WalletActionsModal from '../../pages/modals/WalletActionsModal'; const VALID_ADDRESS = '0xebe6CcB6B55e1d094d9c58980Bc10Fed69932cAb'; -describe('Advanced Gas Fees and Priority Tests', () => { +describe(Smoke('Advanced Gas Fees and Priority Tests'), () => { beforeEach(() => { jest.setTimeout(170000); }); diff --git a/e2e/specs/confirmations/send-eth-flow.spec.js b/e2e/specs/confirmations/send-eth-flow.spec.js index 0aa1c43d8d4..b295ba75ea2 100644 --- a/e2e/specs/confirmations/send-eth-flow.spec.js +++ b/e2e/specs/confirmations/send-eth-flow.spec.js @@ -1,5 +1,6 @@ 'use strict'; +import { Smoke } from '../../tags'; import AmountView from '../../pages/AmountView'; import SendView from '../../pages/SendView'; import TransactionConfirmationView from '../../pages/TransactionConfirmView'; @@ -16,7 +17,7 @@ import Ganache from '../../../app/util/test/ganache'; const validAccount = Accounts.getValidAccount(); const MYTH_ADDRESS = '0x1FDb169Ef12954F20A15852980e1F0C122BfC1D6'; -describe('Send ETH Tests', () => { +describe(Smoke('Send ETH Tests'), () => { let ganacheServer; beforeAll(async () => { jest.setTimeout(150000); diff --git a/e2e/specs/confirmations/send-multisig-address-ios.spec.js b/e2e/specs/confirmations/send-multisig-address-ios.spec.js index 8b7d2108985..4e1cd00145b 100644 --- a/e2e/specs/confirmations/send-multisig-address-ios.spec.js +++ b/e2e/specs/confirmations/send-multisig-address-ios.spec.js @@ -1,4 +1,6 @@ 'use strict'; +import { Regression } from '../../tags'; + import WalletView from '../../pages/WalletView'; import DrawerView from '../../pages/Drawer/DrawerView'; import SendView from '../../pages/SendView'; @@ -11,7 +13,7 @@ import { const MULTISIG_ADDRESS = '0x0C1DD822d1Ddf78b0b702df7BF9fD0991D6255A1'; -describe('Send to multisig address on iOS', () => { +describe(Regression('Send to multisig address on iOS'), () => { beforeEach(() => { jest.setTimeout(170000); }); diff --git a/e2e/specs/deeplinks.spec.js b/e2e/specs/deeplinks.spec.js index eae0faf7e93..74077743bba 100644 --- a/e2e/specs/deeplinks.spec.js +++ b/e2e/specs/deeplinks.spec.js @@ -1,5 +1,6 @@ 'use strict'; import TestHelpers from '../helpers'; +import { Regression } from '../tags'; import ConnectModal from '../pages/modals/ConnectModal'; import NetworkApprovalModal from '../pages/modals/NetworkApprovalModal'; @@ -39,7 +40,7 @@ const networkErrorBodyMessage = const validAccount = Accounts.getValidAccount(); -describe('Deep linking Tests', () => { +describe(Regression('Deep linking Tests'), () => { beforeEach(() => { jest.setTimeout(150000); }); diff --git a/e2e/specs/delete-wallet.spec.js b/e2e/specs/delete-wallet.spec.js index b3bf99d1e0d..ffa6353451b 100644 --- a/e2e/specs/delete-wallet.spec.js +++ b/e2e/specs/delete-wallet.spec.js @@ -1,6 +1,7 @@ 'use strict'; import TestHelpers from '../helpers'; +import { Smoke } from '../tags'; import OnboardingView from '../pages/Onboarding/OnboardingView'; import OnboardingCarouselView from '../pages/Onboarding/OnboardingCarouselView'; @@ -24,123 +25,128 @@ import EnableAutomaticSecurityChecksView from '../pages/EnableAutomaticSecurityC import { acceptTermOfUse } from '../viewHelper'; import Accounts from '../../wdio/helpers/Accounts'; -describe('Import wallet with 24 word SRP, change password then delete wallet flow', () => { - let validAccount; - - beforeAll(() => { - validAccount = Accounts.getValidAccount(); - }); - - beforeEach(() => { - jest.setTimeout(150000); - }); - - it('should go to import wallet view', async () => { - await OnboardingCarouselView.isVisible(); - await OnboardingCarouselView.tapOnGetStartedButton(); - - await OnboardingView.isVisible(); - await OnboardingView.tapImportWalletFromSeedPhrase(); - - await MetaMetricsOptIn.isVisible(); - await MetaMetricsOptIn.tapAgreeButton(); - await acceptTermOfUse(); - - await ImportWalletView.isVisible(); - }); - - it('should import wallet with valid secret recovery phrase and password', async () => { - await ImportWalletView.clearSecretRecoveryPhraseInputBox(); - await ImportWalletView.enterSecretRecoveryPhrase(validAccount.seedPhrase); - await ImportWalletView.enterPassword(validAccount.password); - await ImportWalletView.reEnterPassword(validAccount.password); - }); - it('Should dismiss Automatic Security checks screen', async () => { - await TestHelpers.delay(3500); - await EnableAutomaticSecurityChecksView.isVisible(); - await EnableAutomaticSecurityChecksView.tapNoThanks(); - }); - - it('should dismiss the onboarding wizard', async () => { - // dealing with flakiness on bitrise. - await TestHelpers.delay(1000); - try { - await OnboardingWizardModal.isVisible(); - await OnboardingWizardModal.tapNoThanksButton(); - await OnboardingWizardModal.isNotVisible(); - } catch { - // - } - }); - - it('should tap on "Got it" to dimiss the whats new modal', async () => { - // dealing with flakiness on bitrise. - await TestHelpers.delay(2500); - try { - await WhatsNewModal.isVisible(); - await WhatsNewModal.tapCloseButton(); - } catch { - // - } - }); - - it('should go to settings then security & privacy', async () => { - // Open Drawer - await WalletView.tapDrawerButton(); // tapping burger menu - - await DrawerView.isVisible(); - await DrawerView.tapSettings(); - - await SettingsView.tapSecurityAndPrivacy(); - await SecurityAndPrivacyView.scrollToChangePasswordView(); - - await SecurityAndPrivacyView.isChangePasswordSectionVisible(); - }); - - it('should confirm password before changing it', async () => { - await SecurityAndPrivacyView.tapChangePasswordButton(); - - await ChangePasswordView.isVisible(); - await ChangePasswordView.typeInConfirmPasswordInputBox( - validAccount.password, - ); - //await ChangePasswordView.tapConfirmButton(); - }); - - it('should change the password', async () => { - const NEW_PASSWORD = '11111111'; - await ChangePasswordView.enterPassword(NEW_PASSWORD); - await ChangePasswordView.reEnterPassword(NEW_PASSWORD); - await ChangePasswordView.tapIUnderstandCheckBox(); - - await ChangePasswordView.tapResetPasswordButton(); - }); - - it('should open drawer and log out', async () => { - await device.disableSynchronization(); // because the SRP tutorial video prevents the test from moving forward - await SecurityAndPrivacyView.tapBackButton(); - await device.enableSynchronization(); - - await SettingsView.tapCloseButton(); - - await WalletView.tapDrawerButton(); - - await DrawerView.isVisible(); - await DrawerView.tapLockAccount(); - await DrawerView.tapYesAlertButton(); - await LoginView.isVisible(); - }); - - it('should tap reset wallet button', async () => { - await LoginView.tapResetWalletButton(); - - await DeleteWalletModal.isVisible(); - }); - it('should delete wallet', async () => { - await DeleteWalletModal.tapIUnderstandButton(); - await DeleteWalletModal.typeDeleteInInputBox(); - await DeleteWalletModal.tapDeleteMyWalletButton(); - await TestHelpers.delay(2000); - await OnboardingView.isVisible(); - }); -}); +describe( + Smoke( + 'Import wallet with 24 word SRP, change password then delete wallet flow', + ), + () => { + let validAccount; + + beforeAll(() => { + validAccount = Accounts.getValidAccount(); + }); + + beforeEach(() => { + jest.setTimeout(150000); + }); + + it('should go to import wallet view', async () => { + await OnboardingCarouselView.isVisible(); + await OnboardingCarouselView.tapOnGetStartedButton(); + + await OnboardingView.isVisible(); + await OnboardingView.tapImportWalletFromSeedPhrase(); + + await MetaMetricsOptIn.isVisible(); + await MetaMetricsOptIn.tapAgreeButton(); + await acceptTermOfUse(); + + await ImportWalletView.isVisible(); + }); + + it('should import wallet with valid secret recovery phrase and password', async () => { + await ImportWalletView.clearSecretRecoveryPhraseInputBox(); + await ImportWalletView.enterSecretRecoveryPhrase(validAccount.seedPhrase); + await ImportWalletView.enterPassword(validAccount.password); + await ImportWalletView.reEnterPassword(validAccount.password); + }); + it('Should dismiss Automatic Security checks screen', async () => { + await TestHelpers.delay(3500); + await EnableAutomaticSecurityChecksView.isVisible(); + await EnableAutomaticSecurityChecksView.tapNoThanks(); + }); + + it('should dismiss the onboarding wizard', async () => { + // dealing with flakiness on bitrise. + await TestHelpers.delay(1000); + try { + await OnboardingWizardModal.isVisible(); + await OnboardingWizardModal.tapNoThanksButton(); + await OnboardingWizardModal.isNotVisible(); + } catch { + // + } + }); + + it('should tap on "Got it" to dimiss the whats new modal', async () => { + // dealing with flakiness on bitrise. + await TestHelpers.delay(2500); + try { + await WhatsNewModal.isVisible(); + await WhatsNewModal.tapCloseButton(); + } catch { + // + } + }); + + it('should go to settings then security & privacy', async () => { + // Open Drawer + await WalletView.tapDrawerButton(); // tapping burger menu + + await DrawerView.isVisible(); + await DrawerView.tapSettings(); + + await SettingsView.tapSecurityAndPrivacy(); + await SecurityAndPrivacyView.scrollToChangePasswordView(); + + await SecurityAndPrivacyView.isChangePasswordSectionVisible(); + }); + + it('should confirm password before changing it', async () => { + await SecurityAndPrivacyView.tapChangePasswordButton(); + + await ChangePasswordView.isVisible(); + await ChangePasswordView.typeInConfirmPasswordInputBox( + validAccount.password, + ); + //await ChangePasswordView.tapConfirmButton(); + }); + + it('should change the password', async () => { + const NEW_PASSWORD = '11111111'; + await ChangePasswordView.enterPassword(NEW_PASSWORD); + await ChangePasswordView.reEnterPassword(NEW_PASSWORD); + await ChangePasswordView.tapIUnderstandCheckBox(); + + await ChangePasswordView.tapResetPasswordButton(); + }); + + it('should open drawer and log out', async () => { + await device.disableSynchronization(); // because the SRP tutorial video prevents the test from moving forward + await SecurityAndPrivacyView.tapBackButton(); + await device.enableSynchronization(); + + await SettingsView.tapCloseButton(); + + await WalletView.tapDrawerButton(); + + await DrawerView.isVisible(); + await DrawerView.tapLockAccount(); + await DrawerView.tapYesAlertButton(); + await LoginView.isVisible(); + }); + + it('should tap reset wallet button', async () => { + await LoginView.tapResetWalletButton(); + + await DeleteWalletModal.isVisible(); + }); + it('should delete wallet', async () => { + await DeleteWalletModal.tapIUnderstandButton(); + await DeleteWalletModal.typeDeleteInInputBox(); + await DeleteWalletModal.tapDeleteMyWalletButton(); + await TestHelpers.delay(2000); + await OnboardingView.isVisible(); + }); + }, +); diff --git a/e2e/specs/onboarding-wizard-opt-in.spec.js b/e2e/specs/onboarding-wizard-opt-in.spec.js index 5cad9d44d0b..ff61f9d2820 100644 --- a/e2e/specs/onboarding-wizard-opt-in.spec.js +++ b/e2e/specs/onboarding-wizard-opt-in.spec.js @@ -1,5 +1,6 @@ 'use strict'; import TestHelpers from '../helpers'; +import { Regression } from '../tags'; import OnboardingView from '../pages/Onboarding/OnboardingView'; import OnboardingCarouselView from '../pages/Onboarding/OnboardingCarouselView'; @@ -25,133 +26,136 @@ import { acceptTermOfUse } from '../viewHelper'; const PASSWORD = '12345678'; -describe('Onboarding wizard opt-in, metametrics opt out from settings', () => { - it('should be able to opt-in of the onboarding-wizard', async () => { - await OnboardingCarouselView.isVisible(); - await OnboardingCarouselView.tapOnGetStartedButton(); - - await OnboardingView.isVisible(); - await OnboardingView.tapCreateWallet(); - - await MetaMetricsOptIn.isVisible(); - await MetaMetricsOptIn.tapAgreeButton(); - await acceptTermOfUse(); - - await CreatePasswordView.isVisible(); - }); - it('should be able to create a new wallet', async () => { - await CreatePasswordView.enterPassword(PASSWORD); - await CreatePasswordView.reEnterPassword(PASSWORD); - await CreatePasswordView.tapIUnderstandCheckBox(); - await CreatePasswordView.tapCreatePasswordButton(); - }); - - it('Should skip backup check', async () => { - // Check that we are on the Secure your wallet screen - await ProtectYourWalletView.isVisible(); - await ProtectYourWalletView.tapOnRemindMeLaterButton(); - - await SkipAccountSecurityModal.tapIUnderstandCheckBox(); - await SkipAccountSecurityModal.tapSkipButton(); - await WalletView.isVisible(); - }); - - it('Should dismiss Automatic Security checks screen', async () => { - await TestHelpers.delay(3500); - await EnableAutomaticSecurityChecksView.isVisible(); - await EnableAutomaticSecurityChecksView.tapNoThanks(); - }); - - it('should dismiss the onboarding wizard', async () => { - // dealing with flakiness on bitrise. - await TestHelpers.delay(1000); - try { - await OnboardingWizardModal.isVisible(); - await OnboardingWizardModal.tapNoThanksButton(); - await OnboardingWizardModal.isNotVisible(); - } catch { - // - } - }); - - it('should tap on "Got it" Button in the whats new modal', async () => { - // dealing with flakiness on bitrise. - await TestHelpers.delay(2500); - try { - await WhatsNewModal.isVisible(); - await WhatsNewModal.tapCloseButton(); - } catch { - // - } - }); - - it('should dismiss the protect your wallet modal', async () => { - await ProtectYourWalletModal.isCollapsedBackUpYourWalletModalVisible(); - await TestHelpers.delay(1000); - - await ProtectYourWalletModal.tapRemindMeLaterButton(); - - await SkipAccountSecurityModal.tapIUnderstandCheckBox(); - await SkipAccountSecurityModal.tapSkipButton(); - - await WalletView.isVisible(); - }); - - it('should check that metametrics is enabled in settings', async () => { - await WalletView.tapDrawerButton(); // tapping burger menu - - await DrawerView.isVisible(); - await DrawerView.tapSettings(); - - await SettingsView.tapSecurityAndPrivacy(); - - await SecurityAndPrivacy.scrollToBottomOfView(); - TestHelpers.delay(2000); - await SecurityAndPrivacy.isMetaMetricsToggleOn(); - - TestHelpers.delay(1500); - }); - - it('should disable metametrics', async () => { - await SecurityAndPrivacy.tapMetaMetricsToggle(); - await SecurityAndPrivacy.isMetaMetricsToggleOff(); - - TestHelpers.delay(1500); - await SecurityAndPrivacy.tapOKAlertButton(); - await SecurityAndPrivacy.isMetaMetricsToggleOff(); - }); - - it('should relaunch the app and log in', async () => { - // Relaunch app - await TestHelpers.relaunchApp(); - - await LoginView.isVisible(); - await LoginView.enterPassword(PASSWORD); - - await WalletView.isVisible(); - }); - - it('should dismiss the onboarding wizard after logging in', async () => { - // dealing with flakiness on bitrise. - await TestHelpers.delay(1000); - try { - await OnboardingWizardModal.isVisible(); - await OnboardingWizardModal.tapNoThanksButton(); - await OnboardingWizardModal.isNotVisible(); - } catch { - // - } - }); - - it('should verify metametrics is turned off', async () => { - await WalletView.tapDrawerButton(); // tapping burger menu - - await DrawerView.isVisible(); - await DrawerView.tapSettings(); - - await SettingsView.tapSecurityAndPrivacy(); - - await SecurityAndPrivacy.scrollToBottomOfView(); - await SecurityAndPrivacy.isMetaMetricsToggleOff(); - }); -}); +describe( + Regression('Onboarding wizard opt-in, metametrics opt out from settings'), + () => { + it('should be able to opt-in of the onboarding-wizard', async () => { + await OnboardingCarouselView.isVisible(); + await OnboardingCarouselView.tapOnGetStartedButton(); + + await OnboardingView.isVisible(); + await OnboardingView.tapCreateWallet(); + + await MetaMetricsOptIn.isVisible(); + await MetaMetricsOptIn.tapAgreeButton(); + await acceptTermOfUse(); + + await CreatePasswordView.isVisible(); + }); + it('should be able to create a new wallet', async () => { + await CreatePasswordView.enterPassword(PASSWORD); + await CreatePasswordView.reEnterPassword(PASSWORD); + await CreatePasswordView.tapIUnderstandCheckBox(); + await CreatePasswordView.tapCreatePasswordButton(); + }); + + it('Should skip backup check', async () => { + // Check that we are on the Secure your wallet screen + await ProtectYourWalletView.isVisible(); + await ProtectYourWalletView.tapOnRemindMeLaterButton(); + + await SkipAccountSecurityModal.tapIUnderstandCheckBox(); + await SkipAccountSecurityModal.tapSkipButton(); + await WalletView.isVisible(); + }); + + it('Should dismiss Automatic Security checks screen', async () => { + await TestHelpers.delay(3500); + await EnableAutomaticSecurityChecksView.isVisible(); + await EnableAutomaticSecurityChecksView.tapNoThanks(); + }); + + it('should dismiss the onboarding wizard', async () => { + // dealing with flakiness on bitrise. + await TestHelpers.delay(1000); + try { + await OnboardingWizardModal.isVisible(); + await OnboardingWizardModal.tapNoThanksButton(); + await OnboardingWizardModal.isNotVisible(); + } catch { + // + } + }); + + it('should tap on "Got it" Button in the whats new modal', async () => { + // dealing with flakiness on bitrise. + await TestHelpers.delay(2500); + try { + await WhatsNewModal.isVisible(); + await WhatsNewModal.tapCloseButton(); + } catch { + // + } + }); + + it('should dismiss the protect your wallet modal', async () => { + await ProtectYourWalletModal.isCollapsedBackUpYourWalletModalVisible(); + await TestHelpers.delay(1000); + + await ProtectYourWalletModal.tapRemindMeLaterButton(); + + await SkipAccountSecurityModal.tapIUnderstandCheckBox(); + await SkipAccountSecurityModal.tapSkipButton(); + + await WalletView.isVisible(); + }); + + it('should check that metametrics is enabled in settings', async () => { + await WalletView.tapDrawerButton(); // tapping burger menu + + await DrawerView.isVisible(); + await DrawerView.tapSettings(); + + await SettingsView.tapSecurityAndPrivacy(); + + await SecurityAndPrivacy.scrollToBottomOfView(); + TestHelpers.delay(2000); + await SecurityAndPrivacy.isMetaMetricsToggleOn(); + + TestHelpers.delay(1500); + }); + + it('should disable metametrics', async () => { + await SecurityAndPrivacy.tapMetaMetricsToggle(); + await SecurityAndPrivacy.isMetaMetricsToggleOff(); + + TestHelpers.delay(1500); + await SecurityAndPrivacy.tapOKAlertButton(); + await SecurityAndPrivacy.isMetaMetricsToggleOff(); + }); + + it('should relaunch the app and log in', async () => { + // Relaunch app + await TestHelpers.relaunchApp(); + + await LoginView.isVisible(); + await LoginView.enterPassword(PASSWORD); + + await WalletView.isVisible(); + }); + + it('should dismiss the onboarding wizard after logging in', async () => { + // dealing with flakiness on bitrise. + await TestHelpers.delay(1000); + try { + await OnboardingWizardModal.isVisible(); + await OnboardingWizardModal.tapNoThanksButton(); + await OnboardingWizardModal.isNotVisible(); + } catch { + // + } + }); + + it('should verify metametrics is turned off', async () => { + await WalletView.tapDrawerButton(); // tapping burger menu + + await DrawerView.isVisible(); + await DrawerView.tapSettings(); + + await SettingsView.tapSecurityAndPrivacy(); + + await SecurityAndPrivacy.scrollToBottomOfView(); + await SecurityAndPrivacy.isMetaMetricsToggleOff(); + }); + }, +); diff --git a/e2e/specs/permission-system-delete-wallet.spec.js b/e2e/specs/permission-system-delete-wallet.spec.js index 57ff9336034..b101a7330d0 100644 --- a/e2e/specs/permission-system-delete-wallet.spec.js +++ b/e2e/specs/permission-system-delete-wallet.spec.js @@ -1,5 +1,6 @@ 'use strict'; import TestHelpers from '../helpers'; +import { Regression } from '../tags'; import OnboardingView from '../pages/Onboarding/OnboardingView'; import ProtectYourWalletView from '../pages/Onboarding/ProtectYourWalletView'; @@ -27,91 +28,93 @@ import { const TEST_DAPP = 'https://metamask.github.io/test-dapp/'; const PASSWORD = '12345678'; - -describe('Permission System: Deleting wallet after connecting to a dapp', () => { - beforeEach(() => { - jest.setTimeout(150000); - }); - - it('should import wallet and go to the wallet view', async () => { - await importWalletWithRecoveryPhrase(); - }); - - it('should navigate to browser', async () => { - await TabBarComponent.tapBrowser(); - await Browser.isVisible(); - }); - - it('should connect to the test dapp', async () => { - await TestHelpers.delay(3000); - // Tap on search in bottom navbar - await Browser.tapUrlInputBox(); - await Browser.navigateToURL(TEST_DAPP); - await TestHelpers.delay(3000); - await TestHelpers.tapAtPoint( - BROWSER_SCREEN_ID, - testDappConnectButtonCooridinates, - ); - await ConnectModal.isVisible(); - await ConnectModal.tapConnectButton(); - }); - - it('should navigate to wallet view', async () => { - await TestHelpers.delay(3000); - await TabBarComponent.tapWallet(); - // Check that we are on the browser screen - await WalletView.isVisible(); - }); - - it('should open drawer and log out', async () => { - await WalletView.tapDrawerButton(); - await DrawerView.isVisible(); - await DrawerView.tapLockAccount(); - await DrawerView.tapYesAlertButton(); - await LoginView.isVisible(); - }); - - it('should tap reset wallet button', async () => { - await LoginView.tapResetWalletButton(); - - await DeleteWalletModal.isVisible(); - }); - it('should delete wallet', async () => { - await DeleteWalletModal.tapIUnderstandButton(); - await DeleteWalletModal.typeDeleteInInputBox(); - await DeleteWalletModal.tapDeleteMyWalletButton(); - await OnboardingView.isDeleteWalletToastVisible(); - }); - - it('should create new wallet', async () => { - await OnboardingView.deleteWalletToastisNotVisible(); - await OnboardingView.tapCreateWallet(); - - await CreatePasswordView.isVisible(); - await CreatePasswordView.enterPassword(PASSWORD); - await CreatePasswordView.reEnterPassword(PASSWORD); - await CreatePasswordView.tapIUnderstandCheckBox(); - await CreatePasswordView.tapCreatePasswordButton(); - }); - - it('Should skip backup check', async () => { - await ProtectYourWalletView.isVisible(); - await ProtectYourWalletView.tapOnRemindMeLaterButton(); - - await SkipAccountSecurityModal.tapIUnderstandCheckBox(); - await SkipAccountSecurityModal.tapSkipButton(); - await WalletView.isVisible(); - }); - - it('should go to browser', async () => { - await TabBarComponent.tapBrowser(); - await Browser.isVisible(); - }); - - it('should no longer be connected to the dapp', async () => { - await Browser.tapNetworkAvatarButtonOnBrowser(); - await ConnectedAccountsModal.isNotVisible(); - await NetworkListModal.isVisible(); - await NetworkListModal.tapNetworkListCloseIcon(); - }); -}); +describe( + Regression('Onboarding wizard opt-in, metametrics opt out from settings'), + () => { + beforeEach(() => { + jest.setTimeout(150000); + }); + + it('should import wallet and go to the wallet view', async () => { + await importWalletWithRecoveryPhrase(); + }); + + it('should navigate to browser', async () => { + await TabBarComponent.tapBrowser(); + await Browser.isVisible(); + }); + + it('should connect to the test dapp', async () => { + await TestHelpers.delay(3000); + // Tap on search in bottom navbar + await Browser.tapUrlInputBox(); + await Browser.navigateToURL(TEST_DAPP); + await TestHelpers.delay(3000); + await TestHelpers.tapAtPoint( + BROWSER_SCREEN_ID, + testDappConnectButtonCooridinates, + ); + await ConnectModal.isVisible(); + await ConnectModal.tapConnectButton(); + }); + + it('should navigate to wallet view', async () => { + await TestHelpers.delay(3000); + await TabBarComponent.tapWallet(); + // Check that we are on the browser screen + await WalletView.isVisible(); + }); + + it('should open drawer and log out', async () => { + await WalletView.tapDrawerButton(); + await DrawerView.isVisible(); + await DrawerView.tapLockAccount(); + await DrawerView.tapYesAlertButton(); + await LoginView.isVisible(); + }); + + it('should tap reset wallet button', async () => { + await LoginView.tapResetWalletButton(); + + await DeleteWalletModal.isVisible(); + }); + it('should delete wallet', async () => { + await DeleteWalletModal.tapIUnderstandButton(); + await DeleteWalletModal.typeDeleteInInputBox(); + await DeleteWalletModal.tapDeleteMyWalletButton(); + await OnboardingView.isDeleteWalletToastVisible(); + }); + + it('should create new wallet', async () => { + await OnboardingView.deleteWalletToastisNotVisible(); + await OnboardingView.tapCreateWallet(); + + await CreatePasswordView.isVisible(); + await CreatePasswordView.enterPassword(PASSWORD); + await CreatePasswordView.reEnterPassword(PASSWORD); + await CreatePasswordView.tapIUnderstandCheckBox(); + await CreatePasswordView.tapCreatePasswordButton(); + }); + + it('Should skip backup check', async () => { + await ProtectYourWalletView.isVisible(); + await ProtectYourWalletView.tapOnRemindMeLaterButton(); + + await SkipAccountSecurityModal.tapIUnderstandCheckBox(); + await SkipAccountSecurityModal.tapSkipButton(); + await WalletView.isVisible(); + }); + + it('should go to browser', async () => { + await TabBarComponent.tapBrowser(); + await Browser.isVisible(); + }); + + it('should no longer be connected to the dapp', async () => { + await Browser.tapNetworkAvatarButtonOnBrowser(); + await ConnectedAccountsModal.isNotVisible(); + await NetworkListModal.isVisible(); + await NetworkListModal.tapNetworkListCloseIcon(); + }); + }, +); diff --git a/e2e/specs/permission-system-removing-imported-account.spec.js b/e2e/specs/permission-system-removing-imported-account.spec.js index 2b6a275cd64..acd4e5c1751 100644 --- a/e2e/specs/permission-system-removing-imported-account.spec.js +++ b/e2e/specs/permission-system-removing-imported-account.spec.js @@ -1,6 +1,6 @@ 'use strict'; import TestHelpers from '../helpers'; - +import { Smoke } from '../tags'; import WalletView from '../pages/WalletView'; import ImportAccountView from '../pages/ImportAccountView'; import TabBarComponent from '../pages/TabBarComponent'; @@ -24,108 +24,110 @@ import { } from '../viewHelper'; const TEST_DAPP = 'https://metamask.github.io/test-dapp/'; -const GOERLI = 'Goerli Test Network'; +const SEPOLIA = 'Sepolia Test Network'; const accountPrivateKey = Accounts.getAccountPrivateKey(); - -describe('Permission System Test: Revoking accounts after connecting to a dapp', () => { - beforeEach(() => { - jest.setTimeout(150000); - }); - - it('should import wallet and go to the wallet view', async () => { - await importWalletWithRecoveryPhrase(); - }); - - it('should navigate to browser', async () => { - await TestHelpers.delay(2000); - await TabBarComponent.tapBrowser(); - await Browser.isVisible(); - }); - - it('should connect to the test dapp', async () => { - await TestHelpers.delay(3000); - await Browser.tapUrlInputBox(); - await Browser.navigateToURL(TEST_DAPP); - await TestHelpers.delay(3000); - await TestHelpers.tapAtPoint( - BROWSER_SCREEN_ID, - testDappConnectButtonCooridinates, - ); - await ConnectModal.isVisible(); - }); - - it('should go to multiconnect in the connect account modal', async () => { - await ConnectModal.tapConnectMultipleAccountsButton(); - }); - - it('should import account', async () => { - await ConnectModal.tapImportAccountButton(); - await ImportAccountView.isVisible(); - await ImportAccountView.enterPrivateKey(accountPrivateKey.keys); - await ImportAccountView.isImportSuccessSreenVisible(); - await ImportAccountView.tapCloseButtonOnImportSuccess(); - }); - - it('should connect multiple accounts to a dapp', async () => { - await ConnectModal.tapSelectAllButton(); - - await ConnectModal.tapAccountConnectMultiSelectButton(); - }); - - it('should switch to Goreli', async () => { - await Browser.tapNetworkAvatarButtonOnBrowser(); - await ConnectedAccountsModal.tapNetworksPicker(); - await NetworkListModal.changeNetwork(GOERLI); - }); - - it('should dismiss the network education modal', async () => { - await NetworkEducationModal.isVisible(); - await NetworkEducationModal.tapGotItButton(); - await NetworkEducationModal.isNotVisible(); - }); - - it('should set the imported account as primary account', async () => { - await TestHelpers.delay(1500); - await ConnectedAccountsModal.tapToSetAsPrimaryAccount(); - }); - - it('should submit a EIP1559 transaction ', async () => { - await TestHelpers.swipe(BROWSER_SCREEN_ID, 'up', 'slow', 0.1); - await TestHelpers.tapAtPoint( - BROWSER_SCREEN_ID, - testDappSendEIP1559ButtonCoordinates, - ); - - await TransactionConfirmationView.isBalanceVisible(); - await TestHelpers.tapByText('Confirm', 1); - await TransactionConfirmationView.isBalanceNotVisible(); - }); - - it('should navigate to wallet view', async () => { - await TabBarComponent.tapWallet(); - await WalletView.isVisible(); - }); - - it('should remove imported account', async () => { - // Wait for page to load - await WalletView.tapIdenticon(); - await AccountListView.isVisible(); - await AccountListView.longPressImportedAccount(); - await AccountListView.tapYesToRemoveImportedAccountAlertButton(); - await AccountListView.accountNameNotVisible('Account 2'); - }); - - it('should return to browser', async () => { - await AccountListView.swipeToDimssAccountsModal(); - await TabBarComponent.tapBrowser(); - // Check that we are on the browser screen - await Browser.isVisible(); - }); - - it('imported account is not visible', async () => { - await Browser.tapNetworkAvatarButtonOnBrowser(); - await ConnectedAccountsModal.isVisible(); - await AccountListView.accountNameNotVisible('Account 2'); - }); -}); +describe( + Smoke('Permission System Test: Revoking accounts after connecting to a dapp'), + () => { + beforeEach(() => { + jest.setTimeout(150000); + }); + + it('should import wallet and go to the wallet view', async () => { + await importWalletWithRecoveryPhrase(); + }); + + it('should navigate to browser', async () => { + await TestHelpers.delay(2000); + await TabBarComponent.tapBrowser(); + await Browser.isVisible(); + }); + + it('should connect to the test dapp', async () => { + await TestHelpers.delay(3000); + await Browser.tapUrlInputBox(); + await Browser.navigateToURL(TEST_DAPP); + await TestHelpers.delay(3000); + await TestHelpers.tapAtPoint( + BROWSER_SCREEN_ID, + testDappConnectButtonCooridinates, + ); + await ConnectModal.isVisible(); + }); + + it('should go to multiconnect in the connect account modal', async () => { + await ConnectModal.tapConnectMultipleAccountsButton(); + }); + + it('should import account', async () => { + await ConnectModal.tapImportAccountButton(); + await ImportAccountView.isVisible(); + await ImportAccountView.enterPrivateKey(accountPrivateKey.keys); + await ImportAccountView.isImportSuccessSreenVisible(); + await ImportAccountView.tapCloseButtonOnImportSuccess(); + }); + + it('should connect multiple accounts to a dapp', async () => { + await ConnectModal.tapSelectAllButton(); + + await ConnectModal.tapAccountConnectMultiSelectButton(); + }); + + it('should switch to Sepolia', async () => { + await Browser.tapNetworkAvatarButtonOnBrowser(); + await ConnectedAccountsModal.tapNetworksPicker(); + await NetworkListModal.changeNetwork(SEPOLIA); + }); + + it('should dismiss the network education modal', async () => { + await NetworkEducationModal.isVisible(); + await NetworkEducationModal.tapGotItButton(); + await NetworkEducationModal.isNotVisible(); + }); + + it('should set the imported account as primary account', async () => { + await TestHelpers.delay(1500); + await ConnectedAccountsModal.tapToSetAsPrimaryAccount(); + }); + + it('should submit a EIP1559 transaction ', async () => { + await TestHelpers.swipe(BROWSER_SCREEN_ID, 'up', 'slow', 0.1); + await TestHelpers.tapAtPoint( + BROWSER_SCREEN_ID, + testDappSendEIP1559ButtonCoordinates, + ); + + await TransactionConfirmationView.isBalanceVisible(); + await TestHelpers.tapByText('Confirm', 1); + await TransactionConfirmationView.isBalanceNotVisible(); + }); + + it('should navigate to wallet view', async () => { + await TabBarComponent.tapWallet(); + await WalletView.isVisible(); + }); + + it('should remove imported account', async () => { + // Wait for page to load + await WalletView.tapIdenticon(); + await AccountListView.isVisible(); + await AccountListView.longPressImportedAccount(); + await AccountListView.tapYesToRemoveImportedAccountAlertButton(); + await AccountListView.accountNameNotVisible('Account 2'); + }); + + it('should return to browser', async () => { + await AccountListView.swipeToDimssAccountsModal(); + await TabBarComponent.tapBrowser(); + // Check that we are on the browser screen + await Browser.isVisible(); + }); + + it('imported account is not visible', async () => { + await Browser.tapNetworkAvatarButtonOnBrowser(); + await ConnectedAccountsModal.isVisible(); + await AccountListView.accountNameNotVisible('Account 2'); + }); + }, +); diff --git a/e2e/specs/permission-system-revoke-single-account.spec.js b/e2e/specs/permission-system-revoke-single-account.spec.js index de02367ab41..7c6428fe043 100644 --- a/e2e/specs/permission-system-revoke-single-account.spec.js +++ b/e2e/specs/permission-system-revoke-single-account.spec.js @@ -1,5 +1,6 @@ 'use strict'; import TestHelpers from '../helpers'; +import { Regression } from '../tags'; import OnboardingView from '../pages/Onboarding/OnboardingView'; import OnboardingCarouselView from '../pages/Onboarding/OnboardingCarouselView'; @@ -29,7 +30,7 @@ import { const TEST_DAPP = 'https://metamask.github.io/test-dapp/'; const PASSWORD = '12345678'; -describe('Revoke Single Account after connecting to a dapp', () => { +describe(Regression('Revoke Single Account after connecting to a dapp'), () => { beforeEach(() => { jest.setTimeout(150000); }); diff --git a/e2e/specs/permission-system-revoking-multiple-accounts.spec.js b/e2e/specs/permission-system-revoking-multiple-accounts.spec.js index 28e13fd4772..6cf94b06f9c 100644 --- a/e2e/specs/permission-system-revoking-multiple-accounts.spec.js +++ b/e2e/specs/permission-system-revoking-multiple-accounts.spec.js @@ -1,5 +1,6 @@ 'use strict'; import TestHelpers from '../helpers'; +import { Regression } from '../tags'; import Browser from '../pages/Drawer/Browser'; import { BROWSER_SCREEN_ID } from '../../wdio/screen-objects/testIDs/BrowserScreen/BrowserScreen.testIds'; @@ -19,81 +20,86 @@ import { const SUSHI_SWAP = 'https://app.sushi.com/swap'; const TEST_DAPP = 'https://metamask.github.io/test-dapp/'; -describe('Connecting to multiple dapps and revoking permission on one but staying connected to the other', () => { - beforeEach(() => { - jest.setTimeout(150000); - }); - - it('should import wallet and go to the wallet view', async () => { - await importWalletWithRecoveryPhrase(); - }); - - it('should navigate to browser', async () => { - await TabBarComponent.tapBrowser(); - // Check that we are on the browser screen - await Browser.isVisible(); - }); - - it('should connect to sushi swap dapp', async () => { - await TestHelpers.delay(3000); - // Tap on search in bottom navbar - await Browser.tapUrlInputBox(); - await Browser.navigateToURL(SUSHI_SWAP); - await ConnectModal.isVisible(); - await ConnectModal.tapConnectButton(); - await Browser.isAccountToastVisible('Account 1'); - }); - - it('should go to the test dapp', async () => { - // Tap on search in bottom navbar - await Browser.tapOpenAllTabsButton(); - await Browser.tapOpenNewTabButton(); - await Browser.tapUrlInputBox(); - await Browser.navigateToURL(TEST_DAPP); - await Browser.waitForBrowserPageToLoad(); - await TestHelpers.tapAtPoint( - BROWSER_SCREEN_ID, - testDappConnectButtonCooridinates, - ); - await ConnectModal.isVisible(); - }); - - it('should go to multiconnect in the connect account modal', async () => { - await ConnectModal.tapConnectMultipleAccountsButton(); - }); - - it('should connect with multiple accounts', async () => { - // Wait for page to load - await ConnectModal.tapCreateAccountButton(); - await AccountListView.isNewAccountNameVisible(); - await AccountListView.tapAccountByName('Account 2'); - - await ConnectModal.tapAccountConnectMultiSelectButton(); - }); - - it('should revoke accounts', async () => { - await Browser.tapNetworkAvatarButtonOnBrowser(); - await ConnectedAccountsModal.tapPermissionsButton(); - await TestHelpers.delay(1500); - await ConnectedAccountsModal.tapRevokeAllButton(); - Browser.isRevokeAllAccountToastVisible(); - }); - - it('should no longer be connected to the test dapp', async () => { - await Browser.tapNetworkAvatarButtonOnBrowser(); - await ConnectedAccountsModal.isNotVisible(); - await NetworkListModal.tapNetworkListCloseIcon(); - }); - - it('should open sushi swap dapp', async () => { - // Wait for page to load - await Browser.tapOpenAllTabsButton(); - await TestHelpers.tapByText('app.sushi.com'); - }); - - it('should still be connected to sushi swap', async () => { - // Wait for page to load - await Browser.tapNetworkAvatarButtonOnBrowser(); - await ConnectedAccountsModal.isVisible(); - }); -}); +describe( + Regression( + 'Connecting to multiple dapps and revoking permission on one but staying connected to the other', + ), + () => { + beforeEach(() => { + jest.setTimeout(150000); + }); + + it('should import wallet and go to the wallet view', async () => { + await importWalletWithRecoveryPhrase(); + }); + + it('should navigate to browser', async () => { + await TabBarComponent.tapBrowser(); + // Check that we are on the browser screen + await Browser.isVisible(); + }); + + it('should connect to sushi swap dapp', async () => { + await TestHelpers.delay(3000); + // Tap on search in bottom navbar + await Browser.tapUrlInputBox(); + await Browser.navigateToURL(SUSHI_SWAP); + await ConnectModal.isVisible(); + await ConnectModal.tapConnectButton(); + await Browser.isAccountToastVisible('Account 1'); + }); + + it('should go to the test dapp', async () => { + // Tap on search in bottom navbar + await Browser.tapOpenAllTabsButton(); + await Browser.tapOpenNewTabButton(); + await Browser.tapUrlInputBox(); + await Browser.navigateToURL(TEST_DAPP); + await Browser.waitForBrowserPageToLoad(); + await TestHelpers.tapAtPoint( + BROWSER_SCREEN_ID, + testDappConnectButtonCooridinates, + ); + await ConnectModal.isVisible(); + }); + + it('should go to multiconnect in the connect account modal', async () => { + await ConnectModal.tapConnectMultipleAccountsButton(); + }); + + it('should connect with multiple accounts', async () => { + // Wait for page to load + await ConnectModal.tapCreateAccountButton(); + await AccountListView.isNewAccountNameVisible(); + await AccountListView.tapAccountByName('Account 2'); + + await ConnectModal.tapAccountConnectMultiSelectButton(); + }); + + it('should revoke accounts', async () => { + await Browser.tapNetworkAvatarButtonOnBrowser(); + await ConnectedAccountsModal.tapPermissionsButton(); + await TestHelpers.delay(1500); + await ConnectedAccountsModal.tapRevokeAllButton(); + Browser.isRevokeAllAccountToastVisible(); + }); + + it('should no longer be connected to the test dapp', async () => { + await Browser.tapNetworkAvatarButtonOnBrowser(); + await ConnectedAccountsModal.isNotVisible(); + await NetworkListModal.tapNetworkListCloseIcon(); + }); + + it('should open sushi swap dapp', async () => { + // Wait for page to load + await Browser.tapOpenAllTabsButton(); + await TestHelpers.tapByText('app.sushi.com'); + }); + + it('should still be connected to sushi swap', async () => { + // Wait for page to load + await Browser.tapNetworkAvatarButtonOnBrowser(); + await ConnectedAccountsModal.isVisible(); + }); + }, +); diff --git a/e2e/specs/request-token-flow.spec.js b/e2e/specs/request-token-flow.spec.js index 1c1a9416a9b..8e3a1bb10de 100644 --- a/e2e/specs/request-token-flow.spec.js +++ b/e2e/specs/request-token-flow.spec.js @@ -1,4 +1,6 @@ 'use strict'; +import { Smoke } from '../tags'; + import OnboardingView from '../pages/Onboarding/OnboardingView'; import OnboardingCarouselView from '../pages/Onboarding/OnboardingCarouselView'; import ProtectYourWalletView from '../pages/Onboarding/ProtectYourWalletView'; @@ -24,7 +26,7 @@ import { acceptTermOfUse } from '../viewHelper'; const SAI_CONTRACT_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; const PASSWORD = '12345678'; -describe('Request Token Flow', () => { +describe(Smoke('Request Token Flow'), () => { beforeEach(() => { jest.setTimeout(150000); }); diff --git a/e2e/specs/send-ERC-token.spec.js b/e2e/specs/send-ERC-token.spec.js index ca3f7138f80..255c6d35b83 100644 --- a/e2e/specs/send-ERC-token.spec.js +++ b/e2e/specs/send-ERC-token.spec.js @@ -1,4 +1,6 @@ 'use strict'; +import { Smoke } from '../tags'; + import TestHelpers from '../helpers'; import WalletView from '../pages/WalletView'; @@ -16,7 +18,7 @@ const AVAX_URL = 'https://api.avax-test.network/ext/C/rpc'; const TOKEN_ADDRESS = '0x5425890298aed601595a70AB815c96711a31Bc65'; const SEND_ADDRESS = '0xebe6CcB6B55e1d094d9c58980Bc10Fed69932cAb'; -describe('Send ERC Token', () => { +describe(Smoke('Send ERC Token'), () => { beforeAll(async () => { await importWalletWithRecoveryPhrase(); }); diff --git a/e2e/specs/start-exploring.spec.js b/e2e/specs/start-exploring.spec.js index c40541fbaa2..ac4dcfbb04a 100644 --- a/e2e/specs/start-exploring.spec.js +++ b/e2e/specs/start-exploring.spec.js @@ -1,4 +1,5 @@ 'use strict'; +import { Smoke } from '../tags'; import TestHelpers from '../helpers'; @@ -21,7 +22,7 @@ import { acceptTermOfUse } from '../viewHelper'; const ACCOUNT = 'Test Account One'; const PASSWORD = '12345678'; -describe('Start Exploring', () => { +describe(Smoke('Start Exploring'), () => { beforeEach(() => { jest.setTimeout(150000); }); diff --git a/e2e/specs/wallet-tests.spec.js b/e2e/specs/wallet-tests.spec.js index f338bdbbde9..b65f3c51d59 100644 --- a/e2e/specs/wallet-tests.spec.js +++ b/e2e/specs/wallet-tests.spec.js @@ -1,4 +1,6 @@ 'use strict'; +import { Smoke } from '../tags'; + import TestHelpers from '../helpers'; import WalletView from '../pages/WalletView'; import AccountListView from '../pages/AccountListView'; @@ -13,7 +15,7 @@ import { importWalletWithRecoveryPhrase } from '../viewHelper'; import Accounts from '../../wdio/helpers/Accounts'; import Collectibles from '../resources/collectibles.json'; -describe('Wallet Tests', () => { +describe(Smoke('Wallet Tests'), () => { const GOERLI = 'Goerli Test Network'; const ETHEREUM = 'Ethereum Main Network'; diff --git a/e2e/tags.js b/e2e/tags.js new file mode 100644 index 00000000000..7e95c4c8713 --- /dev/null +++ b/e2e/tags.js @@ -0,0 +1,8 @@ +const tags = { + regression: 'Regression', + smoke: 'Smoke', +}; +const Smoke = (testName) => `${tags.smoke} ${testName}`; +const Regression = (testName) => `${tags.regression} ${testName}`; + +export { Smoke, Regression }; From ca85e7e222945cbdeec643b6e4b6226e805d9466 Mon Sep 17 00:00:00 2001 From: Brendan Kirby <124314512+bkirb@users.noreply.github.com> Date: Thu, 4 May 2023 17:09:55 -0700 Subject: [PATCH 11/20] Fix readme typos (#6275) Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8747c91ee82..b09b8937a92 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,7 @@ For local testing, the wallet is created using the secret recovery phrase from t ##### iOS All tests live within the e2e/specs folder. -Prequisites for running tests: +Prerequisites for running tests: - Make sure to install `detox-cli` by referring to the instructions mentioned [here](https://wix.github.io/Detox/docs/introduction/getting-started/#detox-prerequisites). - Additionally, install `applesimutils` by following the guidelines provided [here](https://github.com/wix/AppleSimulatorUtils). - Before running any tests, it's recommended to refer to the `iOS section` above and check the latest simulator device specified under `Install the correct simulator`. @@ -291,7 +291,7 @@ To get a better understanding of the internal architecture of this app take a lo ### Storybook -We have begun documenting our components using storybook please read the [Documentation Guidelines](./storybook/DOCUMENTATION_GUIDELINES.md) to get up and running. +We have begun documenting our components using Storybook. Please read the [Documentation Guidelines](./storybook/DOCUMENTATION_GUIDELINES.md) to get up and running. ### Other Docs From 6541a90429a0b6ff18431e38021e62e7e0df833f Mon Sep 17 00:00:00 2001 From: witmicko Date: Fri, 5 May 2023 01:16:03 +0100 Subject: [PATCH 12/20] sturdier check (#5866) * sturdier check * apply feedback * apply feedback * unit test * check phishing and deeplinks * feedback * resolve * url check * more tests --------- Co-authored-by: Curtis David --- .../UI/CollectibleOverview/index.js | 75 +++++++++++-------- app/util/linkCheck.test.ts | 47 ++++++++++++ app/util/linkCheck.ts | 35 +++++++++ package.json | 2 + yarn.lock | 10 +++ 5 files changed, 138 insertions(+), 31 deletions(-) create mode 100644 app/util/linkCheck.test.ts create mode 100644 app/util/linkCheck.ts diff --git a/app/components/UI/CollectibleOverview/index.js b/app/components/UI/CollectibleOverview/index.js index 2162e5cbe2a..5028fc1e562 100644 --- a/app/components/UI/CollectibleOverview/index.js +++ b/app/components/UI/CollectibleOverview/index.js @@ -13,6 +13,7 @@ import { SafeAreaView, TouchableWithoutFeedback, } from 'react-native'; + import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { baseStyles } from '../../../styles/common'; @@ -28,6 +29,7 @@ import { toLocaleDate } from '../../../util/date'; import { renderFromWei } from '../../../util/number'; import { renderShortAddress } from '../../../util/address'; import { isMainNet } from '../../../util/networks'; +import { isLinkSafe } from '../../../util/linkCheck'; import etherscanLink from '@metamask/etherscan-link'; import { addFavoriteCollectible, @@ -131,6 +133,10 @@ const createStyles = (colors) => }, }); +const FieldType = { + Link: 'Link', + Text: 'Text', +}; /** * View that displays the information of a specific ERC-721 Token */ @@ -166,11 +172,10 @@ const CollectibleOverview = ({ }, [collectible.description]); const renderCollectibleInfoRow = useCallback( - (key, value, onPress) => { + ({ key, value, onPress, type }) => { if (!value) return null; - - if (value.toLowerCase().includes('javascript')) { - return null; + if (type === FieldType.Link) { + if (!isLinkSafe(value)) return null; } return ( @@ -203,42 +208,50 @@ const CollectibleOverview = ({ ); const renderCollectibleInfo = () => [ - renderCollectibleInfoRow( - strings('collectible.collectible_token_standard'), - collectible?.standard, - ), - renderCollectibleInfoRow( - strings('collectible.collectible_last_sold'), - collectible?.lastSale?.event_timestamp && + renderCollectibleInfoRow({ + key: strings('collectible.collectible_token_standard'), + value: collectible?.standard, + type: FieldType.Text, + }), + renderCollectibleInfoRow({ + key: strings('collectible.collectible_last_sold'), + value: + collectible?.lastSale?.event_timestamp && toLocaleDate( new Date(collectible?.lastSale?.event_timestamp), ).toString(), - ), - renderCollectibleInfoRow( - strings('collectible.collectible_last_price_sold'), - collectible?.lastSale?.total_price && + type: FieldType.Text, + }), + renderCollectibleInfoRow({ + key: strings('collectible.collectible_last_price_sold'), + value: + collectible?.lastSale?.total_price && `${renderFromWei(collectible?.lastSale?.total_price)} ETH`, - ), - renderCollectibleInfoRow( - strings('collectible.collectible_source'), - collectible?.imageOriginal, - () => openLink(collectible?.imageOriginal), - ), - renderCollectibleInfoRow( - strings('collectible.collectible_link'), - collectible?.externalLink, - () => openLink(collectible?.externalLink), - ), - renderCollectibleInfoRow( - strings('collectible.collectible_asset_contract'), - renderShortAddress(collectible?.address), - () => { + type: FieldType.Text, + }), + renderCollectibleInfoRow({ + key: strings('collectible.collectible_source'), + value: collectible?.imageOriginal, + onPress: () => openLink(collectible?.imageOriginal), + type: FieldType.Link, + }), + renderCollectibleInfoRow({ + key: strings('collectible.collectible_link'), + value: collectible?.externalLink, + onPress: () => openLink(collectible?.externalLink), + type: FieldType.Link, + }), + renderCollectibleInfoRow({ + key: strings('collectible.collectible_asset_contract'), + value: renderShortAddress(collectible?.address), + onPress: () => { if (isMainNet(chainId)) openLink( etherscanLink.createTokenTrackerLink(collectible?.address, chainId), ); }, - ), + type: FieldType.Text, + }), ]; const collectibleToFavorites = useCallback(() => { diff --git a/app/util/linkCheck.test.ts b/app/util/linkCheck.test.ts new file mode 100644 index 00000000000..ffd18494b6d --- /dev/null +++ b/app/util/linkCheck.test.ts @@ -0,0 +1,47 @@ +/* eslint-disable no-script-url */ +import isLinkSafe from './linkCheck'; + +jest.mock('../core/Engine', () => ({ + context: { + PhishingController: { + maybeUpdateState: jest.fn(), + test: jest.fn((url: string) => { + if (url === 'phishing.com') return { result: true }; + return { result: false }; + }), + }, + }, +})); + +describe('linkCheck', () => { + it('should correctly check links for safety', () => { + expect(isLinkSafe('htps://ww.example.com/')).toEqual(false); + expect(isLinkSafe('https://ww.example.com/')).toEqual(true); + expect(isLinkSafe('http://example com/page?id=123')).toEqual(false); + expect(isLinkSafe('https://www.example.com/')).toEqual(true); + expect(isLinkSafe('http://phishing.com')).toEqual(false); + expect( + isLinkSafe( + 'https://metamask.app.link/send/pay-Contract-Address@chain-id/transfer?address=Receiver-Address&uint256=1e21', + ), + ).toEqual(false); + + expect(isLinkSafe('javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('j avascript:alert(1);')).toEqual(false); + expect(isLinkSafe(' javascript:alert(1);&tab;')).toEqual(false); + expect(isLinkSafe('javas\x00cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x07cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x0Dcript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x0Acript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x08cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x02cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x03cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x04cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x01cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x05cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x0Bcript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x09cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x06cript:javascript:alert(1)')).toEqual(false); + expect(isLinkSafe('javas\x0Ccript:javascript:alert(1)')).toEqual(false); + }); +}); diff --git a/app/util/linkCheck.ts b/app/util/linkCheck.ts new file mode 100644 index 00000000000..caaf4afc701 --- /dev/null +++ b/app/util/linkCheck.ts @@ -0,0 +1,35 @@ +import Url from 'url-parse'; +import isUrl from 'is-url'; +import { PhishingController as PhishingControllerClass } from '@metamask/phishing-controller'; +import Engine from '../core/Engine'; +const ALLOWED_PROTOCOLS = ['http:', 'https:']; +const DENYLISTED_DOMAINS = ['metamask.app.link']; + +const isAllowedProtocol = (protocol: string): boolean => + ALLOWED_PROTOCOLS.includes(protocol); + +const isAllowedHostname = (hostname: string): boolean => { + const { PhishingController } = Engine.context as { + PhishingController: PhishingControllerClass; + }; + PhishingController.maybeUpdateState(); + const phishingControllerTestResult = PhishingController.test(hostname); + + return !( + phishingControllerTestResult.result || DENYLISTED_DOMAINS.includes(hostname) + ); +}; + +export const isLinkSafe = (link: string): boolean => { + try { + const url = new Url(link); + const { protocol, hostname, href } = url; + return ( + isUrl(href) && isAllowedProtocol(protocol) && isAllowedHostname(hostname) + ); + } catch (err) { + return false; + } +}; + +export default isLinkSafe; diff --git a/package.json b/package.json index 51dd0759c6c..939cf1ac249 100644 --- a/package.json +++ b/package.json @@ -339,6 +339,7 @@ "@storybook/react-native": "^5.3.25", "@testing-library/react-hooks": "^8.0.1", "@types/enzyme": "^3.10.9", + "@types/is-url": "^1.2.30", "@types/jest": "^27.0.1", "@types/react": "^17.0.11", "@types/react-native": "^0.64.10", @@ -347,6 +348,7 @@ "@types/react-native-vector-icons": "^6.4.8", "@types/react-native-video": "^5.0.13", "@types/redux-mock-store": "^1.0.3", + "@types/url-parse": "^1.4.8", "@typescript-eslint/eslint-plugin": "^4.20.0", "@typescript-eslint/parser": "^4.20.0", "@wdio/appium-service": "^7.19.1", diff --git a/yarn.lock b/yarn.lock index ffa2251f6ff..0f951f52b8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5574,6 +5574,11 @@ resolved "https://registry.yarnpkg.com/@types/is-glob/-/is-glob-4.0.2.tgz#c243dd0d09eac2992130142419ff2308ffd988bf" integrity sha512-4j5G9Y5jljDSICQ1R2f/Rcyoj6DZmYGneny+p/cDkjep0rkqNg0W73Ty0bVjMUTZgLXHf8oiMjg1XC3CDwCz+g== +"@types/is-url@^1.2.30": + version "1.2.30" + resolved "https://registry.yarnpkg.com/@types/is-url/-/is-url-1.2.30.tgz#85567e8bee4fee69202bc3448f9fb34b0d56c50a" + integrity sha512-AnlNFwjzC8XLda5VjRl4ItSd8qp8pSNowvsut0WwQyBWHpOxjxRJm8iO6uETWqEyLdYdb9/1j+Qd9gQ4l5I4fw== + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" @@ -5952,6 +5957,11 @@ resolved "https://registry.yarnpkg.com/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz#9bd0b47f26b5a3151be21ba4ce9f5fa457c5f190" integrity sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ== +"@types/url-parse@^1.4.8": + version "1.4.8" + resolved "https://registry.yarnpkg.com/@types/url-parse/-/url-parse-1.4.8.tgz#c3825047efbca1295b7f1646f38203d9145130d6" + integrity sha512-zqqcGKyNWgTLFBxmaexGUKQyWqeG7HjXj20EuQJSJWwXe54BjX0ihIo5cJB9yAQzH8dNugJ9GvkBYMjPXs/PJw== + "@types/uuid@8.3.1", "@types/uuid@^8.3.0": version "8.3.1" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f" From eb3eaad68fa099faed00542036db99dc10ea7ecc Mon Sep 17 00:00:00 2001 From: Chris Wilcox Date: Thu, 4 May 2023 18:10:20 -0700 Subject: [PATCH 13/20] Appium/fix reports video failures (#6343) * try/catch error generating reports * clean up for reports * Update SendToken.feature * delete feature, was renamed --- .../Accounts/CreatingWalletAccount.feature | 2 +- .../Accounts/ImportingAccount.feature | 4 +- wdio/features/BrowserFlow/AddFavorite.feature | 2 +- wdio/features/BrowserFlow/InvalidURL.feature | 2 +- .../BrowserFlow/PhishingDetection.feature | 2 +- .../Onboarding/CreateNewWallet.feature | 2 +- .../Onboarding/OnboardingCarousel.feature | 2 +- .../features/Wallet/ImportCustomToken.feature | 3 +- wdio/features/Wallet/SendToken.feature | 3 - wdio/utils/generateTestReports.js | 60 +++++++++++-------- 10 files changed, 44 insertions(+), 38 deletions(-) diff --git a/wdio/features/Accounts/CreatingWalletAccount.feature b/wdio/features/Accounts/CreatingWalletAccount.feature index 262ce5c847e..bd4f5d2d4be 100644 --- a/wdio/features/Accounts/CreatingWalletAccount.feature +++ b/wdio/features/Accounts/CreatingWalletAccount.feature @@ -1,6 +1,6 @@ @androidApp @smoke -Feature: Creating account in wallet +Feature: Create Account Scenario: Import wallet Given the app displayed the splash animation diff --git a/wdio/features/Accounts/ImportingAccount.feature b/wdio/features/Accounts/ImportingAccount.feature index 14957c4f29b..6799eaafb1d 100644 --- a/wdio/features/Accounts/ImportingAccount.feature +++ b/wdio/features/Accounts/ImportingAccount.feature @@ -1,8 +1,8 @@ @androidApp @regression -Feature: Importing account in wallet +Feature: Import Aaccount - Scenario: Import wallet + Scenario: Import Wallet Given the app displayed the splash animation And I have imported my wallet And I tap No Thanks on the Enable security check screen diff --git a/wdio/features/BrowserFlow/AddFavorite.feature b/wdio/features/BrowserFlow/AddFavorite.feature index da44bdc2247..448cff33c93 100644 --- a/wdio/features/BrowserFlow/AddFavorite.feature +++ b/wdio/features/BrowserFlow/AddFavorite.feature @@ -1,6 +1,6 @@ @androidApp @smoke -Feature: This feature file covers adding favorite websites in browser. +Feature: Browser Add Favorite Scenario: Adding browser Favorites Add, click and delete favorites. Display favorites in the Favorites tab of home.metamask.io diff --git a/wdio/features/BrowserFlow/InvalidURL.feature b/wdio/features/BrowserFlow/InvalidURL.feature index 1f00baf5944..4f65eb616c7 100644 --- a/wdio/features/BrowserFlow/InvalidURL.feature +++ b/wdio/features/BrowserFlow/InvalidURL.feature @@ -1,6 +1,6 @@ @androidApp @smoke -Feature: This feature file covers invalid url functionality in the browser. +Feature: Browser Invalid URL Scenario: Searching an invalid url and prompts the user with an error message Given the app displayed the splash animation diff --git a/wdio/features/BrowserFlow/PhishingDetection.feature b/wdio/features/BrowserFlow/PhishingDetection.feature index e23bc049739..9aedc84400e 100644 --- a/wdio/features/BrowserFlow/PhishingDetection.feature +++ b/wdio/features/BrowserFlow/PhishingDetection.feature @@ -1,6 +1,6 @@ @androidApp @smoke -Feature: This feature file covers phishing detection functionality the browser. +Feature: Browser Phishing Detection Scenario: Visiting a malicious website prompts the user with the phishing detection warning Given the app displayed the splash animation diff --git a/wdio/features/Onboarding/CreateNewWallet.feature b/wdio/features/Onboarding/CreateNewWallet.feature index f7469c6df39..32c2761caeb 100644 --- a/wdio/features/Onboarding/CreateNewWallet.feature +++ b/wdio/features/Onboarding/CreateNewWallet.feature @@ -1,6 +1,6 @@ @androidApp @regression -Feature: New wallet flow +Feature: Create New Wallet Scenario: Onboarding New walllet User opens the app for first time and creates a new wallet. diff --git a/wdio/features/Onboarding/OnboardingCarousel.feature b/wdio/features/Onboarding/OnboardingCarousel.feature index 8c7f07894ff..59f9cf6879b 100644 --- a/wdio/features/Onboarding/OnboardingCarousel.feature +++ b/wdio/features/Onboarding/OnboardingCarousel.feature @@ -1,6 +1,6 @@ @androidApp @smoke -Feature: Onboarding +Feature: Onboarding Carousel Users can install MetaMask mobile app from the device app store and read the onboarding carousel Scenario: New app install setup on a mobile device diff --git a/wdio/features/Wallet/ImportCustomToken.feature b/wdio/features/Wallet/ImportCustomToken.feature index 1af44ba0159..18408955cca 100644 --- a/wdio/features/Wallet/ImportCustomToken.feature +++ b/wdio/features/Wallet/ImportCustomToken.feature @@ -1,5 +1,6 @@ @androidApp -Feature: Adding a custom token to your wallet +@smoke +Feature: Import Custom Token Scenario: Import wallet Given the app displayed the splash animation diff --git a/wdio/features/Wallet/SendToken.feature b/wdio/features/Wallet/SendToken.feature index bb8906b5751..ed46deb49b6 100644 --- a/wdio/features/Wallet/SendToken.feature +++ b/wdio/features/Wallet/SendToken.feature @@ -39,8 +39,6 @@ Feature: Sending Native and ERC Tokens When I tap button "Send" on Confirm Amount view # Then the transaction is submitted with Transaction Complete! toast appearing And I am taken to the token overview screen - - Examples: | TOKEN_NAME | TOKEN_SYMBOL | AMOUNT | Address | | ChainLink Token | LINK | 0.002 | 0x2990079bcdEe240329a520d2444386FC119da21a | @@ -59,7 +57,6 @@ Feature: Sending Native and ERC Tokens When I tap button "Send" on Confirm Amount view # Then the transaction is submitted with Transaction Complete! toast appearing And Sending token takes me to main wallet view - Examples: | TOKEN | AMOUNT | Address | | SepoliaETH | 0.002 | 0x2990079bcdEe240329a520d2444386FC119da21a | diff --git a/wdio/utils/generateTestReports.js b/wdio/utils/generateTestReports.js index 60fab93507a..0c413b5e444 100644 --- a/wdio/utils/generateTestReports.js +++ b/wdio/utils/generateTestReports.js @@ -1,6 +1,13 @@ -const fs = require('fs'); -const xml2js = require('xml2js'); -const { generate } = require('multiple-cucumber-html-reporter'); +import { + readdirSync, + readFileSync, + existsSync, + mkdirSync, + renameSync, + writeFileSync, +} from 'fs'; +import { Parser } from 'xml2js'; +import { generate } from 'multiple-cucumber-html-reporter'; function generateTestReports() { // Generate the report when it all tests are done @@ -10,37 +17,38 @@ function generateTestReports() { // for more options see https://github.com/wswebcreation/multiple-cucumber-html-reporter#options }); - const testSuites = fs.readdirSync('./wdio/reports/junit-results'); + const testSuites = readdirSync('./wdio/reports/junit-results'); testSuites.forEach((testSuite) => { - const file = fs.readFileSync( + const file = readFileSync( `./wdio/reports/junit-results/${testSuite}`, 'utf8', ); - const parser = new xml2js.Parser(); + const parser = new Parser(); parser.parseString(file, (err, result) => { - if (err) { - throw err; - } - const suiteName = result.testsuites.testsuite[0].$.name; - // Create dir for each test suite - if (!fs.existsSync(`./wdio/reports/junit-results/${suiteName}`)) { - fs.mkdirSync(`./wdio/reports/junit-results/${suiteName}`); - fs.renameSync( - `./wdio/reports/junit-results/${testSuite}`, - `./wdio/reports/junit-results/${suiteName}/${suiteName}.xml`, - ); - // Create test-info.json file for each test suite - const testInfo = { - 'test-name': suiteName, - }; - fs.writeFileSync( - `./wdio/reports/junit-results/${suiteName}/test-info.json`, - JSON.stringify(testInfo), - ); + try { + const suiteName = result.testsuites.testsuite[0].$.name; + // Create dir for each test suite + if (!existsSync(`./wdio/reports/junit-results/${suiteName}`)) { + mkdirSync(`./wdio/reports/junit-results/${suiteName}`); + renameSync( + `./wdio/reports/junit-results/${testSuite}`, + `./wdio/reports/junit-results/${suiteName}/${suiteName}.xml`, + ); + // Create test-info.json file for each test suite + const testInfo = { + 'test-name': suiteName, + }; + writeFileSync( + `./wdio/reports/junit-results/${suiteName}/test-info.json`, + JSON.stringify(testInfo), + ); + } + } catch (error) { + //do nothing for now } }); }); } -module.exports = generateTestReports; +export default generateTestReports; From 7f3fad8b7dbfb3c2ddec66ad9272619a4af76ce1 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Fri, 5 May 2023 09:52:56 +0200 Subject: [PATCH 14/20] [e2e] Send ETH to an EOA using Ganache network on Android (#6215) * Send ETH with Ganache network * Move Ganache initialization to common steps * Remove unneeded async * Update wdio/features/Confirmations/SendEthEOA.feature Co-authored-by: Curtis David * Add extra step for closing new modal * Add tag @confirmations --------- Co-authored-by: Curtis David --- wdio.conf.js | 4 ++ .../features/Confirmations/SendEthEOA.feature | 58 +++++++++++++++++++ wdio/step-definitions/common-steps.js | 14 +++++ 3 files changed, 76 insertions(+) create mode 100644 wdio/features/Confirmations/SendEthEOA.feature diff --git a/wdio.conf.js b/wdio.conf.js index 64e641e43cc..bdcffaf8371 100644 --- a/wdio.conf.js +++ b/wdio.conf.js @@ -31,6 +31,10 @@ export const config = { // specs: ['./wdio/features/**/*.feature'], + suites: { + confirmations: ['./wdio/features/Confirmations/*.feature'] + }, + // Patterns to exclude. exclude: [ // 'path/to/excluded/files' diff --git a/wdio/features/Confirmations/SendEthEOA.feature b/wdio/features/Confirmations/SendEthEOA.feature new file mode 100644 index 00000000000..0c59cb176a5 --- /dev/null +++ b/wdio/features/Confirmations/SendEthEOA.feature @@ -0,0 +1,58 @@ +@androidApp +@confirmations +@regression + +Feature: Sending ETH to an EOA + A user should be able to send ETH to another EOA address. + + Scenario: Import wallet + Given the app displayed the splash animation + And I have imported my wallet + And I tap No Thanks on the Enable security check screen + And I tap No thanks on the onboarding welcome tutorial + + Scenario: Setting up Ganache local network + Given Ganache server is started + And I close the Whats New modal + When I tap on the burger menu + And I tap on "Settings" in the menu + And In settings I tap on "Networks" + And I tap on the Add Network button + Then "POPULAR" tab is displayed on networks screen + And "CUSTOM NETWORKS" tab is displayed on networks screen + + When I tap on the "CUSTOM NETWORKS" tab + + When I type "" into Network name field + And I type "" into the RPC url field + And I type "" into the Chain ID field + And I type "" into the Network symbol field + + When I tap on the Add button + And I tap on Got it in the network education modal + Then I should see the added network name "" in the top navigation bar + + Examples: + | Network | rpcUrl | ChainID | Symbol | + | Localhost 8545 | http://localhost:8545 | 1337 | ETH | + + Scenario Outline: Sending ETH to an EOA from inside MetaMask wallet + When On the Main Wallet view I tap "ETHER" + And On the Main Wallet view I tap "Send" + And I enter address "
" in the sender's input box + When I tap button "Next" on Send To view + Then I proceed to the amount view + + When I type amount "" into amount input field + And I tap button "Next" on the Amount view + Then I should be taken to the transaction confirmation view + And the token amount to be sent is visible + + When I tap button "Send" on Confirm Amount view + Then I am taken to the token overview screen + And the transaction is submitted with Transaction Complete! toast appearing + Then Ganache server is stopped + + Examples: + | Address | Amount | + | 0x1FDb169Ef12954F20A15852980e1F0C122BfC1D6 | 1 | \ No newline at end of file diff --git a/wdio/step-definitions/common-steps.js b/wdio/step-definitions/common-steps.js index 458bb6bb713..e56658cb848 100644 --- a/wdio/step-definitions/common-steps.js +++ b/wdio/step-definitions/common-steps.js @@ -15,6 +15,11 @@ import LoginScreen from '../screen-objects/LoginScreen'; import TermOfUseScreen from '../screen-objects/Modals/TermOfUseScreen'; import WhatsNewModal from '../screen-objects/Modals/WhatsNewModal'; +import Ganache from '../../app/util/test/ganache'; + +const ganacheServer = new Ganache(); +const validAccount = Accounts.getValidAccount(); + Then(/^the Welcome Screen is displayed$/, async () => { await WelcomeScreen.waitForScreenToDisplay(); }); @@ -236,8 +241,17 @@ When(/^the toast is displayed$/, async () => { await CommonScreen.waitForToastToDisplay(); await CommonScreen.waitForToastToDisappear(); }); + Given(/^I close the Whats New modal$/, async () => { await WhatsNewModal.waitForDisplay(); await WhatsNewModal.tapCloseButton(); await WhatsNewModal.waitForDisappear(); }); + +Given(/^Ganache server is started$/, async () => { + await ganacheServer.start({ mnemonic: validAccount.seedPhrase }); +}); + +Then(/^Ganache server is stopped$/, async () => { + await ganacheServer.quit(); +}); \ No newline at end of file From 82ebe72e9be07a44719b26b61996e2c5bee9c323 Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Fri, 5 May 2023 10:59:22 +0100 Subject: [PATCH 15/20] Fix yarn watch clean (#6339) --- scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.sh b/scripts/build.sh index 979842ea2b8..a3ad4e781b5 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -396,7 +396,7 @@ startWatcher() { yarn --ignore-engines build:static-logos if [ "$MODE" == "clean" ]; then watchman watch-del-all - rm -rf $TMPDIR/react-* + rm -rf $TMPDIR/metro-cache react-native start -- --reset-cache else react-native start From 14bc6969b2f10ebf739a7cd7a6c1e0a4bd10f984 Mon Sep 17 00:00:00 2001 From: Unik0rnMaggie <128788650+Unik0rnMaggie@users.noreply.github.com> Date: Sat, 6 May 2023 00:06:45 +0300 Subject: [PATCH 16/20] Update es.js file (#6345) Hi Team, We have noticed some mistakes in the ES translation for MM mobile: - "Nonce" should be translated as "Nonce", instead of "mientras tanto" (which means "meanwhile"), as it currently is now. - "Agilizar" should be replaced with "Acelerar", for consistency: everywhere else, "speed up" was translated as "Acelerar" Thank you! Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com> --- locales/languages/es.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/languages/es.json b/locales/languages/es.json index e9b10bd9378..05433e6628a 100644 --- a/locales/languages/es.json +++ b/locales/languages/es.json @@ -928,7 +928,7 @@ "gas_fee_average": "PROMEDIO", "gas_fee_slow": "LENTO", "hex_data": "Datos hexadecimales", - "custom_nonce": "Mientras tanto", + "custom_nonce": "Nonce", "this_is_an_advanced": "Esta es una función avanzada que se usa para cancelar o acelerar transacciones pendientes.", "current_suggested_nonce": "Nonce actual sugerido:", "edit_transaction_nonce": "Editar nonce de transacción", @@ -1197,7 +1197,7 @@ "address_from_balance": "Saldo:", "status": "Estado", "date": "Fecha", - "nonce": "Mientras tanto", + "nonce": "Nonce", "from_device_label": "de este dispositivo", "import_wallet_row": "Cuenta agregada a este dispositivo", "import_wallet_label": "Cuenta agregada", @@ -2197,7 +2197,7 @@ "aggressive": "Agresivo", "low_fee_warning": "Tome nota de su tiempo de procesamiento. Las transacciones futuras se pondrán en la cola después de esta.", "edit_priority": "Editar prioridad", - "speed_up_transaction": "Agilizar transacción", + "speed_up_transaction": "Acelerar transacción", "cancel_transaction": "Cancelar transacción", "new_gas_fee": "Nueva tarifa de gas", "edit_suggested_gas_fee": "Editar tarifa de gas sugerida", From 5a6488adc8f0917034f758c827abb86e918393ec Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Fri, 5 May 2023 20:18:40 -0230 Subject: [PATCH 17/20] Update controller packages to match core v40 (#6124) * Update controller packages to match core v40 The controller packages have been updated to match the versions in the core monorepo v40 release. The keyring controller update was held back due to incompatibilities related to BigInt. The only breaking change was to the network controller state. The state property `properties` was renamed to `networkDetails`. Luckily there was only a single direct reference to this property (in a test) so the number of changes required was minimal, but we did need a state migration. * Update assets-controllers patch --- .../Contacts/ContactForm/index.test.tsx | 2 +- app/store/migrations.js | 9 ++++++- package.json | 4 ++-- ... @metamask+assets-controllers+4.0.1.patch} | 0 yarn.lock | 24 +++++++++++++++---- 5 files changed, 30 insertions(+), 9 deletions(-) rename patches/{@metamask+assets-controllers+4.0.0.patch => @metamask+assets-controllers+4.0.1.patch} (100%) diff --git a/app/components/Views/Settings/Contacts/ContactForm/index.test.tsx b/app/components/Views/Settings/Contacts/ContactForm/index.test.tsx index 42af478505c..3aaeb40407e 100644 --- a/app/components/Views/Settings/Contacts/ContactForm/index.test.tsx +++ b/app/components/Views/Settings/Contacts/ContactForm/index.test.tsx @@ -11,7 +11,7 @@ const initialState = { NetworkController: { isCustomNetwork: false, network: '1', - properties: {}, + networkDetails: {}, providerConfig: { chainId: '1', ticker: 'ETH', type: 'mainnet' }, }, AddressBookController: { diff --git a/app/store/migrations.js b/app/store/migrations.js index 3c9ff690cb4..5173797da8c 100644 --- a/app/store/migrations.js +++ b/app/store/migrations.js @@ -404,6 +404,13 @@ export const migrations = { } return state; }, + 16: (state) => { + if (state.engine.backgroundState.NetworkController.properties) { + state.engine.backgroundState.NetworkController.networkDetails = + state.engine.backgroundState.NetworkController.properties; + delete state.engine.backgroundState.NetworkController.properties; + } + }, }; -export const version = 15; +export const version = 16; diff --git a/package.json b/package.json index 939cf1ac249..b78252f4921 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,7 @@ "@keystonehq/ur-decoder": "^0.6.1", "@metamask/address-book-controller": "^1.1.0", "@metamask/approval-controller": "^1.1.0", - "@metamask/assets-controllers": "4.0.0", + "@metamask/assets-controllers": "^4.0.1", "@metamask/base-controller": "^1.1.2", "@metamask/composable-controller": "^1.0.2", "@metamask/contract-metadata": "^2.1.0", @@ -155,7 +155,7 @@ "@metamask/gas-fee-controller": "^3.0.0", "@metamask/keyring-controller": "^1.0.1", "@metamask/message-manager": "^1.0.2", - "@metamask/network-controller": "^3.0.0", + "@metamask/network-controller": "^4.0.0", "@metamask/permission-controller": "^2.0.0", "@metamask/phishing-controller": "^2.0.0", "@metamask/preferences-controller": "^2.1.0", diff --git a/patches/@metamask+assets-controllers+4.0.0.patch b/patches/@metamask+assets-controllers+4.0.1.patch similarity index 100% rename from patches/@metamask+assets-controllers+4.0.0.patch rename to patches/@metamask+assets-controllers+4.0.1.patch diff --git a/yarn.lock b/yarn.lock index 0f951f52b8a..401e2c07193 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3953,10 +3953,10 @@ immer "^9.0.6" nanoid "^3.1.31" -"@metamask/assets-controllers@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@metamask/assets-controllers/-/assets-controllers-4.0.0.tgz#81278619128cf6b22503584eebcd25a529e42386" - integrity sha512-e/ngelUbyo6drDsIm/lzh7qf43Laju/sxDLaEtolRWJDVW8ZiTrWzCAVQ1m7aduVIS7WDUR51uKzsxiTWY19cA== +"@metamask/assets-controllers@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@metamask/assets-controllers/-/assets-controllers-4.0.1.tgz#75a8e20f441809178490c3952f956e71df15b31e" + integrity sha512-ZzZw6o0gD0kjgVjOBzKfuQ1zTIutsgZfwryceRyGgSP24zhCutIFpcClsRzNLgGMShD6JRV0Ul8bjyH1WchKrw== dependencies: "@ethersproject/bignumber" "^5.7.0" "@ethersproject/contracts" "^5.7.0" @@ -3966,7 +3966,7 @@ "@metamask/contract-metadata" "^2.1.0" "@metamask/controller-utils" "^2.0.0" "@metamask/metamask-eth-abis" "3.0.0" - "@metamask/network-controller" "^3.0.0" + "@metamask/network-controller" "^4.0.0" "@metamask/preferences-controller" "^1.0.2" "@metamask/utils" "^3.3.1" "@types/uuid" "^8.3.0" @@ -4226,6 +4226,20 @@ immer "^9.0.6" web3-provider-engine "^16.0.3" +"@metamask/network-controller@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@metamask/network-controller/-/network-controller-4.0.0.tgz#0b0eeb2c507f5ae0501074118ae81e8d85b6b9c3" + integrity sha512-zu1webUQCurzTAgf03WQJoiKyxmbA+VP4xs08ZwATnXSxDHbbLWtXYC18YGoiwpY7Rw0yfJqZZduNxYLfMPELA== + dependencies: + "@metamask/base-controller" "^1.1.2" + "@metamask/controller-utils" "^2.0.0" + async-mutex "^0.2.6" + babel-runtime "^6.26.0" + eth-json-rpc-infura "^5.1.0" + eth-query "^2.1.2" + immer "^9.0.6" + web3-provider-engine "^16.0.3" + "@metamask/obs-store@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@metamask/obs-store/-/obs-store-7.0.0.tgz#6cae5f28306bb3e83a381bc9ae22682316095bd3" From 792dc18b4e0fd424cf8520bbe4b4917dcbd46983 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Tue, 9 May 2023 18:19:50 -0230 Subject: [PATCH 18/20] Update controller packages to match core v42 (#6125) Most controller packages have been updated to the versions included in the core monorepo v42 release. The keyring controller was the only package held back, due to the BigInt incompatibility. The breaking change for most of these updates was related to the removal of the `isomorphic-fetch` package. That package would polyfill the `fetch` API if it wasn't present. It's not a breaking change for mobile because mobile already includes its own polyfill for the `fetch` API. The only other breaking change is to the gas fee controller, which has made a constructor parameter required rather than optional. This does not affect mobile because mobile already sets that parameter.. See here for the release notes for each updated controller: https://github.com/MetaMask/core/releases/tag/v42.0.0 This progresses https://github.com/MetaMask/mobile-planning/issues/798 --- package.json | 28 +-- ... @metamask+assets-controllers+5.0.0.patch} | 0 yarn.lock | 187 +++++++----------- 3 files changed, 81 insertions(+), 134 deletions(-) rename patches/{@metamask+assets-controllers+4.0.1.patch => @metamask+assets-controllers+5.0.0.patch} (100%) diff --git a/package.json b/package.json index b78252f4921..0a241bf0c65 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "test:e2e": "yarn test:e2e:ios && yarn test:e2e:android", "test:e2e:ios": "detox build -c ios.sim.release && detox test -c ios.sim.release", "test:e2e:ios:debug": "detox build -c ios.sim.debug && detox test -c ios.sim.debug", - "test:e2e:ios:debug:single":"detox test -c ios.sim.debug", + "test:e2e:ios:debug:single": "detox test -c ios.sim.debug", "test:e2e:android": "detox build -c android.emu.release && detox test -c android.emu.release --record-videos failing", "test:e2e:android:qa": "detox build -c android.emu.release.qa && detox test -c android.emu.release.qa --record-videos failing", "test:wdio:ios": "yarn wdio ./wdio/config/ios.config.debug.js", @@ -113,6 +113,8 @@ "react-native-level-fs/**/bl": "^1.2.3", "react-native-level-fs/**/semver": "^4.3.2", "@metamask/contract-metadata": "^2.1.0", + "@metamask/controller-utils": "~3.0.0", + "@metamask/approval-controller": "~2.0.0", "@exodus/react-native-payments/validator": "^13.7.0", "react-devtools-core": "4.22.1", "**/got": "^11.8.5", @@ -142,26 +144,26 @@ "@keystonehq/bc-ur-registry-eth": "^0.7.7", "@keystonehq/metamask-airgapped-keyring": "^0.3.0", "@keystonehq/ur-decoder": "^0.6.1", - "@metamask/address-book-controller": "^1.1.0", - "@metamask/approval-controller": "^1.1.0", - "@metamask/assets-controllers": "^4.0.1", - "@metamask/base-controller": "^1.1.2", - "@metamask/composable-controller": "^1.0.2", + "@metamask/address-book-controller": "^2.0.0", + "@metamask/approval-controller": "~2.0.0", + "@metamask/assets-controllers": "5.0.0", + "@metamask/base-controller": "^2.0.0", + "@metamask/composable-controller": "^2.0.0", "@metamask/contract-metadata": "^2.1.0", - "@metamask/controller-utils": "^2.0.0", + "@metamask/controller-utils": "~3.0.0", "@metamask/design-tokens": "^1.11.1", "@metamask/eth-sig-util": "^4.0.1", "@metamask/etherscan-link": "^2.0.0", - "@metamask/gas-fee-controller": "^3.0.0", + "@metamask/gas-fee-controller": "4.0.0", "@metamask/keyring-controller": "^1.0.1", - "@metamask/message-manager": "^1.0.2", - "@metamask/network-controller": "^4.0.0", - "@metamask/permission-controller": "^2.0.0", - "@metamask/phishing-controller": "^2.0.0", + "@metamask/message-manager": "^2.0.0", + "@metamask/network-controller": "^5.0.0", + "@metamask/permission-controller": "~3.0.0", + "@metamask/phishing-controller": "^3.0.0", "@metamask/preferences-controller": "^2.1.0", "@metamask/sdk-communication-layer": "0.2.2", "@metamask/swaps-controller": "^6.8.0", - "@metamask/transaction-controller": "^3.0.0", + "@metamask/transaction-controller": "4.0.0", "@ngraveio/bc-ur": "^1.1.6", "@react-native-async-storage/async-storage": "1.17.10", "@react-native-clipboard/clipboard": "^1.8.4", diff --git a/patches/@metamask+assets-controllers+4.0.1.patch b/patches/@metamask+assets-controllers+5.0.0.patch similarity index 100% rename from patches/@metamask+assets-controllers+4.0.1.patch rename to patches/@metamask+assets-controllers+5.0.0.patch diff --git a/yarn.lock b/yarn.lock index 401e2c07193..3a3150b98c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3934,40 +3934,40 @@ "@metamask/utils" "^3.4.1" superstruct "^1.0.3" -"@metamask/address-book-controller@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@metamask/address-book-controller/-/address-book-controller-1.1.0.tgz#45106353c113c17357bb23a5191eb0bd56cbfc8d" - integrity sha512-J2oJkt2cgiSdl/qwjG4hVlCn9bSdB/WxkS3m4zwC8BEv/pJPfxkgl/yyNp9hk/JVCRigTGe5CTuFwkoRjzz8zQ== +"@metamask/address-book-controller@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@metamask/address-book-controller/-/address-book-controller-2.0.0.tgz#5866282c0c1c95e7c6cf7058b86962e74c9955fd" + integrity sha512-gifdVdIKOWMK/UGX97CucpBXQy+Yk4KmOWd2j9Hbu6j296htqdAvo2NfvVTGtUG2JRNnNg3qsGIJ8V/lVntSww== dependencies: - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" + "@metamask/base-controller" "^2.0.0" + "@metamask/controller-utils" "^3.0.0" -"@metamask/approval-controller@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@metamask/approval-controller/-/approval-controller-1.1.0.tgz#1f0c89ffa3a60600f69886ffb9a8bd06ef823b32" - integrity sha512-6RFPMUayRDxe1ZrkDPIqPNSQ10pMUB1uGr8c52X7gm+EEaS3OnZV4qLMASvwpu7gNQe5dFiCZPypRHlM5qiq+A== +"@metamask/approval-controller@^2.0.0", "@metamask/approval-controller@~2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@metamask/approval-controller/-/approval-controller-2.0.0.tgz#a4a129ba9377465257c6dc632a92af9273b3a112" + integrity sha512-NbRJdtyfPyY810xGcZqI+MqtvouRC39pYBCA+BZCvXEoam0b+g9Z/j0QOMLrplSSWM7OsNNQP5Q/Ge1R07ERmw== dependencies: - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" + "@metamask/base-controller" "^2.0.0" + "@metamask/controller-utils" "^3.0.0" eth-rpc-errors "^4.0.0" immer "^9.0.6" nanoid "^3.1.31" -"@metamask/assets-controllers@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@metamask/assets-controllers/-/assets-controllers-4.0.1.tgz#75a8e20f441809178490c3952f956e71df15b31e" - integrity sha512-ZzZw6o0gD0kjgVjOBzKfuQ1zTIutsgZfwryceRyGgSP24zhCutIFpcClsRzNLgGMShD6JRV0Ul8bjyH1WchKrw== +"@metamask/assets-controllers@5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@metamask/assets-controllers/-/assets-controllers-5.0.0.tgz#6622fa3e400a4d380ec7d36bb8ba4159f33788ee" + integrity sha512-Ix93B4SRMmvUVwyVvz4SkjaWBwTD1HMvxmeFyWxhE18k46wTSKsq5bQ3pk7D5jgcWFDFdgFJ4Mv1TCcW2dDbnw== dependencies: "@ethersproject/bignumber" "^5.7.0" "@ethersproject/contracts" "^5.7.0" "@ethersproject/providers" "^5.7.0" "@metamask/abi-utils" "^1.1.0" - "@metamask/base-controller" "^1.1.2" + "@metamask/base-controller" "^2.0.0" "@metamask/contract-metadata" "^2.1.0" - "@metamask/controller-utils" "^2.0.0" + "@metamask/controller-utils" "^3.0.0" "@metamask/metamask-eth-abis" "3.0.0" - "@metamask/network-controller" "^4.0.0" - "@metamask/preferences-controller" "^1.0.2" + "@metamask/network-controller" "^5.0.0" + "@metamask/preferences-controller" "^2.0.0" "@metamask/utils" "^3.3.1" "@types/uuid" "^8.3.0" abort-controller "^3.0.0" @@ -3989,14 +3989,6 @@ "@metamask/controller-utils" "^1.0.0" immer "^9.0.6" -"@metamask/base-controller@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@metamask/base-controller/-/base-controller-1.1.2.tgz#92643d16a322664adae924cf45806c96c6704e30" - integrity sha512-lOV3dyaTw+dTZOYkpjFwKN4DfOlvRpALknUlOzoFg+ChLeva8T7E4/pyo52FOEtxhajsq9/77soGm729oaNGMA== - dependencies: - "@metamask/controller-utils" "^2.0.0" - immer "^9.0.6" - "@metamask/base-controller@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@metamask/base-controller/-/base-controller-2.0.0.tgz#8f9130df3edaa270ade00378cf57917545d44617" @@ -4015,43 +4007,19 @@ pbkdf2 "^3.0.9" randombytes "^2.0.1" -"@metamask/composable-controller@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@metamask/composable-controller/-/composable-controller-1.0.2.tgz#d6c7528084e34c17df3009efe1d9cd58bdf69187" - integrity sha512-nDFlFKsajuiw/HaeLqBUuEfpgUpRZenY0a0atiWwNQ2B3EETPATICaPT179owgXiXUI3rhQdRmLn7sX6WEs5GQ== +"@metamask/composable-controller@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@metamask/composable-controller/-/composable-controller-2.0.0.tgz#a3549c5ad150d2c74e575987968de4b8f8ae5d9b" + integrity sha512-vc1OVUtP/h9BYtYQtcJxbwzXKg/ELUguZ7XzT/yEIFUJh9m+1c8f1YPq7wYq1qmSF37U/5O4e/1d7GhJRJw9Dg== dependencies: - "@metamask/base-controller" "^1.1.2" + "@metamask/base-controller" "^2.0.0" "@metamask/contract-metadata@^1.31.0", "@metamask/contract-metadata@^2.1.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-2.2.0.tgz#277764d0d56e37180ae7644a9d11eb96295b36fc" integrity sha512-SM6A4C7vXNbVpgMTX67kfW8QWvu3eSXxMZlY5PqZBTkvri1s9zgQ0uwRkK5r2VXNEoVmXCDnnEX/tX5EzzgNUQ== -"@metamask/controller-utils@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@metamask/controller-utils/-/controller-utils-1.0.0.tgz#2e2261b65c3f38ba0c5b893743fca8cce764339c" - integrity sha512-LXIpnmF/C5/vCBX0u2DiUWA55utZy54guUV+A8qUYmz8PvZrXfK7mdq1zlk8z0aq+aO0rHHfSVbTNacEE3TlAQ== - dependencies: - eth-ens-namehash "^2.0.8" - eth-rpc-errors "^4.0.0" - ethereumjs-util "^7.0.10" - ethjs-unit "^0.1.6" - fast-deep-equal "^3.1.3" - isomorphic-fetch "^3.0.0" - -"@metamask/controller-utils@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@metamask/controller-utils/-/controller-utils-2.0.0.tgz#11b7639b7724b67c4ad983fd1185313fff2217be" - integrity sha512-dwpF1qPIGzTr6kMAJQmX6/eVtRPrBBMlB9oiHnOhHN2mYPqd6fCnesyA3TsqM8I65mTjqrkV4OtPtz6pzYvclw== - dependencies: - eth-ens-namehash "^2.0.8" - eth-rpc-errors "^4.0.0" - ethereumjs-util "^7.0.10" - ethjs-unit "^0.1.6" - fast-deep-equal "^3.1.3" - isomorphic-fetch "^3.0.0" - -"@metamask/controller-utils@^3.0.0": +"@metamask/controller-utils@^1.0.0", "@metamask/controller-utils@^3.0.0", "@metamask/controller-utils@^3.1.0", "@metamask/controller-utils@~3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@metamask/controller-utils/-/controller-utils-3.0.0.tgz#e0984cdab14280409297671b5858891527c5e4ee" integrity sha512-JjFWBZnnh5DSX2tRsw5xtXxaqVkTzaW7mkSZ+lL3LoCAw47Cf8zGP1kGR6VKxcceKi+MpEFvZr7gf1OFnOoEjw== @@ -4144,14 +4112,14 @@ resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-2.1.0.tgz#c0be8e68445b7b83cf85bcc03a56cdf8e256c973" integrity sha512-ADuWlTUkFfN2vXlz81Bg/0BA+XRor+CdK1055p6k7H6BLIPoDKn9SBOFld9haQFuR9cKh/JYHcnlSIv5R4fUEw== -"@metamask/gas-fee-controller@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@metamask/gas-fee-controller/-/gas-fee-controller-3.0.0.tgz#6b6c81ba9e553b253e4875bacf6f84e17d2238e1" - integrity sha512-5kFnfqimsRAJKydjG8jgGFdosjDI42+72vIPuGeCZkSV93KsXX30NjrQQD6Sl1ZJjyfmysdQbFS6unsOheU0lg== +"@metamask/gas-fee-controller@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@metamask/gas-fee-controller/-/gas-fee-controller-4.0.0.tgz#b3532373ed1a245aaecdd23903a02951e20ee47b" + integrity sha512-dIN8e4UAU8uOjUk4Zl1l8fwsWk8vFpFoeng2VHvfxkvDkK5XxNbxF4IidffRnoJpCaynNWNH0Y+7QrtSR3qf+w== dependencies: - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" - "@metamask/network-controller" "^3.0.0" + "@metamask/base-controller" "^2.0.0" + "@metamask/controller-utils" "^3.0.0" + "@metamask/network-controller" "^5.0.0" "@types/uuid" "^8.3.0" babel-runtime "^6.26.0" eth-query "^2.1.2" @@ -4189,13 +4157,13 @@ jsonschema "^1.2.4" uuid "^8.3.2" -"@metamask/message-manager@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@metamask/message-manager/-/message-manager-1.0.2.tgz#2474ed1a3f60884bf79d47533b61bb55baf26614" - integrity sha512-HX4e4GnpQxAQLGL+BeHxZcjTBgt0a4S2MBpLoEvgStMHpfiuEanZfhKTgDUR12BKcctw9SMyfcKNvyKBaxYD6Q== +"@metamask/message-manager@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@metamask/message-manager/-/message-manager-2.1.0.tgz#0048eb56d37798a4d92bba51bc816e02b2983ed3" + integrity sha512-tHa+Hky2cLJAkmKa1wx+8s7Daxpa9E/OJJQ62666ASgAFqV+cvxilGAcTwUOYnx+ZHa1kzvGatE0KePsnHJ2HQ== dependencies: - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" + "@metamask/base-controller" "^2.0.0" + "@metamask/controller-utils" "^3.1.0" "@types/uuid" "^8.3.0" eth-sig-util "^3.0.0" ethereumjs-util "^7.0.10" @@ -4212,27 +4180,13 @@ resolved "https://registry.yarnpkg.com/@metamask/mobile-provider/-/mobile-provider-2.1.0.tgz#685b2f6a55d24197af3f26de4dd0bb78e10ac83e" integrity sha512-VuVUIZ5jEQmLaU8SJC8692crxtNncsxyR9q5j1J6epyMHUU75WTtQdq7VSsu1ghkmP9NXNAz3inlWOGsbT8lLA== -"@metamask/network-controller@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@metamask/network-controller/-/network-controller-3.0.0.tgz#f43dd9588240bed187a078da2bd3f758b3338172" - integrity sha512-SjffWl0kLqeT6F4X2EFHkPu5fkCMF+hblqM+BvDnDoanSFDk7Dcw+jXKSv7sw5QDX2DcfYtqvZbms2VWXu3x6g== - dependencies: - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" - async-mutex "^0.2.6" - babel-runtime "^6.26.0" - eth-json-rpc-infura "^5.1.0" - eth-query "^2.1.2" - immer "^9.0.6" - web3-provider-engine "^16.0.3" - -"@metamask/network-controller@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@metamask/network-controller/-/network-controller-4.0.0.tgz#0b0eeb2c507f5ae0501074118ae81e8d85b6b9c3" - integrity sha512-zu1webUQCurzTAgf03WQJoiKyxmbA+VP4xs08ZwATnXSxDHbbLWtXYC18YGoiwpY7Rw0yfJqZZduNxYLfMPELA== +"@metamask/network-controller@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@metamask/network-controller/-/network-controller-5.0.0.tgz#7f14a06f9ebec738888d6e2bf10ae05a4caabcb6" + integrity sha512-rYZl/geh3+M03umPJrWkkMhy+hJL6L0P7rV+KwzFwgfE8jL3EdB+Z9PtIVkGj0qj/8QIswhP3j/xAFWzyRlsZw== dependencies: - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" + "@metamask/base-controller" "^2.0.0" + "@metamask/controller-utils" "^3.0.0" async-mutex "^0.2.6" babel-runtime "^6.26.0" eth-json-rpc-infura "^5.1.0" @@ -4248,14 +4202,14 @@ "@metamask/safe-event-emitter" "^2.0.0" through2 "^2.0.3" -"@metamask/permission-controller@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@metamask/permission-controller/-/permission-controller-2.0.0.tgz#04135b7164a13df71f0f9b70de0a9fbd09f8a15a" - integrity sha512-KKnRc1F+N7fI8AXNxS+X21E1X0yQrBoqCGDn1WX5QPPOZ/wjvDbrPxaCK/Vkd2TxDosJ2jmA5HSl2TFY5X7U0w== +"@metamask/permission-controller@~3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@metamask/permission-controller/-/permission-controller-3.0.0.tgz#2c58f749c4fc192743fd2e5fad5ffa503ba1c068" + integrity sha512-902jw48yetCsNo6DGrXKHDWWz/QzdmC90O6Am5WgUmwUlboU9Mr0uS8Fp8b7qPQiDZRXz8PvckodyEX2XNW+tQ== dependencies: - "@metamask/approval-controller" "^1.1.0" - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" + "@metamask/approval-controller" "^2.0.0" + "@metamask/base-controller" "^2.0.0" + "@metamask/controller-utils" "^3.0.0" "@metamask/types" "^1.1.0" "@types/deep-freeze-strict" "^1.1.0" deep-freeze-strict "^1.1.1" @@ -4264,16 +4218,15 @@ json-rpc-engine "^6.1.0" nanoid "^3.1.31" -"@metamask/phishing-controller@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@metamask/phishing-controller/-/phishing-controller-2.0.0.tgz#4a5471a70af5353d4c33a4f9a756f7e0070cb163" - integrity sha512-dI8LQD4q4o2pVvBTWGpjnrK+MMwV1/CkmKh6ga0hy4aDDcw7hLJuDGM3b+R7lPvS3QEb0WJNH76qyaIeR2FQaw== +"@metamask/phishing-controller@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@metamask/phishing-controller/-/phishing-controller-3.0.0.tgz#6a5d93f29354468e416f670d2892e3228b5fd562" + integrity sha512-U5TTGod1up/qiClswmjyfZjedzuj1wOcrHSYWyD2u4f1Tq0slcF9vbqV2nDWHslK6z+3hyuUTESd48SZ61sFjA== dependencies: - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" + "@metamask/base-controller" "^2.0.0" + "@metamask/controller-utils" "^3.0.0" "@types/punycode" "^2.1.0" eth-phishing-detect "^1.2.0" - isomorphic-fetch "^3.0.0" punycode "^2.1.1" "@metamask/preferences-controller@^1.0.1": @@ -4284,15 +4237,7 @@ "@metamask/base-controller" "^1.1.1" "@metamask/controller-utils" "^1.0.0" -"@metamask/preferences-controller@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@metamask/preferences-controller/-/preferences-controller-1.0.2.tgz#44deb138f63763ac2300753fde36616d791c1402" - integrity sha512-oITXsI5sypaIv2rzr07zvfiWB8L906mB2ff/MVOHR+dgAq8bgmcym01jdJEu8YlVQgFB63E+C6qgtm0F7AwEww== - dependencies: - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" - -"@metamask/preferences-controller@^2.1.0": +"@metamask/preferences-controller@^2.0.0", "@metamask/preferences-controller@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@metamask/preferences-controller/-/preferences-controller-2.1.0.tgz#c3ed464259f3f969ff492167c368752d23db3924" integrity sha512-/GvYSaCCT0DVDZLlt8eiJDcw7WNFeIMpssP0X0+MK+Ye5eGEMp0Wo0n5uoMOKDR+x3HnWo5YuVGHBlSCnusEeg== @@ -4331,16 +4276,16 @@ human-standard-token-abi "^2.0.0" web3 "^0.20.7" -"@metamask/transaction-controller@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@metamask/transaction-controller/-/transaction-controller-3.0.0.tgz#91b556b3c88787c854328b64822eaa14c59ce292" - integrity sha512-xlJIWUFznki3Nh+txI6cKVwKYgF79itmef9Ml5icjBfLOsyMe7up4I/SJ+228+fWw1PycYClmCyIbHc3vREZXA== +"@metamask/transaction-controller@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@metamask/transaction-controller/-/transaction-controller-4.0.0.tgz#adf95691861f8839180772bbfd16409126d85a2f" + integrity sha512-CR1LzcA10TotuH4DSCGJlquYh4P1yDVkP+3VGkyGk6XL2Co5wy3igt8dIs1WKebccPEP540oy7yYG4amcW9hVw== dependencies: "@ethereumjs/common" "^2.6.1" "@ethereumjs/tx" "^3.5.2" - "@metamask/base-controller" "^1.1.2" - "@metamask/controller-utils" "^2.0.0" - "@metamask/network-controller" "^3.0.0" + "@metamask/base-controller" "^2.0.0" + "@metamask/controller-utils" "^3.0.0" + "@metamask/network-controller" "^5.0.0" async-mutex "^0.2.6" babel-runtime "^6.26.0" eth-method-registry "1.1.0" From 1a78b2fef0c7af3039d6c73f5b53ddf6f9fb3c4e Mon Sep 17 00:00:00 2001 From: yande <110056475+Andepande@users.noreply.github.com> Date: Wed, 10 May 2023 16:41:43 +0100 Subject: [PATCH 19/20] Added retries (#6362) --- wdio.conf.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wdio.conf.js b/wdio.conf.js index bdcffaf8371..d501d68690b 100644 --- a/wdio.conf.js +++ b/wdio.conf.js @@ -56,6 +56,7 @@ export const config = { // from the same test should run tests. // maxInstances: 10, + specFileRetries: 1, // // If you have trouble getting all important capabilities together, check out the // Sauce Labs platform configurator - a great tool to configure your capabilities: @@ -120,7 +121,7 @@ export const config = { baseUrl: 'http://localhost', // // Default timeout for all waitFor* commands. - waitforTimeout: 100000, + waitforTimeout: 40000, // // Default timeout in milliseconds for request // if browser driver or grid doesn't send response From 64d2658377ce607ad6add6a5a262895e34117e1c Mon Sep 17 00:00:00 2001 From: legobeat <109787230+legobeat@users.noreply.github.com> Date: Thu, 11 May 2023 11:02:35 +0000 Subject: [PATCH 20/20] chore(devDeps): bump webdriverio packages (#6328) * devDeps: @wdio/appium-service@7.25.1->7.31.1 * devDeps: bump webdriverio packages Maintenance update staying on major version v7. Upgrading to current [v8](https://github.com/webdriverio/webdriverio/releases/tag/v8.0.0) addressed in a later change. * devDeps: bump @cucumber/ packages Subdeps of wdio framework * devDeps: dedupe open@^8.* * devDeps: drop unused wdio-cucumber-reporter Unmaintained since 2016 and does not seem to work with currently used version of webdriverio anyway. Drops transitive dependency on deprecated babel-runtime v5. * devDeps: remove unused wdio-vscode-service * devDeps: remove unused wdio-image-comparison-service Removes transitive dep on @mapbox/node-pre-gyp * devDeps: remove unused wdio-chromedriver-service * devDeps: add gherkin missing peerDeps @cucumber/message-streams, @cucumber/messages --- package.json | 6 +- yarn.lock | 1003 ++++++++++++++------------------------------------ 2 files changed, 280 insertions(+), 729 deletions(-) diff --git a/package.json b/package.json index 0a241bf0c65..070aa711a1d 100644 --- a/package.json +++ b/package.json @@ -327,6 +327,8 @@ "devDependencies": { "@babel/core": "^7.12.9", "@babel/runtime": "^7.12.5", + "@cucumber/message-streams": "^4.0.1", + "@cucumber/messages": "^22.0.0", "@lavamoat/allow-scripts": "^1.0.6", "@metamask/eslint-config": "^7.0.0", "@metamask/eslint-config-typescript": "^7.0.0", @@ -408,11 +410,7 @@ "rn-nodeify": "10.0.1", "stack-beautifier": "1.0.2", "typescript": "^4.4.2", - "wdio-chromedriver-service": "^7.3.2", - "wdio-cucumber-reporter": "^0.0.2", "wdio-cucumberjs-json-reporter": "^4.4.3", - "wdio-image-comparison-service": "^3.1.0", - "wdio-vscode-service": "^0.1.5", "xml2js": "^0.5.0" }, "config": { diff --git a/yarn.lock b/yarn.lock index 3a3150b98c2..0b528436785 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1636,6 +1636,13 @@ dependencies: "@cucumber/messages" "^19.0.0" +"@cucumber/gherkin@26.0.3": + version "26.0.3" + resolved "https://registry.yarnpkg.com/@cucumber/gherkin/-/gherkin-26.0.3.tgz#6ffe37570c608caa329784161305056135a19c96" + integrity sha512-xwJHi//bLFEU1drIyw2yswwUHnnVWO4XcyVBbCTDs6DkSh262GkogFI/IWwChZqJfOXnPglzLGxR1DibcZsILA== + dependencies: + "@cucumber/messages" "19.1.4 - 21" + "@cucumber/gherkin@^24.1.0": version "24.1.0" resolved "https://registry.yarnpkg.com/@cucumber/gherkin/-/gherkin-24.1.0.tgz#ca2dcbe11f5f7d7f30fd073280550bd6eca2363c" @@ -1656,7 +1663,7 @@ resolved "https://registry.yarnpkg.com/@cucumber/html-formatter/-/html-formatter-20.0.0.tgz#d0958b2d53a6f5ce0fb6f6d7eac88902e9b31030" integrity sha512-I6ZzUZ0CkaaPm6QHThoCRmdcuEIV9kJlNjaWvQ3PRkJm0OscQkQ0SXL/j73U30RDPiCAWwtq6ZSeQrgkTnSK+Q== -"@cucumber/message-streams@4.0.1": +"@cucumber/message-streams@4.0.1", "@cucumber/message-streams@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@cucumber/message-streams/-/message-streams-4.0.1.tgz#a5339d3504594bb2edb5732aaae94dddb24d0970" integrity sha512-Kxap9uP5jD8tHUZVjTWgzxemi/0uOsbGjd4LBOSxcJoOCRbESFwemUzilJuzNTB8pcTQUh8D5oudUyxfkJOKmA== @@ -1678,10 +1685,10 @@ reflect-metadata "0.1.13" uuid "8.3.2" -"@cucumber/messages@19.1.4", "@cucumber/messages@^19.0.0", "@cucumber/messages@^19.1.4": - version "19.1.4" - resolved "https://registry.yarnpkg.com/@cucumber/messages/-/messages-19.1.4.tgz#5cefc47cac3004c0bc38d42933042ec248bb747c" - integrity sha512-Pksl0pnDz2l1+L5Ug85NlG6LWrrklN9qkMxN5Mv+1XZ3T6u580dnE6mVaxjJRdcOq4tR17Pc0RqIDZMyVY1FlA== +"@cucumber/messages@19.1.4 - 21", "@cucumber/messages@21.0.1": + version "21.0.1" + resolved "https://registry.yarnpkg.com/@cucumber/messages/-/messages-21.0.1.tgz#1468cef60d6da4d4f540a70ab1265f6540f44f51" + integrity sha512-pGR7iURM4SF9Qp1IIpNiVQ77J9kfxMkPOEbyy+zRmGABnWWCsqMpJdfHeh9Mb3VskemVw85++e15JT0PYdcR3g== dependencies: "@types/uuid" "8.3.4" class-transformer "0.5.1" @@ -1698,6 +1705,26 @@ reflect-metadata "0.1.13" uuid "8.3.2" +"@cucumber/messages@^19.0.0", "@cucumber/messages@^19.1.4": + version "19.1.4" + resolved "https://registry.yarnpkg.com/@cucumber/messages/-/messages-19.1.4.tgz#5cefc47cac3004c0bc38d42933042ec248bb747c" + integrity sha512-Pksl0pnDz2l1+L5Ug85NlG6LWrrklN9qkMxN5Mv+1XZ3T6u580dnE6mVaxjJRdcOq4tR17Pc0RqIDZMyVY1FlA== + dependencies: + "@types/uuid" "8.3.4" + class-transformer "0.5.1" + reflect-metadata "0.1.13" + uuid "9.0.0" + +"@cucumber/messages@^22.0.0": + version "22.0.0" + resolved "https://registry.yarnpkg.com/@cucumber/messages/-/messages-22.0.0.tgz#2d86974ebd73046f66d217334c2245365c7990d4" + integrity sha512-EuaUtYte9ilkxcKmfqGF9pJsHRUU0jwie5ukuZ/1NPTuHS1LxHPsGEODK17RPRbZHOFhqybNzG2rHAwThxEymg== + dependencies: + "@types/uuid" "9.0.1" + class-transformer "0.5.1" + reflect-metadata "0.1.13" + uuid "9.0.0" + "@cucumber/tag-expressions@4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@cucumber/tag-expressions/-/tag-expressions-4.1.0.tgz#9a91b0e0dd2f2ba703e3038c52b49b9ac06c2c6f" @@ -3911,21 +3938,6 @@ resolved "https://registry.yarnpkg.com/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz#7a8143fb33f077df3e579dca7f18fea74a02ec8b" integrity sha512-6SJfx949YEWooh/CUPpJ+F491y4BYJmknz4hUN1+RHvKoUEynKbRmhnwbk/VLmh4OthLLDNCyWXfbh4DG1cTXA== -"@mapbox/node-pre-gyp@^1.0.0": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" - integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== - dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - "@metamask/abi-utils@^1.1.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@metamask/abi-utils/-/abi-utils-1.2.0.tgz#068e1b0f5e423dfae96961e0e5276a7c1babc03a" @@ -5484,11 +5496,25 @@ resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== -"@types/fs-extra@^9.0.4": - version "9.0.13" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45" - integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== +"@types/fs-extra@^11.0.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.1.tgz#f542ec47810532a8a252127e6e105f487e0a6ea5" + integrity sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA== dependencies: + "@types/jsonfile" "*" + "@types/node" "*" + +"@types/gitconfiglocal@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/gitconfiglocal/-/gitconfiglocal-2.0.1.tgz#c134f9fb03d71917afa35c14f3b82085520509a6" + integrity sha512-AYC38la5dRwIfbrZhPNIvlGHlIbH+kdl2j8A37twoCQyhKPPoRPfVmoBZKajpLIfV7SMboU6MZ6w/RmZLH68IQ== + +"@types/glob@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-8.1.0.tgz#b63e70155391b0584dce44e7ea25190bbc38f2fc" + integrity sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w== + dependencies: + "@types/minimatch" "^5.1.2" "@types/node" "*" "@types/graceful-fs@^4.1.2": @@ -5590,6 +5616,13 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/jsonfile@*": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.1.tgz#ac84e9aefa74a2425a0fb3012bdea44f58970f1b" + integrity sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png== + dependencies: + "@types/node" "*" + "@types/keyv@*": version "3.1.4" resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" @@ -5633,6 +5666,11 @@ resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== +"@types/minimatch@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + "@types/mockery@^1.4.29": version "1.4.30" resolved "https://registry.yarnpkg.com/@types/mockery/-/mockery-1.4.30.tgz#25f07fa7340371c7ee0fb9239511a34e0a19d5b7" @@ -5931,6 +5969,11 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== +"@types/uuid@9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.1.tgz#98586dc36aee8dacc98cc396dbca8d0429647aa6" + integrity sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA== + "@types/validator@^13.1.3": version "13.7.10" resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.7.10.tgz#f9763dc0933f8324920afa9c0790308eedf55ca7" @@ -6108,16 +6151,6 @@ "@typescript-eslint/types" "4.30.0" eslint-visitor-keys "^2.0.0" -"@vscode/test-electron@^2.1.3": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@vscode/test-electron/-/test-electron-2.2.0.tgz#b90c76b8f076f9cf2d885f14b3c5fc3f586b9419" - integrity sha512-xk2xrOTMG75/hxO8OVVZ+GErv9gmdZwOD8rEHV3ty3n1Joav2yFcfrmqD6Ukref27U13LEL8gVvSHzauGAK5nQ== - dependencies: - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - rimraf "^3.0.2" - unzipper "^0.10.11" - "@walletconnect/browser-utils@^1.7.1": version "1.7.1" resolved "https://registry.yarnpkg.com/@walletconnect/browser-utils/-/browser-utils-1.7.1.tgz#2a28846cd4d73166debbbf7d470e78ba25616f5e" @@ -6250,61 +6283,65 @@ "@walletconnect/window-getters" "^1.0.0" "@wdio/appium-service@^7.19.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@wdio/appium-service/-/appium-service-7.25.1.tgz#800f35eb8c9e73a79de852ca71d927905650a54a" - integrity sha512-EMUdwP2P8EYTf+KR8B3QrDJv3HF3XWKEdbeUERYlAmc2aJqrDxcxVH/ztbpFHDCRw9Acoao62hJ2s0Gm5VpRxA== - dependencies: - "@types/fs-extra" "^9.0.4" - "@wdio/config" "7.25.1" - "@wdio/logger" "7.19.0" - "@wdio/types" "7.25.1" - fs-extra "^10.0.0" + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/appium-service/-/appium-service-7.31.1.tgz#c86a056cbdcd382388fec5143c710183636e244f" + integrity sha512-C+bzKNpJMvxbLf64U4wO4zHb8N0JXRX3Kk5HcxjYTaCrkqSY8zfcg7UHORTqcgFju3JFYEz4NMwT5nlrvOqyEQ== + dependencies: + "@types/fs-extra" "^11.0.1" + "@wdio/config" "7.31.1" + "@wdio/logger" "7.26.0" + "@wdio/types" "7.30.2" + fs-extra "^11.1.1" param-case "^3.0.0" "@wdio/browserstack-service@^7.26.0": - version "7.28.1" - resolved "https://registry.yarnpkg.com/@wdio/browserstack-service/-/browserstack-service-7.28.1.tgz#69db230634eea60fd33802f4a1f54eca18d1f9ff" - integrity sha512-aUulloEvAPQOkbBnmf7oPI6faOcMCwibRRJuwXEM5R1VpJeXvmLRgfZXZe9T+j/zXwvBVfJ1KDEk65Oyvwc/cg== + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/browserstack-service/-/browserstack-service-7.31.1.tgz#839c9d9ed6022227c8910e0a30c28c67ddb603e0" + integrity sha512-2OVAphX/Oz4n/R38mQvSSW6v/XQhVIfJot/XKLnnOwRLa/SF2HZgxF+cFJdyeHBBHCJmr8qISmYd1JnT/ttzIQ== dependencies: - "@types/node" "^18.0.0" + "@types/gitconfiglocal" "^2.0.1" "@wdio/logger" "7.26.0" - "@wdio/types" "7.26.0" + "@wdio/reporter" "7.25.4" + "@wdio/types" "7.30.2" browserstack-local "^1.4.5" form-data "^4.0.0" + git-repo-info "^2.1.1" + gitconfiglocal "^2.1.0" got "^11.0.2" - webdriverio "7.28.1" + uuid "^8.3.2" + webdriverio "7.31.1" "@wdio/cli@^7.19.1": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@wdio/cli/-/cli-7.25.2.tgz#81b1933457184c4fcd705d13e96798e4ad229900" - integrity sha512-jpQmPR14D2nIBKby6I21zSHNQAPayZXmu+3IBNRe3SDTNEAHb9jZuyhj4IdoaPilfXrJAzQ2BRql6/T2oA29Yw== + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/cli/-/cli-7.31.1.tgz#c6d3905a64ebb31973940bf3cbe660c566632724" + integrity sha512-LEBZ6+a+ptfete6QjBnuFV2FWawilTQGzTeK7zWLc6sgCFxSV2+ifOHvw19p531WhVknm9ZX4s/GelurMhB/6w== dependencies: "@types/ejs" "^3.0.5" - "@types/fs-extra" "^9.0.4" + "@types/fs-extra" "^11.0.1" "@types/inquirer" "^8.1.2" "@types/lodash.flattendeep" "^4.4.6" "@types/lodash.pickby" "^4.6.6" "@types/lodash.union" "^4.6.6" "@types/node" "^18.0.0" "@types/recursive-readdir" "^2.2.0" - "@wdio/config" "7.25.1" - "@wdio/logger" "7.19.0" - "@wdio/protocols" "7.22.0" - "@wdio/types" "7.25.1" - "@wdio/utils" "7.25.1" + "@wdio/config" "7.31.1" + "@wdio/logger" "7.26.0" + "@wdio/protocols" "7.27.0" + "@wdio/types" "7.30.2" + "@wdio/utils" "7.30.2" async-exit-hook "^2.0.1" chalk "^4.0.0" chokidar "^3.0.0" cli-spinners "^2.1.0" ejs "^3.0.1" - fs-extra "^10.0.0" + fs-extra "^11.1.1" inquirer "8.2.4" lodash.flattendeep "^4.4.0" lodash.pickby "^4.6.0" lodash.union "^4.6.0" - mkdirp "^1.0.4" + mkdirp "^3.0.0" recursive-readdir "^2.2.2" - webdriverio "7.25.2" + webdriverio "7.31.1" yargs "^17.0.0" yarn-install "^1.0.0" @@ -6336,44 +6373,35 @@ deepmerge "^4.0.0" glob "^7.1.2" -"@wdio/config@7.25.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@wdio/config/-/config-7.25.1.tgz#1a094e639343466adcea678fc443daef041dc7b3" - integrity sha512-7I3L+TE75gvh8jiv8cE/Ch9S9erDgrZG9o5587OlNKfpgFciT7DH7/efPXzYwh8YPFV3grFaydxaaoYzDv6PDA== - dependencies: - "@wdio/logger" "7.19.0" - "@wdio/types" "7.25.1" - "@wdio/utils" "7.25.1" - deepmerge "^4.0.0" - glob "^8.0.3" - -"@wdio/config@7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@wdio/config/-/config-7.26.0.tgz#56710cf7cf2e5a60eafd91d7a399e49a028b6eb8" - integrity sha512-GO6kFGgFrx2Hiq+Ww6V9I7cZfShPjfPVhPy3uXnKN2B4FilX8ilLAp5cIFuMuHPeOQq0crYX9cnLYXka6dCGgg== +"@wdio/config@7.31.1": + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/config/-/config-7.31.1.tgz#53550a164c970403628525ecdc5e0c3f96a0ff30" + integrity sha512-WAfswbCatwiaDVqy6kfF/5T8/WS/US/SRhBGUFrfBuGMIe+RRoHgy7jURFWSvUIE7CNHj8yvs46fLUcxhXjzcQ== dependencies: + "@types/glob" "^8.1.0" "@wdio/logger" "7.26.0" - "@wdio/types" "7.26.0" - "@wdio/utils" "7.26.0" + "@wdio/types" "7.30.2" + "@wdio/utils" "7.30.2" deepmerge "^4.0.0" glob "^8.0.3" "@wdio/cucumber-framework@^7.19.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@wdio/cucumber-framework/-/cucumber-framework-7.25.1.tgz#5a34539b854da653929ffe53236e6e3988e767f6" - integrity sha512-FhyO1cFmCtti9Vj3lG9P8HYXppdQmLvFQP3fMlKpbDOcXHsyslzO7CMl1puf6etJhy9ik/6G1XPygiO+IY8X7g== + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/cucumber-framework/-/cucumber-framework-7.31.1.tgz#032ffbe53c1923e3acbf990cd4d2462a67eefdbf" + integrity sha512-UEjIQRCl847UdBZNjWQqBTsd8Ejk+gV9tfs5k8p2/cIvMLMEbb6Eq2FJY7YbjRAlEWpVTqXpC9N4kqu6LszazA== dependencies: "@cucumber/cucumber" "8.6.0" - "@cucumber/gherkin" "24.0.0" + "@cucumber/gherkin" "26.0.3" "@cucumber/gherkin-streams" "^5.0.0" - "@cucumber/messages" "19.1.4" + "@cucumber/messages" "21.0.1" + "@types/glob" "^8.1.0" "@types/is-glob" "^4.0.1" "@types/long" "^4.0.1" "@types/mockery" "^1.4.29" "@types/sinonjs__fake-timers" "^8.1.2" - "@wdio/logger" "7.19.0" - "@wdio/types" "7.25.1" - "@wdio/utils" "7.25.1" + "@wdio/logger" "7.26.0" + "@wdio/types" "7.30.2" + "@wdio/utils" "7.30.2" expect-webdriverio "^3.0.0" glob "^8.0.3" is-glob "^4.0.0" @@ -6381,28 +6409,28 @@ mockery "^2.1.0" "@wdio/junit-reporter@^7.25.4": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@wdio/junit-reporter/-/junit-reporter-7.28.0.tgz#76b8087ae98109590e637138ef1dbccd91a485ad" - integrity sha512-fG525KED4VAdkZUtc/s5JD4DrvwKzxlE3Onvz1HNi3W3TQGJtdNqY55RHMEVsVwRwTzrC3WU34MHKP/qCmtwlw== + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/junit-reporter/-/junit-reporter-7.31.1.tgz#b446a023b1e92f465fb235d75c77db941e7b4cf8" + integrity sha512-2hqZrUnIOthyNi0DmN/2Zg0nGWBpmNvvFh94f2VHCofIe79f+eCqaMAqhVNsd2TpmYxpUv3sX9TmDzgWhhAmZA== dependencies: "@types/json-stringify-safe" "^5.0.0" "@types/validator" "^13.1.3" - "@wdio/reporter" "7.28.0" - "@wdio/types" "7.26.0" + "@wdio/reporter" "7.31.1" + "@wdio/types" "7.30.2" json-stringify-safe "^5.0.1" junit-report-builder "^3.0.0" validator "^13.0.0" "@wdio/local-runner@^7.19.1": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@wdio/local-runner/-/local-runner-7.25.2.tgz#e2fe3f366018d80b01c3c58153b5bd85e97b3e3d" - integrity sha512-6FXuGSX7UNpMLmH2k0dpCZRxgiX7nF6kDN+NjUyUNdp2H6qLHxkOdpNTI0rIijamHEFADjGoeYAluybu6QtbmA== + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/local-runner/-/local-runner-7.31.1.tgz#d600b00e66e67ebf67533cedaf2d5aefd3bf4494" + integrity sha512-yzhUJVWvVBeCWUHOxA9M5cAFMQ2RyNrrZxNOfSxBLyUytXnPIUHvvwP28Cugx/Hu1jTap98YNy6qszoC7K5P2g== dependencies: "@types/stream-buffers" "^3.0.3" - "@wdio/logger" "7.19.0" - "@wdio/repl" "7.25.1" - "@wdio/runner" "7.25.2" - "@wdio/types" "7.25.1" + "@wdio/logger" "7.26.0" + "@wdio/repl" "7.30.2" + "@wdio/runner" "7.31.1" + "@wdio/types" "7.30.2" async-exit-hook "^2.0.1" split2 "^4.0.0" stream-buffers "^3.0.2" @@ -6437,16 +6465,6 @@ loglevel-plugin-prefix "^0.8.4" strip-ansi "^6.0.0" -"@wdio/logger@7.19.0", "@wdio/logger@^7.17.3", "@wdio/logger@^7.19.0", "@wdio/logger@^7.5.3": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@wdio/logger/-/logger-7.19.0.tgz#23697a4b4aaea56c3bd477a0393af2a5c175fc85" - integrity sha512-xR7SN/kGei1QJD1aagzxs3KMuzNxdT/7LYYx+lt6BII49+fqL/SO+5X0FDCZD0Ds93AuQvvz9eGyzrBI2FFXmQ== - dependencies: - chalk "^4.0.0" - loglevel "^1.6.0" - loglevel-plugin-prefix "^0.8.4" - strip-ansi "^6.0.0" - "@wdio/logger@7.26.0": version "7.26.0" resolved "https://registry.yarnpkg.com/@wdio/logger/-/logger-7.26.0.tgz#2c105a00f63a81d52de969fef5a54a9035146b2d" @@ -6472,11 +6490,6 @@ resolved "https://registry.yarnpkg.com/@wdio/protocols/-/protocols-7.16.7.tgz#8a160d59f0c028ff2dda6a1599a86a801a79bcb8" integrity sha512-Wv40pNQcLiPzQ3o98Mv4A8T1EBQ6k4khglz/e2r16CTm+F3DDYh8eLMAsU5cgnmuwwDKX1EyOiFwieykBn5MCg== -"@wdio/protocols@7.22.0": - version "7.22.0" - resolved "https://registry.yarnpkg.com/@wdio/protocols/-/protocols-7.22.0.tgz#d89faef687cb08981d734bbc5e5dffc6fb5a064c" - integrity sha512-8EXRR+Ymdwousm/VGtW3H1hwxZ/1g1H99A1lF0U4GuJ5cFWHCd0IVE5H31Z52i8ZruouW8jueMkGZPSo2IIUSQ== - "@wdio/protocols@7.27.0": version "7.27.0" resolved "https://registry.yarnpkg.com/@wdio/protocols/-/protocols-7.27.0.tgz#8e2663ec877dce7a5f76b021209c18dd0132e853" @@ -6503,49 +6516,42 @@ dependencies: "@wdio/utils" "7.16.14" -"@wdio/repl@7.25.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@wdio/repl/-/repl-7.25.1.tgz#9c0e1b9a3db90ff438fde63f34da1f3966bcca58" - integrity sha512-3DUtOrLi5thba22IBn/XQ7caFrbXtYOg3750UtXxUuxXU4QHkKq1AN8+WXr4Rq2EnXfB2G9t9pEdqjZSv9oPAw== - dependencies: - "@wdio/utils" "7.25.1" - -"@wdio/repl@7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@wdio/repl/-/repl-7.26.0.tgz#bf0703f46ad379107b9cfc254c3eccbd5cd6d848" - integrity sha512-2YxbXNfYVGVLrffUJzl/l5s8FziDPl917eLP62gkEH/H5IV27Pnwx3Iyu0KOEaBzgntnURANlwhCZFXQ4OPq8Q== +"@wdio/repl@7.30.2": + version "7.30.2" + resolved "https://registry.yarnpkg.com/@wdio/repl/-/repl-7.30.2.tgz#a92592078cb892d5bd14c2b300ef01ae6c8baf90" + integrity sha512-aW4nuMI+gbRmxmL4jMarBjuiQ+cFscr/8jHDt5hGx/gc/f7ifrZa4t6M5H8vFIKsvjUwl9lZRiVO4NVvvp6+cg== dependencies: - "@wdio/utils" "7.26.0" + "@wdio/utils" "7.30.2" -"@wdio/reporter@7.25.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@wdio/reporter/-/reporter-7.25.1.tgz#a241745b20136393568958e29840d49caa873f02" - integrity sha512-MLEiuoQGFn1ZD5FvzWFdsInuJT7TF/E1sg81mwlMjm5iFpuTvbPCUQq3uJ24xnXfMbw/HLZUnhPqC47+KTKTkw== +"@wdio/reporter@7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@wdio/reporter/-/reporter-7.25.4.tgz#b6a69652dd0c4ec131255000af128eac403a18b9" + integrity sha512-M37qzEmF5qNffyZmRQGjDlrXqWW21EFvgW8wsv1b/NtfpZc0c0MoRpeh6BnvX1KcE4nCXfjXgSJPOqV4ZCzUEQ== dependencies: "@types/diff" "^5.0.0" "@types/node" "^18.0.0" "@types/object-inspect" "^1.8.0" "@types/supports-color" "^8.1.0" "@types/tmp" "^0.2.0" - "@wdio/types" "7.25.1" + "@wdio/types" "7.25.4" diff "^5.0.0" fs-extra "^10.0.0" object-inspect "^1.10.3" supports-color "8.1.1" -"@wdio/reporter@7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@wdio/reporter/-/reporter-7.28.0.tgz#a2fd5e08209784efe92236796aedf1a2c6734638" - integrity sha512-KK8rLTYRHI6mdljg+Jgfift1s+UJIupBG+F8KcPjRilbgk7UOoqYorfq7d24bHrVjRuvoOIDAfAGeFFbGinR7g== +"@wdio/reporter@7.31.1": + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/reporter/-/reporter-7.31.1.tgz#3f0e71d34c134c0e8b3f3ff33ffffe815d568d62" + integrity sha512-0xd3RtavOast2ihu46/ndj+EI5auXTh9EO6odBixLtDbwAXYQ9LIPfbIUg7iTuCI48y/UVT9vw9nNWMd3UDMNA== dependencies: "@types/diff" "^5.0.0" "@types/node" "^18.0.0" "@types/object-inspect" "^1.8.0" "@types/supports-color" "^8.1.0" "@types/tmp" "^0.2.0" - "@wdio/types" "7.26.0" + "@wdio/types" "7.30.2" diff "^5.0.0" - fs-extra "^11.1.0" + fs-extra "^11.1.1" object-inspect "^1.10.3" supports-color "8.1.1" @@ -6565,28 +6571,28 @@ object-inspect "^1.10.3" supports-color "8.1.1" -"@wdio/runner@7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@wdio/runner/-/runner-7.25.2.tgz#1991c8fa09d9840f8bb3d645f47722418ab25043" - integrity sha512-0fQe9qmYPmbZ+PiDmZw6uy9XEx0A8+VhQAxyUSp/K9NCDUABY+I1tCSHCY/0mzlwk+ykscn8+qhaN1g9LvBtPA== +"@wdio/runner@7.31.1": + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/runner/-/runner-7.31.1.tgz#2839e11c18f7ea17c0786c83683bbae8f6df9f23" + integrity sha512-D36KWd6GviqAx0imupOSo0kkAc5AOamFBb0yHv4TK4F0AlokXu0Sh0EbZdmQxAhhudrlk/L1OhGLLCk7XxSoXA== dependencies: - "@wdio/config" "7.25.1" - "@wdio/logger" "7.19.0" - "@wdio/types" "7.25.1" - "@wdio/utils" "7.25.1" + "@wdio/config" "7.31.1" + "@wdio/logger" "7.26.0" + "@wdio/types" "7.30.2" + "@wdio/utils" "7.30.2" deepmerge "^4.0.0" gaze "^1.1.2" - webdriver "7.25.1" - webdriverio "7.25.2" + webdriver "7.31.1" + webdriverio "7.31.1" "@wdio/spec-reporter@^7.19.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@wdio/spec-reporter/-/spec-reporter-7.25.1.tgz#01315a3ff718bcc017bd59696b856b09e15b6293" - integrity sha512-CazLMJGWh0b+eWtiSmWGfFCl+nB1LHwST30gWsBJ44Xtd/rwl7rXi76Uq/qE2a2kwUs0Od6NLK7ZCa+ISejqwQ== + version "7.31.1" + resolved "https://registry.yarnpkg.com/@wdio/spec-reporter/-/spec-reporter-7.31.1.tgz#c025a94f202336b19cf79485f2cbf581bc13ae15" + integrity sha512-Ta0XSDYliaB4k8lEbYweegN0Cz/Dycz6oTbn2ZUU48DyGfq7AtLYw7UB9+3SQ6Q/ao5cMEEh6Q8zvLXhw9+ovw== dependencies: "@types/easy-table" "^1.2.0" - "@wdio/reporter" "7.25.1" - "@wdio/types" "7.25.1" + "@wdio/reporter" "7.31.1" + "@wdio/types" "7.30.2" chalk "^4.0.0" easy-table "^1.1.1" pretty-ms "^7.0.0" @@ -6599,18 +6605,18 @@ "@types/node" "^17.0.4" got "^11.8.1" -"@wdio/types@7.25.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@wdio/types/-/types-7.25.1.tgz#9e06f5479bc3c95f78811ba77dd96470417f882a" - integrity sha512-9Xt2U0YXYxRW4UvMFwjt+44UkfhwrI1gPhW+y56SubpyKaUfdNGberteboQoR/7Os1SVtJry4FohEZNmFzPK6g== +"@wdio/types@7.25.4": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@wdio/types/-/types-7.25.4.tgz#6f8f028e3108dc880de5068264695f1572e65352" + integrity sha512-muvNmq48QZCvocctnbe0URq2FjJjUPIG4iLoeMmyF0AQgdbjaUkMkw3BHYNHVTbSOU9WMsr2z8alhj/I2H6NRQ== dependencies: "@types/node" "^18.0.0" got "^11.8.1" -"@wdio/types@7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@wdio/types/-/types-7.26.0.tgz#70bc879c5dbe316a0eebbac4a46f0f66430b1d84" - integrity sha512-mOTfWAGQ+iT58iaZhJMwlUkdEn3XEWE4jthysMLXFnSuZ2eaODVAiK31SmlS/eUqgSIaupeGqYUrtCuSNbLefg== +"@wdio/types@7.30.2": + version "7.30.2" + resolved "https://registry.yarnpkg.com/@wdio/types/-/types-7.30.2.tgz#0baa4b8249aa1d98a545144e6fb494f1b186b24f" + integrity sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q== dependencies: "@types/node" "^18.0.0" got "^11.8.1" @@ -6639,22 +6645,13 @@ "@wdio/types" "7.16.14" p-iteration "^1.1.8" -"@wdio/utils@7.25.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@wdio/utils/-/utils-7.25.1.tgz#29bfe7e2dcd4f9b31868f069afa1eb761e96b8a7" - integrity sha512-DL+nDRVgzruJLhedBUQEMUcojLoGwsjCQCYWram4NfwAIIkxcAX/5Y4vHSut3OoW2bEHl3R8/FQ4B/ivIr2EoQ== - dependencies: - "@wdio/logger" "7.19.0" - "@wdio/types" "7.25.1" - p-iteration "^1.1.8" - -"@wdio/utils@7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@wdio/utils/-/utils-7.26.0.tgz#e282d072ccbacbe583f6d1b192c0320cede170c1" - integrity sha512-pVq2MPXZAYLkKGKIIHktHejnHqg4TYKoNYSi2EDv+I3GlT8VZKXHazKhci82ov0tD+GdF27+s4DWNDCfGYfBdQ== +"@wdio/utils@7.30.2": + version "7.30.2" + resolved "https://registry.yarnpkg.com/@wdio/utils/-/utils-7.30.2.tgz#d4642c3b8333f3f2ae9d46229098c0a77c3f887b" + integrity sha512-np7I+smszFUennbQKdzbMN/zUL3s3EZq9pCCUcTRjjs9TE4tnn0wfmGdoz2o7REYu6kn9NfFFJyVIM2VtBbKEA== dependencies: "@wdio/logger" "7.26.0" - "@wdio/types" "7.26.0" + "@wdio/types" "7.30.2" p-iteration "^1.1.8" "@xmldom/xmldom@^0.x": @@ -7608,18 +7605,6 @@ aproba@^1.0.3: resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== -arch@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" - integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== - -archive-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" - integrity sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA== - dependencies: - file-type "^4.2.0" - archiver-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" @@ -8295,13 +8280,6 @@ babel-preset-jest@^26.6.2: babel-plugin-jest-hoist "^26.6.2" babel-preset-current-node-syntax "^1.0.0" -babel-runtime@^5.8.25: - version "5.8.38" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-5.8.38.tgz#1c0b02eb63312f5f087ff20450827b425c9d4c19" - integrity sha512-KpgoA8VE/pMmNCrnEeeXqFG24TIH11Z3ZaimIhJWsin8EbfZy3WzFKUTIan10ZIDgRVvi9EkLbruJElJC9dRlg== - dependencies: - core-js "^1.0.0" - babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" @@ -8398,7 +8376,7 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== -big-integer@1.6.x, big-integer@^1.6.17: +big-integer@1.6.x: version "1.6.51" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== @@ -8427,14 +8405,6 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -binary@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" - integrity sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg== - dependencies: - buffers "~0.1.1" - chainsaw "~0.1.0" - bindings@^1.2.1, bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -8460,7 +8430,7 @@ bip66@^1.1.5: dependencies: safe-buffer "^5.0.1" -bl@^1.0.0, bl@^1.2.3, bl@~0.8.1: +bl@^1.2.3, bl@~0.8.1: version "1.2.3" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== @@ -8487,11 +8457,6 @@ bluebird@3.x, bluebird@^3.1.1, bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.1 resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bluebird@~3.4.1: - version "3.4.7" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" - integrity sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA== - bmp-js@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" @@ -8829,11 +8794,6 @@ buffer-from@^1.0.0, buffer-from@^1.1.1: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== -buffer-indexof-polyfill@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz#d2732135c5999c64b277fcf9b1abe3498254729c" - integrity sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A== - buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -8872,11 +8832,6 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" -buffers@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" - integrity sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ== - bufferutil@4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028" @@ -9055,15 +9010,6 @@ caniuse-lite@^1.0.30001349: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001352.tgz#cc6f5da3f983979ad1e2cdbae0505dccaa7c6a12" integrity sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA== -canvas@^2.9.1: - version "2.10.1" - resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.10.1.tgz#fbfd4b1b3b106c3454481d79d363ebadf8811c08" - integrity sha512-29pIjn9uwTUsIgJUNd7GXxKk8sg4iyJwLm1wIilNIqX1mVzXSc2nUij9exW1LqNpis1d2ebMYfMqTWcokZ4pdA== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.0" - nan "^2.15.0" - simple-get "^3.0.3" - capital-case@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" @@ -9108,13 +9054,6 @@ chai@^4.3.4: pathval "^1.1.1" type-detect "^4.0.5" -chainsaw@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" - integrity sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ== - dependencies: - traverse ">=0.3.0 <0.4" - chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -9420,15 +9359,6 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== -clipboardy@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-2.3.0.tgz#3c2903650c68e46a91b388985bc2774287dba290" - integrity sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ== - dependencies: - arch "^2.1.1" - execa "^1.0.0" - is-wsl "^2.1.1" - cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -9655,7 +9585,7 @@ commander@9.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-9.3.0.tgz#f619114a5a2d2054e0d9ff1b31d5ccf89255e26b" integrity sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw== -commander@^2.19.0, commander@^2.8.1: +commander@^2.19.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -9768,7 +9698,7 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control- resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -content-disposition@0.5.4, content-disposition@^0.5.2: +content-disposition@0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== @@ -9852,11 +9782,6 @@ core-js-compat@^3.14.0: browserslist "^4.16.6" semver "7.0.0" -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - integrity sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA== - core-js@^2.4.0, core-js@^2.5.7, core-js@^2.6.5: version "2.6.12" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" @@ -10297,59 +10222,6 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" -decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" - integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== - dependencies: - file-type "^5.2.0" - is-stream "^1.1.0" - tar-stream "^1.5.2" - -decompress-tarbz2@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" - integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== - dependencies: - decompress-tar "^4.1.0" - file-type "^6.1.0" - is-stream "^1.1.0" - seek-bzip "^1.0.5" - unbzip2-stream "^1.0.9" - -decompress-targz@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" - integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== - dependencies: - decompress-tar "^4.1.1" - file-type "^5.2.0" - is-stream "^1.1.0" - -decompress-unzip@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" - integrity sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw== - dependencies: - file-type "^3.8.0" - get-stream "^2.2.0" - pify "^2.3.0" - yauzl "^2.4.2" - -decompress@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" - integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== - dependencies: - decompress-tar "^4.0.0" - decompress-tarbz2 "^4.0.0" - decompress-targz "^4.0.0" - decompress-unzip "^4.0.1" - graceful-fs "^4.1.10" - make-dir "^1.0.0" - pify "^2.3.0" - strip-dirs "^2.0.0" - dedent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.6.0.tgz#0e6da8f0ce52838ef5cec5c8f9396b0c1b64a3cb" @@ -10642,15 +10514,10 @@ devtools-protocol@0.0.981744: resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.981744.tgz#9960da0370284577d46c28979a0b32651022bacf" integrity sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg== -devtools-protocol@^0.0.1056733: - version "0.0.1056733" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1056733.tgz#55bb1d56761014cc221131cca5e6bad94eefb2b9" - integrity sha512-CmTu6SQx2g3TbZzDCAV58+LTxVdKplS7xip0g5oDXpZ+isr0rv5dDP8ToyVRywzPHkCCPKgKgScEcwz4uPWDIA== - -devtools-protocol@^0.0.1084670: - version "0.0.1084670" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1084670.tgz#853b4e14f9324fd7b8b52a191d403364ceb0aa79" - integrity sha512-6iZb5kgfopmFMzJZD3rk0Ipa9WBd7VzTw+2yoOeBmg1/araNAhrFVWYQQkWo7aTFsNLdmGLtZlTOP6c2WG9UfA== +devtools-protocol@^0.0.1130274: + version "0.0.1130274" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1130274.tgz#1cd0c472a84fc9a09becaaed35a247a6eab9310c" + integrity sha512-kIozBWajgsi1g0W8yzALI4ZdCp6KG1yWaq8NN1ehQM3zX6JRegLSzfexz7XT5eFjmq1RkpMYgeKmfi3GsHrCLw== devtools-protocol@^0.0.973690: version "0.0.973690" @@ -10691,37 +10558,18 @@ devtools@7.16.16: ua-parser-js "^1.0.1" uuid "^8.0.0" -devtools@7.25.1: - version "7.25.1" - resolved "https://registry.yarnpkg.com/devtools/-/devtools-7.25.1.tgz#64ad59db9a769e68d70afbf1bc1b456bd9ced7e8" - integrity sha512-01T8QZeiD92MpI/7rP8kUflN3XcMqv2moa07123OjjENuuOhYxRWmJ7xj94txnF5PJp1Cv8/jvK8EUbnEHf6MQ== +devtools@7.31.1: + version "7.31.1" + resolved "https://registry.yarnpkg.com/devtools/-/devtools-7.31.1.tgz#c7a5db22d720a83f57871138da76125948be346a" + integrity sha512-QU8rMSspKk3c/mX0uawIlRslwH7F+sdTGBZseXgAA5XIgqWbanCQdfHLvxcEzJJHRE5Gq6vGPJIAjq/z9Z4j/Q== dependencies: "@types/node" "^18.0.0" "@types/ua-parser-js" "^0.7.33" - "@wdio/config" "7.25.1" - "@wdio/logger" "7.19.0" - "@wdio/protocols" "7.22.0" - "@wdio/types" "7.25.1" - "@wdio/utils" "7.25.1" - chrome-launcher "^0.15.0" - edge-paths "^2.1.0" - puppeteer-core "^13.1.3" - query-selector-shadow-dom "^1.0.0" - ua-parser-js "^1.0.1" - uuid "^9.0.0" - -devtools@7.28.1: - version "7.28.1" - resolved "https://registry.yarnpkg.com/devtools/-/devtools-7.28.1.tgz#9699e0ca41c9a3adfa351d8afac2928f8e1d381c" - integrity sha512-sDoszzrXDMLiBQqsg9A5gDqDBwhH4sjYzJIW15lQinB8qgNs0y4o1zdfNlqiKs4HstCA2uFixQeibbDCyMa7hQ== - dependencies: - "@types/node" "^18.0.0" - "@types/ua-parser-js" "^0.7.33" - "@wdio/config" "7.26.0" + "@wdio/config" "7.31.1" "@wdio/logger" "7.26.0" "@wdio/protocols" "7.27.0" - "@wdio/types" "7.26.0" - "@wdio/utils" "7.26.0" + "@wdio/types" "7.30.2" + "@wdio/utils" "7.30.2" chrome-launcher "^0.15.0" edge-paths "^2.1.0" puppeteer-core "^13.1.3" @@ -10909,23 +10757,6 @@ dotenv@^16.0.3: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== -download@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/download/-/download-8.0.0.tgz#afc0b309730811731aae9f5371c9f46be73e51b1" - integrity sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA== - dependencies: - archive-type "^4.0.0" - content-disposition "^0.5.2" - decompress "^4.2.1" - ext-name "^5.0.0" - file-type "^11.1.0" - filenamify "^3.0.0" - get-stream "^4.1.0" - got "^8.3.1" - make-dir "^2.1.0" - p-event "^2.1.0" - pify "^4.0.1" - drbg.js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" @@ -10942,13 +10773,6 @@ dtrace-provider@~0.8: dependencies: nan "^2.14.0" -duplexer2@~0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" - integrity sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA== - dependencies: - readable-stream "^2.0.2" - duplexer@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -11106,7 +10930,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0, end-of-stream@^1.4.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -12851,9 +12675,9 @@ expand-template@^2.0.3: integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== expect-webdriverio@^3.0.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/expect-webdriverio/-/expect-webdriverio-3.4.0.tgz#32944cefaae3380285ee8d3a88edc1a3b9ed4612" - integrity sha512-7Ivy1IB35pmkbCcI36un2OMytGEYCy1PcdqrlDnWZBzTpewAO14r+gO2FSuO5kNpDWm3gZSD4NYLG1KXJOlI3w== + version "3.6.0" + resolved "https://registry.yarnpkg.com/expect-webdriverio/-/expect-webdriverio-3.6.0.tgz#529dd8a05cf952ed31c28541f8411f8d30182dc9" + integrity sha512-8HuVToXDVzkKgUKIUzW/v3bP4ZoMDEwCjX9QmlRlMIvjt3HOSzSIBnRMv8lpeVTUKoR9DZNr/lSuKH4Amx4BBg== dependencies: expect "^28.1.0" jest-matcher-utils "^28.1.0" @@ -12925,14 +12749,6 @@ ext-list@^2.0.0: dependencies: mime-db "^1.28.0" -ext-name@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" - integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== - dependencies: - ext-list "^2.0.0" - sort-keys-length "^1.0.0" - ext@^1.1.2: version "1.7.0" resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" @@ -13184,31 +13000,6 @@ file-entry-cache@^5.0.1: dependencies: flat-cache "^2.0.1" -file-type@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-11.1.0.tgz#93780f3fed98b599755d846b99a1617a2ad063b8" - integrity sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g== - -file-type@^3.8.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" - integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== - -file-type@^4.2.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" - integrity sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ== - -file-type@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" - integrity sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ== - -file-type@^6.1.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" - integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== - file-type@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" @@ -13226,20 +13017,6 @@ filelist@^1.0.1: dependencies: minimatch "^5.0.1" -filename-reserved-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" - integrity sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ== - -filenamify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-3.0.0.tgz#9603eb688179f8c5d40d828626dcbb92c3a4672c" - integrity sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g== - dependencies: - filename-reserved-regex "^2.0.0" - strip-outer "^1.0.0" - trim-repeated "^1.0.0" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -13521,7 +13298,7 @@ fs-extra@^1.0.0: jsonfile "^2.1.0" klaw "^1.0.0" -fs-extra@^10.0.0, fs-extra@^10.0.1, fs-extra@^10.1.0: +fs-extra@^10.0.0, fs-extra@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== @@ -13530,10 +13307,10 @@ fs-extra@^10.0.0, fs-extra@^10.0.1, fs-extra@^10.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.0.tgz#5784b102104433bb0e090f48bfc4a30742c357ed" - integrity sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw== +fs-extra@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -13566,7 +13343,7 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: +fs-extra@^9.0.0, fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -13612,16 +13389,6 @@ fsevents@^2.1.2, fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -fstream@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" - integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - ftp-response-parser@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ftp-response-parser/-/ftp-response-parser-1.0.1.tgz#3b9d33f8edd5fb8e4700b8f778c462e5b1581f89" @@ -13814,15 +13581,7 @@ get-stdin@^6.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== -get-stream@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - integrity sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA== - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - -get-stream@^4.0.0, get-stream@^4.1.0: +get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== @@ -13869,6 +13628,18 @@ gifwrap@^0.9.2: image-q "^4.0.0" omggif "^1.0.10" +git-repo-info@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/git-repo-info/-/git-repo-info-2.1.1.tgz#220ffed8cbae74ef8a80e3052f2ccb5179aed058" + integrity sha512-8aCohiDo4jwjOwma4FmYFd3i97urZulL8XL24nIPxuE+GZnfsAyy/g2Shqx6OjUiFKUXZM+Yy+KHnOmmA3FVcg== + +gitconfiglocal@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-2.1.0.tgz#07c28685c55cc5338b27b5acbcfe34aeb92e43d1" + integrity sha512-qoerOEliJn3z+Zyn1HW2F6eoYJqKwS6MgC9cztTLUB/xLWX8gD/6T60pKn4+t/d6tP7JlybI7Z3z+I572CR/Vg== + dependencies: + ini "^1.3.2" + github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" @@ -13959,7 +13730,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -got@^11.0.2, got@^11.8.1, got@^11.8.5, got@^8.3.1: +got@^11.0.2, got@^11.8.1, got@^11.8.5: version "11.8.5" resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046" integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ== @@ -13976,15 +13747,10 @@ got@^11.0.2, got@^11.8.1, got@^11.8.5, got@^8.3.1: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.10, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.3, graceful-fs@^4.2.4, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== graceful-fs@~2.0.0: version "2.0.3" @@ -14557,7 +14323,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -14577,7 +14343,7 @@ ini@2.0.0, ini@^2.0.0: resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ini@^1.3.4, ini@~1.3.0: +ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -14983,11 +14749,6 @@ is-nan@^1.2.1: call-bind "^1.0.0" define-properties "^1.1.3" -is-natural-number@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" - integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== - is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" @@ -16589,11 +16350,6 @@ lint-staged@10.5.4: string-argv "0.3.1" stringify-object "^3.3.0" -listenercount@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" - integrity sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ== - listr2@^3.2.2: version "3.10.0" resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.10.0.tgz#58105a53ed7fa1430d1b738c6055ef7bb006160f" @@ -16935,23 +16691,16 @@ ltgt@^2.1.3, ltgt@~2.2.0: resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= -luxon@^3.0.4: - version "3.2.1" - resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.2.1.tgz#14f1af209188ad61212578ea7e3d518d18cee45f" - integrity sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg== +luxon@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.3.0.tgz#d73ab5b5d2b49a461c47cedbc7e73309b4805b48" + integrity sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg== lz-string@^1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ== -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -18031,7 +17780,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@5.1.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2, minimatch@^5.0.0, minimatch@^5.0.1, minimatch@^5.1.0, minimatch@~3.0.2: +minimatch@5.1.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2, minimatch@^5.0.0, minimatch@^5.0.1, minimatch@^5.1.0, minimatch@^6.0.4, minimatch@~3.0.2: version "5.1.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== @@ -18085,23 +17834,28 @@ mkdirp@0.x.x, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1: dependencies: minimist "^1.2.5" -"mkdirp@>=0.5 0", mkdirp@^0.5.3, mkdirp@^0.5.6: +mkdirp@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" + integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc= + +mkdirp@^0.5.3, mkdirp@^0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" -mkdirp@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" - integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc= - mkdirp@^1.0.0, mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mkdirp@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + mockery@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mockery/-/mockery-2.1.0.tgz#5b0aef1ff564f0f8139445e165536c7909713470" @@ -18214,16 +17968,16 @@ multihashes@^0.4.15, multihashes@~0.4.15: varint "^5.0.0" multiple-cucumber-html-reporter@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/multiple-cucumber-html-reporter/-/multiple-cucumber-html-reporter-3.0.1.tgz#06560e37b6699bc4a5792b6c87cee4f3504aa4ee" - integrity sha512-ccmDnlD/RK7321/TwpoOJ5D6Me2lQRsMTl21rpPvxItnPcpFIx9nMyHmQsL0tjIgn03n8v/p0rxFK+gJzzO+AQ== + version "3.4.0" + resolved "https://registry.yarnpkg.com/multiple-cucumber-html-reporter/-/multiple-cucumber-html-reporter-3.4.0.tgz#03db1772834952c70555ee16074d26c308d18ca4" + integrity sha512-Y2FQA/OosmlsB/ZQUPJvnkKKYFKa/J+Qv2QUl5PsO3BC77jXwyPE8fAWopLH+CEYlRTs7fcdfydmWFitGMFi0A== dependencies: find "^0.3.0" - fs-extra "^10.1.0" + fs-extra "^11.1.1" jsonfile "^6.1.0" - lodash "^4.17.19" - luxon "^3.0.4" - open "^8.4.0" + lodash "^4.17.21" + luxon "^3.3.0" + open "^8.4.2" uuid "^9.0.0" mute-stream@0.0.7: @@ -18259,11 +18013,6 @@ nan@^2.0.5, nan@^2.14.0, nan@^2.2.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== -nan@^2.15.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - nanoclone@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4" @@ -18664,7 +18413,7 @@ npmlog@4.x, npmlog@^4.0.1, npmlog@^4.1.2: gauge "~2.7.3" set-blocking "~2.0.0" -npmlog@^5.0.0, npmlog@^5.0.1: +npmlog@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== @@ -19006,10 +18755,10 @@ open@^7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" -open@^8.2.0, open@^8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== +open@^8.2.0, open@^8.4.2: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== dependencies: define-lazy-prop "^2.0.0" is-docker "^2.1.1" @@ -19128,13 +18877,6 @@ p-each-series@^2.1.0: resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== -p-event@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" - integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== - dependencies: - p-timeout "^2.0.1" - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -19192,13 +18934,6 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" -p-timeout@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" - integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== - dependencies: - p-finally "^1.0.0" - p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -19544,7 +19279,7 @@ pify@4.0.1, pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pify@^2.0.0, pify@^2.3.0: +pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= @@ -21195,7 +20930,7 @@ readable-stream@1.0.33: isarray "0.0.1" string_decoder "~0.10.x" -"readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: +"readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -21214,7 +20949,7 @@ readable-stream@^1.0.26-4, readable-stream@^1.0.27-1, readable-stream@^1.0.31, r isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: +readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -21698,13 +21433,6 @@ rgb2hex@^0.1.0: resolved "https://registry.yarnpkg.com/rgb2hex/-/rgb2hex-0.1.10.tgz#4fdd432665273e2d5900434940ceba0a04c8a8a8" integrity sha512-vKz+kzolWbL3rke/xeTE2+6vHmZnNxGyDnaVW4OckntAIcc7DcZzWkQSfxMDwqHS8vhgySnIFyBUH7lIk6PxvQ== -rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@2.6.3, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -21712,6 +21440,13 @@ rimraf@2.6.3, rimraf@~2.6.2: dependencies: glob "^7.1.3" +rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -22024,13 +21759,6 @@ seed-random@~2.2.0: resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54" integrity sha512-34EQV6AAHQGhoc0tn/96a9Fsi6v2xdqe/dMUwljGRaFOzR3EgRmECvD0O8vi8X+/uQ50LGHfkNu/Eue5TPKZkQ== -seek-bzip@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" - integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== - dependencies: - commander "^2.8.1" - selenium-webdriver@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc" @@ -22208,7 +21936,7 @@ set-value@^2.0.0, set-value@^2.0.1, set-value@^4.0.1: is-plain-object "^2.0.4" is-primitive "^3.0.1" -setimmediate@^1.0.5, setimmediate@~1.0.4: +setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= @@ -22696,13 +22424,6 @@ split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" -split2@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" - integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== - dependencies: - readable-stream "^3.0.0" - split2@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/split2/-/split2-4.1.0.tgz#101907a24370f85bb782f08adaabe4e281ecf809" @@ -23068,13 +22789,6 @@ strip-bom@^4.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== -strip-dirs@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" - integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== - dependencies: - is-natural-number "^4.0.1" - strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -23102,13 +22816,6 @@ strip-json-comments@^3.0.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1 resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-outer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" - integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== - dependencies: - escape-string-regexp "^1.0.2" - sudo-prompt@^9.0.0: version "9.2.1" resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.2.1.tgz#77efb84309c9ca489527a4e749f287e6bdd52afd" @@ -23235,19 +22942,6 @@ tar-fs@2.1.1, tar-fs@^2.0.0, tar-fs@^2.1.1: pump "^3.0.0" tar-stream "^2.1.4" -tar-stream@^1.5.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" - integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== - dependencies: - bl "^1.0.0" - buffer-alloc "^1.2.0" - end-of-stream "^1.0.0" - fs-constants "^1.0.0" - readable-stream "^2.3.0" - to-buffer "^1.1.1" - xtend "^4.0.0" - tar-stream@^2.1.0, tar-stream@^2.1.4, tar-stream@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" @@ -23259,7 +22953,7 @@ tar-stream@^2.1.0, tar-stream@^2.1.4, tar-stream@^2.2.0: inherits "^2.0.3" readable-stream "^3.1.1" -tar@6.1.11, tar@^6.0.2, tar@^6.1.11: +tar@6.1.11, tar@^6.0.2: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== @@ -23433,13 +23127,6 @@ tinycolor2@^1.4.1: resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== -tmp-promise@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" - integrity sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ== - dependencies: - tmp "^0.2.0" - tmp@0.0.30: version "0.0.30" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed" @@ -23454,7 +23141,7 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmp@^0.2.0, tmp@^0.2.1: +tmp@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== @@ -23466,11 +23153,6 @@ tmpl@1.0.x: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== -to-buffer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -23562,11 +23244,6 @@ traverse-chain@~0.1.0: resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1" integrity sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg== -"traverse@>=0.3.0 <0.4": - version "0.3.9" - resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" - integrity sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ== - traverse@~0.6.3: version "0.6.6" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" @@ -23582,13 +23259,6 @@ treeify@~1.0.1: resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.0.1.tgz#69b3cd022022a168424e7cfa1ced44c939d3eb2f" integrity sha1-abPNAiAioWhCTnz6HO1EyTnT6y8= -trim-repeated@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" - integrity sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg== - dependencies: - escape-string-regexp "^1.0.2" - triple-beam@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" @@ -23806,7 +23476,7 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -unbzip2-stream@1.4.3, unbzip2-stream@^1.0.9, unbzip2-stream@^1.3.3: +unbzip2-stream@1.4.3, unbzip2-stream@^1.3.3: version "1.4.3" resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== @@ -23819,11 +23489,6 @@ underscore@1.12.1, underscore@~1.4.4, underscore@~1.5.2: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e" integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw== -undici@^4.15.1: - version "4.16.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-4.16.0.tgz#469bb87b3b918818d3d7843d91a1d08da357d5ff" - integrity sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw== - unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" @@ -23923,22 +23588,6 @@ untildify@^4.0.0: resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== -unzipper@^0.10.11: - version "0.10.11" - resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.10.11.tgz#0b4991446472cbdb92ee7403909f26c2419c782e" - integrity sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw== - dependencies: - big-integer "^1.6.17" - binary "~0.3.0" - bluebird "~3.4.1" - buffer-indexof-polyfill "~1.0.0" - duplexer2 "~0.1.4" - fstream "^1.0.12" - graceful-fs "^4.2.2" - listenercount "~1.0.1" - readable-stream "~2.3.6" - setimmediate "~1.0.4" - upper-case-first@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324" @@ -24261,23 +23910,6 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -wdio-chromedriver-service@^7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/wdio-chromedriver-service/-/wdio-chromedriver-service-7.3.2.tgz#569053df4ceaf6ce9e43bebcdd540197f516e313" - integrity sha512-4M3OqFzBSC4FdbqkfwOrUMeroMEuyIFCHfcUebkU6tJ1w5GenWO61YweJ8NKlhPZx9nkO8223+20MpvBjv+fTg== - dependencies: - "@wdio/logger" "^7.5.3" - fs-extra "^9.1.0" - split2 "^3.2.2" - tcp-port-used "^1.0.1" - -wdio-cucumber-reporter@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wdio-cucumber-reporter/-/wdio-cucumber-reporter-0.0.2.tgz#6dc9efee8e2bbe225a175f9fd1d4e9871c1252c2" - integrity sha512-BvVcsXZY1sV8G2hgZzQGw/5pKB2Zs8E/7Vjrb9efUSrxYBjqJoo/331ZDrMsYAqvdbCfuzxOAi+g8ekLDGYY1g== - dependencies: - babel-runtime "^5.8.25" - wdio-cucumberjs-json-reporter@^4.4.3: version "4.4.3" resolved "https://registry.yarnpkg.com/wdio-cucumberjs-json-reporter/-/wdio-cucumberjs-json-reporter-4.4.3.tgz#3727a85acac6bc95480dcb5ec4df56063711d0a1" @@ -24290,28 +23922,6 @@ wdio-cucumberjs-json-reporter@^4.4.3: strip-ansi "^6.0.1" webdriverio "~7.16.13" -wdio-image-comparison-service@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/wdio-image-comparison-service/-/wdio-image-comparison-service-3.1.1.tgz#402192bb2fdc1a3ef2ba46c654b5ac253f1b8c8d" - integrity sha512-W0JQNAbz3kEAAOz7erJB00APw0y5um3DbI60BAHNQrq8K5Q/vVNNgjmjQaQkpJ8bcUoqoQIJJBdU9zZT88DcWg== - dependencies: - "@wdio/logger" "^7.19.0" - webdriver-image-comparison "0.20.3" - -wdio-vscode-service@^0.1.5: - version "0.1.13" - resolved "https://registry.yarnpkg.com/wdio-vscode-service/-/wdio-vscode-service-0.1.13.tgz#e8ccc148cb063bd20c15bf0a2d098238e0b13b5d" - integrity sha512-C6xvGT5CmHAvyIe7+S7TuggOIhEZbias9GsB6kMEIT7n2DNgBBmSDZtHzQIqVWlJTWBTx2MtObLwQsUKG9JkOA== - dependencies: - "@vscode/test-electron" "^2.1.3" - "@wdio/logger" "^7.17.3" - clipboardy "^2.3.0" - download "^8.0.0" - slash "^3.0.0" - tmp-promise "^3.0.3" - undici "^4.15.1" - wdio-chromedriver-service "^7.3.2" - weak@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/weak/-/weak-1.0.1.tgz#ab99aab30706959aa0200cb8cf545bb9cb33b99e" @@ -24359,15 +23969,6 @@ web3@^0.20.7: xhr2-cookies "^1.1.0" xmlhttprequest "*" -webdriver-image-comparison@0.20.3: - version "0.20.3" - resolved "https://registry.yarnpkg.com/webdriver-image-comparison/-/webdriver-image-comparison-0.20.3.tgz#4d89d3cf2ebdb67c2316c572baf492a8fdf59e0f" - integrity sha512-rSMOB/maanlcIqzFCqSY676I6p8h2Ewa/XFxBKdZb8XLk64QjEdtGlXcdT8Cbz0Kuf8k1+bhfbwAKgpIBBWvvg== - dependencies: - canvas "^2.9.1" - chalk "^4.1.2" - fs-extra "^10.0.1" - webdriver@5.23.0: version "5.23.0" resolved "https://registry.yarnpkg.com/webdriver/-/webdriver-5.23.0.tgz#5373e3e43803aaf962da24b47bbdb98bf8f84cc6" @@ -24408,101 +24009,53 @@ webdriver@7.16.16: ky "^0.29.0" lodash.merge "^4.6.1" -webdriver@7.25.1: - version "7.25.1" - resolved "https://registry.yarnpkg.com/webdriver/-/webdriver-7.25.1.tgz#0e9a98093f0a572b846048eb7a5e422db04f58bd" - integrity sha512-BmR5RT37EGNJj/O/GTCqBKXV/Jr9V4oQTTDaurZixVKW0ubG7uyfrhiklzuWUtmES9VualTKgQumhGhchBTC6g== +webdriver@7.31.1: + version "7.31.1" + resolved "https://registry.yarnpkg.com/webdriver/-/webdriver-7.31.1.tgz#2dafdef92b59dc6456023ac92a9707d7331ecdb6" + integrity sha512-nCdJLxRnYvOMFqTEX7sqQtF/hV/Jgov0Y6ICeOm1DMTlZSRRDaUsBMlEAPkEwif9uBJYdM0znv8qzfX358AGqQ== dependencies: "@types/node" "^18.0.0" - "@wdio/config" "7.25.1" - "@wdio/logger" "7.19.0" - "@wdio/protocols" "7.22.0" - "@wdio/types" "7.25.1" - "@wdio/utils" "7.25.1" - got "^11.0.2" - ky "0.30.0" - lodash.merge "^4.6.1" - -webdriver@7.27.0: - version "7.27.0" - resolved "https://registry.yarnpkg.com/webdriver/-/webdriver-7.27.0.tgz#41d23a6c38bd79ea868f0b9fb9c9e3d4b6e4f8bd" - integrity sha512-870uIBnrGJ86g3DdYjM+PHhqdWf6NxysSme1KIs6irWxK+LqcaWKWhN75PldE+04xJB2mVWt1tKn0NBBFTWeMg== - dependencies: - "@types/node" "^18.0.0" - "@wdio/config" "7.26.0" + "@wdio/config" "7.31.1" "@wdio/logger" "7.26.0" "@wdio/protocols" "7.27.0" - "@wdio/types" "7.26.0" - "@wdio/utils" "7.26.0" + "@wdio/types" "7.30.2" + "@wdio/utils" "7.30.2" got "^11.0.2" ky "0.30.0" lodash.merge "^4.6.1" -webdriverio@7.25.2: - version "7.25.2" - resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-7.25.2.tgz#9fcb360d7ac47118b886bfa911a6f06bffafc932" - integrity sha512-lZwHh1G2Zxg4LmVQZZZNhKAqjGoSxoDaqlAf0ojh/3DcWVxMpFtaj0mksrqCyVhObudb2dopOX26beWPyKwL4A== - dependencies: - "@types/aria-query" "^5.0.0" - "@types/node" "^18.0.0" - "@wdio/config" "7.25.1" - "@wdio/logger" "7.19.0" - "@wdio/protocols" "7.22.0" - "@wdio/repl" "7.25.1" - "@wdio/types" "7.25.1" - "@wdio/utils" "7.25.1" - archiver "^5.0.0" - aria-query "^5.0.0" - css-shorthand-properties "^1.1.1" - css-value "^0.0.1" - devtools "7.25.1" - devtools-protocol "^0.0.1056733" - fs-extra "^10.0.0" - grapheme-splitter "^1.0.2" - lodash.clonedeep "^4.5.0" - lodash.isobject "^3.0.2" - lodash.isplainobject "^4.0.6" - lodash.zip "^4.2.0" - minimatch "^5.0.0" - puppeteer-core "^13.1.3" - query-selector-shadow-dom "^1.0.0" - resq "^1.9.1" - rgb2hex "0.2.5" - serialize-error "^8.0.0" - webdriver "7.25.1" - -webdriverio@7.28.1: - version "7.28.1" - resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-7.28.1.tgz#b6a7567ee0c9e93a8bd525aa393090a7a87a7f60" - integrity sha512-fz0nALbRpEPvJf8+ptwPoyxlpknQonOzpXeBFqGjxcUoQ6eT817xZG8Cp35KJmra1KXQCrQVjO+9yy8bROZcig== +webdriverio@7.31.1: + version "7.31.1" + resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-7.31.1.tgz#631171ff8f2a7c0b34014079465489b54ecc9a3a" + integrity sha512-ri8L7A8VbJ2lZyndu0sG56d2zBot7SXdeI95Kni43e0pd/5Xm4IMAPdWB60yS8vqrP8goJU2iuQ8/ltry4IDbQ== dependencies: "@types/aria-query" "^5.0.0" "@types/node" "^18.0.0" - "@wdio/config" "7.26.0" + "@wdio/config" "7.31.1" "@wdio/logger" "7.26.0" "@wdio/protocols" "7.27.0" - "@wdio/repl" "7.26.0" - "@wdio/types" "7.26.0" - "@wdio/utils" "7.26.0" + "@wdio/repl" "7.30.2" + "@wdio/types" "7.30.2" + "@wdio/utils" "7.30.2" archiver "^5.0.0" aria-query "^5.0.0" css-shorthand-properties "^1.1.1" css-value "^0.0.1" - devtools "7.28.1" - devtools-protocol "^0.0.1084670" - fs-extra "^11.1.0" + devtools "7.31.1" + devtools-protocol "^0.0.1130274" + fs-extra "^11.1.1" grapheme-splitter "^1.0.2" lodash.clonedeep "^4.5.0" lodash.isobject "^3.0.2" lodash.isplainobject "^4.0.6" lodash.zip "^4.2.0" - minimatch "^5.0.0" + minimatch "^6.0.4" puppeteer-core "^13.1.3" query-selector-shadow-dom "^1.0.0" resq "^1.9.1" rgb2hex "0.2.5" serialize-error "^8.0.0" - webdriver "7.27.0" + webdriver "7.31.1" webdriverio@^5.10.9: version "5.23.0" @@ -25227,7 +24780,7 @@ yarn-install@^1.0.0: chalk "^1.1.3" cross-spawn "^4.0.2" -yauzl@^2.10.0, yauzl@^2.4.2, yauzl@^2.7.0: +yauzl@^2.10.0, yauzl@^2.7.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==