diff --git a/.github/workflows/coveralls.yml b/.github/workflows/coveralls.yml index 94139a4332b0..a6089e63e206 100644 --- a/.github/workflows/coveralls.yml +++ b/.github/workflows/coveralls.yml @@ -4,11 +4,15 @@ on: - master pull_request: types: [opened, synchronize, edited] -name: Coveralls +name: Reporter jobs: - build: - name: Reporter + test: + name: Run tests in parallel runs-on: Runner_16cores_Deriv-app + strategy: + matrix: + shard: [1,2,3,4,5,6,7,8,9,10] + fail-fast: true steps: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 @@ -16,9 +20,25 @@ jobs: uses: './.github/actions/setup_node' - name: Install dependencies uses: "./.github/actions/npm_install_from_cache" - - name: Build - uses: "./.github/actions/build" + - name: Build components package + working-directory: packages/components + run: npm run build - name: Test - run: JEST_MAX_WORKERS=95% npm run test:jest -- --collectCoverage - - name: Coveralls + run: JEST_MAX_WORKERS=95% SHARD_INDEX=${{ matrix.shard }} SHARD_COUNT=10 npm run test:shard -- --collectCoverage + - name: Coveralls Parallel uses: coverallsapp/github-action@3dfc5567390f6fa9267c0ee9c251e4c8c3f18949 + with: + allow-empty: true + flag-name: ${{ matrix.shard}} + parallel: true + + finish: + name: Coveralls Finished + needs: [test] + if: ${{ always() }} + runs-on: Runner_16cores_Deriv-app + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@3dfc5567390f6fa9267c0ee9c251e4c8c3f18949 + with: + parallel-finished: true \ No newline at end of file diff --git a/package.json b/package.json index 8eaa8a30b715..1976f72e2f82 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "test:stylelint": "stylelint \"./packages/*/src/**/*.s(a|c)ss\"", "test:ci": "f () { npm run test:stylelint && npm run test:eslint-all ;}; f", "test:jest": "jest --all --maxWorkers=${JEST_MAX_WORKERS:-'50%'}", + "test:shard": "jest --all --shard=${SHARD_INDEX}/${SHARD_COUNT} --maxWorkers=${JEST_MAX_WORKERS:-'50%'} --coverage", "test:performance": "cd e2e-tests && jest -c ./jest.config.js --detectOpenHandles performance", "stylelint:fix": "stylelint \"./packages/*/src/**/*.s(a|c)ss\" --fix", "translate": "f () { npm exec --workspace=@deriv/translations -- npm run translate ;}; f", diff --git a/packages/account/src/Types/common.type.ts b/packages/account/src/Types/common.type.ts index 64ead58d0144..9e9603bb3033 100644 --- a/packages/account/src/Types/common.type.ts +++ b/packages/account/src/Types/common.type.ts @@ -163,7 +163,7 @@ export type TIDVFormValues = { error_message?: string; }; -export type TPlatforms = typeof Platforms[keyof typeof Platforms]; +export type TPlatforms = (typeof Platforms)[keyof typeof Platforms]; export type TServerError = { code?: string; @@ -172,7 +172,7 @@ export type TServerError = { details?: { [key: string]: string }; fields?: string[]; }; -export type TCFDPlatform = typeof CFD_PLATFORMS[keyof typeof CFD_PLATFORMS]; +export type TCFDPlatform = (typeof CFD_PLATFORMS)[keyof typeof CFD_PLATFORMS]; export type TClosingAccountFormValues = { 'financial-priorities': boolean; @@ -250,7 +250,7 @@ export type TAutoComplete = { value: boolean; text: string; }; -export type TPaymentMethodIdentifier = typeof IDENTIFIER_TYPES[keyof typeof IDENTIFIER_TYPES]; +export type TPaymentMethodIdentifier = (typeof IDENTIFIER_TYPES)[keyof typeof IDENTIFIER_TYPES]; export type TPaymentMethodInfo = { documents_required: number; @@ -285,11 +285,11 @@ export type TProofOfOwnershipErrors = Record< export type TFinancialInformationForm = Omit; -export type TAuthStatusCodes = typeof AUTH_STATUS_CODES[keyof typeof AUTH_STATUS_CODES]; +export type TAuthStatusCodes = (typeof AUTH_STATUS_CODES)[keyof typeof AUTH_STATUS_CODES]; export type TMT5AccountStatus = - | typeof MT5_ACCOUNT_STATUS[keyof typeof MT5_ACCOUNT_STATUS] - | typeof TRADING_PLATFORM_STATUS[keyof typeof TRADING_PLATFORM_STATUS]; + | (typeof MT5_ACCOUNT_STATUS)[keyof typeof MT5_ACCOUNT_STATUS] + | (typeof TRADING_PLATFORM_STATUS)[keyof typeof TRADING_PLATFORM_STATUS]; export type TFilesDescription = { descriptions: { id: string; value: JSX.Element }[]; diff --git a/packages/appstore/jest.config.js b/packages/appstore/jest.config.js index 30f0e20d7639..50e9aefcc5e4 100644 --- a/packages/appstore/jest.config.js +++ b/packages/appstore/jest.config.js @@ -7,6 +7,7 @@ module.exports = { '\\.s(c|a)ss$': '/../../__mocks__/styleMock.js', '^.+\\.svg$': '/../../__mocks__/fileMock.js', '@deriv-com/translations': '/../../__mocks__/translation.mock.js', + '^@deriv/account$': '/../account/src', '@deriv-com/ui': '/../../__mocks__/deriv-com.ui.mock.js', '^Assets/(.*)$': '/src/assets/$1', '^Components/(.*)$': '/src/components/$1', diff --git a/packages/cashier/src/containers/cashier/__tests__/cashier.spec.tsx b/packages/cashier/src/containers/cashier/__tests__/cashier.spec.tsx index 082e88127758..cd059e4cfa5c 100644 --- a/packages/cashier/src/containers/cashier/__tests__/cashier.spec.tsx +++ b/packages/cashier/src/containers/cashier/__tests__/cashier.spec.tsx @@ -14,6 +14,8 @@ jest.mock('@deriv-com/ui', () => ({ useDevice: jest.fn(() => ({ isDesktop: true })), })); +jest.mock('@deriv/p2p', () => jest.fn(() =>
P2P
)); + jest.mock('@deriv/hooks', () => { return { ...jest.requireActual('@deriv/hooks'), diff --git a/packages/cfd/jest.config.js b/packages/cfd/jest.config.js index 5d82f30d188d..29129d24f455 100644 --- a/packages/cfd/jest.config.js +++ b/packages/cfd/jest.config.js @@ -7,6 +7,7 @@ module.exports = { '\\.s(c|a)ss$': '/../../__mocks__/styleMock.js', '^.+\\.svg$': '/../../__mocks__/styleMock.js', '@deriv-com/translations': '/../../__mocks__/translation.mock.js', + '^@deriv/account$': '/../account/src', '@deriv-com/ui': '/../../__mocks__/deriv-com.ui.mock.js', '^_common/(.*)$': '/src/_common/$1', '^App/(.*)$': '/src/App/$1', diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js index c487bf44cac0..7290179e255a 100644 --- a/packages/core/jest.config.js +++ b/packages/core/jest.config.js @@ -7,6 +7,7 @@ module.exports = { '\\.s(c|a)ss$': '/../../__mocks__/styleMock.js', '^.+\\.svg$': '/../../__mocks__/styleMock.js', '@deriv-com/translations': '/../../__mocks__/translation.mock.js', + '^@deriv/account$': '/../account/src', '@deriv-com/ui': '/../../__mocks__/deriv-com.ui.mock.js', '^_common/(.*)$': '/src/_common/$1', '^App/(.*)$': '/src/App/$1', diff --git a/packages/core/src/App/Components/Layout/Header/__tests__/account-info-wallets.spec.tsx b/packages/core/src/App/Components/Layout/Header/__tests__/account-info-wallets.spec.tsx index 0f7b6970c926..a7e0e438c15b 100644 --- a/packages/core/src/App/Components/Layout/Header/__tests__/account-info-wallets.spec.tsx +++ b/packages/core/src/App/Components/Layout/Header/__tests__/account-info-wallets.spec.tsx @@ -35,7 +35,7 @@ describe('AccountInfoWallets component', () => { }, }; - it('should show "disabled_message" when "is_disabled" property is "true"', () => { + it('should show "disabled_message" when "is_disabled" property is "true"', async () => { const mock = mockStore({ client: { accounts: { @@ -64,7 +64,7 @@ describe('AccountInfoWallets component', () => { render(, { wrapper: wrapper(mock) }); const popover = screen.getByTestId('dt_popover_wrapper'); - userEvent.hover(popover); + await userEvent.hover(popover); const disabled_message = screen.getByText(/test disabled message/i); expect(disabled_message).toBeInTheDocument(); }); @@ -108,7 +108,7 @@ describe('AccountInfoWallets component', () => { expect(div_element).not.toHaveClass('acc-info--show'); }); - it('can not "toggleDialog" when "is_disabled" property is "true"', () => { + it('can not "toggleDialog" when "is_disabled" property is "true"', async () => { const mock = mockStore({ client: { accounts: { @@ -134,7 +134,7 @@ describe('AccountInfoWallets component', () => { render(, { wrapper: wrapper(mock) }); const div_element = screen.getByTestId('dt_acc_info'); - userEvent.click(div_element); + await userEvent.click(div_element); expect(toggleDialog).toHaveBeenCalledTimes(0); }); diff --git a/packages/core/src/App/Containers/AccountSwitcherWallet/__tests__/account-switcher-wallet-item.spec.tsx b/packages/core/src/App/Containers/AccountSwitcherWallet/__tests__/account-switcher-wallet-item.spec.tsx index 36d8e75e6b69..ce83375254ae 100644 --- a/packages/core/src/App/Containers/AccountSwitcherWallet/__tests__/account-switcher-wallet-item.spec.tsx +++ b/packages/core/src/App/Containers/AccountSwitcherWallet/__tests__/account-switcher-wallet-item.spec.tsx @@ -68,10 +68,10 @@ describe('AccountSwitcherWalletItem', () => { expect(screen.getByText('Demo')).toBeInTheDocument(); }); - it('calls closeAccountsDialog when clicked', () => { + it('calls closeAccountsDialog when clicked', async () => { const store = mockStore({}); render(); - userEvent.click(screen.getByTestId('account-switcher-wallet-item')); + await userEvent.click(screen.getByTestId('account-switcher-wallet-item')); expect(props.closeAccountsDialog).toHaveBeenCalled(); }); @@ -79,7 +79,7 @@ describe('AccountSwitcherWalletItem', () => { const switchAccount = jest.fn(); const store = mockStore({ client: { switchAccount, loginid: 'CR008' } }); render(); - userEvent.click(screen.getByTestId('account-switcher-wallet-item')); + await userEvent.click(screen.getByTestId('account-switcher-wallet-item')); expect(switchAccount).toHaveBeenCalledWith('CR007'); expect(props.closeAccountsDialog).toHaveBeenCalled(); }); @@ -88,7 +88,7 @@ describe('AccountSwitcherWalletItem', () => { const switchAccount = jest.fn(); const store = mockStore({ client: { switchAccount, loginid: 'CR007' } }); render(); - userEvent.click(screen.getByTestId('account-switcher-wallet-item')); + await userEvent.click(screen.getByTestId('account-switcher-wallet-item')); expect(switchAccount).not.toHaveBeenCalled(); expect(props.closeAccountsDialog).toHaveBeenCalled(); }); diff --git a/packages/trader/src/AppV2/Components/TradeParameters/Stake/__tests__/stake.spec.tsx b/packages/trader/src/AppV2/Components/TradeParameters/Stake/__tests__/stake.spec.tsx index be0cf74c0b5a..f2ab352154d4 100644 --- a/packages/trader/src/AppV2/Components/TradeParameters/Stake/__tests__/stake.spec.tsx +++ b/packages/trader/src/AppV2/Components/TradeParameters/Stake/__tests__/stake.spec.tsx @@ -100,12 +100,12 @@ describe('Stake', () => { expect(screen.getByRole('textbox')).toHaveValue(`${amount} ${currency}`); }); - it('opens ActionSheet with input, details and "Save" button if user clicks on "Stake" trade param', () => { + it('opens ActionSheet with input, details and "Save" button if user clicks on "Stake" trade param', async () => { render(); expect(screen.queryByTestId('dt-actionsheet-overlay')).not.toBeInTheDocument(); - userEvent.click(screen.getByText(stake_param_label)); + await userEvent.click(screen.getByText(stake_param_label)); expect(screen.getByTestId('dt-actionsheet-overlay')).toBeInTheDocument(); expect(screen.getByPlaceholderText(input_placeholder)).toBeInTheDocument(); @@ -113,37 +113,37 @@ describe('Stake', () => { expect(screen.getByRole('button', { name: save_button_label })).toBeInTheDocument(); }); - it('calls onChange when stake input changes', () => { + it('calls onChange when stake input changes', async () => { render(); - userEvent.click(screen.getByText(stake_param_label)); - userEvent.type(screen.getByPlaceholderText(input_placeholder), '0'); + await userEvent.click(screen.getByText(stake_param_label)); + await userEvent.type(screen.getByPlaceholderText(input_placeholder), '0'); expect(default_mock_store.modules.trade.onChange).toHaveBeenCalledWith({ target: { name: 'amount', value: '100' }, }); }); - it('does not render payout details for Accumulators', () => { + it('does not render payout details for Accumulators', async () => { default_mock_store.modules.trade.is_accumulator = true; render(); - userEvent.click(screen.getByText(stake_param_label)); + await userEvent.click(screen.getByText(stake_param_label)); expect(screen.queryByText(/payout/i)).not.toBeInTheDocument(); }); - it('does not render payout details for Turbos', () => { + it('does not render payout details for Turbos', async () => { default_mock_store.modules.trade.is_turbos = true; render(); - userEvent.click(screen.getByText(stake_param_label)); + await userEvent.click(screen.getByText(stake_param_label)); expect(screen.queryByText(/payout/i)).not.toBeInTheDocument(); }); - it('does not render payout details for Vanillas', () => { + it('does not render payout details for Vanillas', async () => { default_mock_store.modules.trade.is_vanilla = true; render(); - userEvent.click(screen.getByText(stake_param_label)); + await userEvent.click(screen.getByText(stake_param_label)); expect(screen.queryByText(/payout/i)).not.toBeInTheDocument(); }); - it('renders Stop out and Commission details instead of payout details for Multipliers', () => { + it('renders Stop out and Commission details instead of payout details for Multipliers', async () => { render( { /> ); - userEvent.click(screen.getByText(stake_param_label)); + await userEvent.click(screen.getByText(stake_param_label)); expect(screen.getByText('Acceptable range: 1.00 to 2,000.00 USD')).toBeInTheDocument(); expect(screen.getByText('Stop out')).toBeInTheDocument(); expect(screen.getByText('Commission')).toBeInTheDocument(); }); - it('calls setV2ParamsInitialValues if v2_params_initial_values.stake !== amount on mount and on Save button click if no error', () => { + it('calls setV2ParamsInitialValues if v2_params_initial_values.stake !== amount on mount and on Save button click if no error', async () => { default_mock_store.modules.trade.amount = '30'; render(); - userEvent.click(screen.getByText(stake_param_label)); - userEvent.type(screen.getByPlaceholderText(input_placeholder), '0'); + await userEvent.click(screen.getByText(stake_param_label)); + await userEvent.type(screen.getByPlaceholderText(input_placeholder), '0'); expect(default_mock_store.modules.trade.setV2ParamsInitialValues).toHaveBeenCalledTimes(2); - userEvent.click(screen.getByRole('button', { name: save_button_label })); + await userEvent.click(screen.getByRole('button', { name: save_button_label })); expect(default_mock_store.modules.trade.setV2ParamsInitialValues).toHaveBeenCalledTimes(3); }); @@ -222,7 +222,7 @@ describe('Stake', () => { }); }); - it('shows error in case of a validation error if input is non-empty', () => { + it('shows error in case of a validation error if input is non-empty', async () => { const error_text = "Please enter a stake amount that's at least 0.35."; default_mock_store.modules.trade.proposal_info = { PUT: { id: '', has_error: true, message: error_text }, @@ -232,12 +232,12 @@ describe('Stake', () => { default_mock_store.modules.trade.amount = 0; render(); - userEvent.click(screen.getByText(stake_param_label)); + await userEvent.click(screen.getByText(stake_param_label)); expect(screen.getByText(error_text)).toBeInTheDocument(); expect(screen.getAllByText('- USD')).toHaveLength(2); }); - it('shows max payout error with the least current payout when both of the 2 contract types exceed max payout', () => { + it('shows max payout error with the least current payout when both of the 2 contract types exceed max payout', async () => { const error_text_rise = 'Minimum stake of 0.35 and maximum payout of 50000.00. Current payout is 50631.97.'; const error_text_fall = 'Minimum stake of 0.35 and maximum payout of 50000.00. Current payout is 50513.21.'; default_mock_store.modules.trade.proposal_info = { @@ -248,13 +248,13 @@ describe('Stake', () => { default_mock_store.modules.trade.amount = '26500'; render(); - userEvent.click(screen.getByText(stake_param_label)); + await userEvent.click(screen.getByText(stake_param_label)); expect(screen.getByText(error_text_fall)).toBeInTheDocument(); expect(screen.queryByText('- USD')).not.toBeInTheDocument(); }); - it('does not show max payout error if one of the 2 contract types satisfies max payout', () => { + it('does not show max payout error if one of the 2 contract types satisfies max payout', async () => { const error_text_rise = 'Minimum stake of 0.35 and maximum payout of 50000.00. Current payout is 50058.77.'; const success_text_fall = 'Win payout if Volatility 100 (1s) Index is strictly lower than entry spot at 5 minutes after contract start time.'; @@ -270,7 +270,7 @@ describe('Stake', () => { default_mock_store.modules.trade.amount = '26200'; render(); - userEvent.click(screen.getByText(stake_param_label)); + await userEvent.click(screen.getByText(stake_param_label)); expect(screen.queryByText(error_text_rise)).not.toBeInTheDocument(); }); diff --git a/packages/trader/src/Stores/Modules/Trading/trade-store.ts b/packages/trader/src/Stores/Modules/Trading/trade-store.ts index 3bc5bb12c17a..c5b82502599b 100644 --- a/packages/trader/src/Stores/Modules/Trading/trade-store.ts +++ b/packages/trader/src/Stores/Modules/Trading/trade-store.ts @@ -1374,7 +1374,7 @@ export default class TradeStore extends BaseStore { const is_crypto = isCryptocurrency(this.currency ?? ''); const default_crypto_value = getMinPayout(this.currency ?? '') ?? ''; this.setV2ParamsInitialValues({ - value: is_crypto ? default_crypto_value : this.default_stake ?? '', + value: is_crypto ? default_crypto_value : (this.default_stake ?? ''), name: 'stake', }); obj_new_values.amount = is_crypto ? default_crypto_value : this.default_stake; diff --git a/packages/wallets/src/components/OptionsAndMultipliersListing/__test__/OptionsAndMultipliersListing.spec.tsx b/packages/wallets/src/components/OptionsAndMultipliersListing/__test__/OptionsAndMultipliersListing.spec.tsx index ed8e2190e848..2e1e633547be 100644 --- a/packages/wallets/src/components/OptionsAndMultipliersListing/__test__/OptionsAndMultipliersListing.spec.tsx +++ b/packages/wallets/src/components/OptionsAndMultipliersListing/__test__/OptionsAndMultipliersListing.spec.tsx @@ -45,24 +45,24 @@ describe('OptionsAndMultipliersListing', () => { expect(screen.getAllByTestId('dt_label_paired_chevron')[0]).toBeInTheDocument(); }); - it('handles onclick for the TradingAccountCard when loginid is undefined', () => { + it('handles onclick for the TradingAccountCard when loginid is undefined', async () => { (useActiveLinkedToTradingAccount as jest.Mock).mockReturnValue({ data: { loginid: undefined }, }); render(, { wrapper }); const tradingAccountCard = screen.getAllByTestId('dt_wallets_trading_account_card')[0]; - userEvent.click(tradingAccountCard); + await userEvent.click(tradingAccountCard); expect(screen.queryByTestId('dt_label_paired_chevron')).not.toBeInTheDocument(); expect(mockHistoryPush).not.toHaveBeenCalled(); }); - it('handles onclick for the TradingAccountCard when loginid is defined', () => { + it('handles onclick for the TradingAccountCard when loginid is defined', async () => { (useActiveLinkedToTradingAccount as jest.Mock).mockReturnValue({ data: { loginid: 'CR1' }, }); render(, { wrapper }); const tradingAccountCard = screen.getAllByTestId('dt_wallets_trading_account_card')[0]; - userEvent.click(tradingAccountCard); + await userEvent.click(tradingAccountCard); const icon = within(tradingAccountCard).queryByTestId('dt_label_paired_chevron'); expect(icon).toBeInTheDocument(); expect(mockHistoryPush).toHaveBeenCalled(); diff --git a/packages/wallets/src/features/cfd/constants.tsx b/packages/wallets/src/features/cfd/constants.tsx index e34c51c9e5c4..c81968919e5a 100644 --- a/packages/wallets/src/features/cfd/constants.tsx +++ b/packages/wallets/src/features/cfd/constants.tsx @@ -83,7 +83,7 @@ export const getMarketTypeDetails = ( icon: , title: 'Standard', }, - } as const); + }) as const; export const PlatformDetails = { ctrader: { @@ -158,7 +158,7 @@ export const getAppToContentMapper = (localize: ReturnType, @@ -176,7 +176,7 @@ export const getServiceMaintenanceMessages = (localize: ReturnType