Skip to content

Commit

Permalink
Feat/suite desktop core/market locators (#16302)
Browse files Browse the repository at this point in the history
* feat(e2e): adds locators for market buy form

* feat(e2e): Adds test locators for sell and confirm market screens
  • Loading branch information
Vere-Grey authored Jan 10, 2025
1 parent 3afada7 commit 00a9752
Show file tree
Hide file tree
Showing 16 changed files with 95 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const BadgeWrapper = styled.div`

interface AssetItemProps extends AssetOptionBaseProps {
handleClick: (selectedAsset: AssetOptionBaseProps) => void;
'data-testid'?: string;
}

export const AssetItem = ({
Expand All @@ -41,6 +42,7 @@ export const AssetItem = ({
shouldTryToFetch,
contractAddress,
handleClick,
'data-testid': dataTestId,
}: AssetItemProps) => {
const getCoinLogo = () =>
isCoinSymbol(symbol) ? <CoinLogo size={24} symbol={symbol} /> : null;
Expand All @@ -58,7 +60,7 @@ export const AssetItem = ({
})
}
>
<Row gap={spacings.sm}>
<Row data-testid={dataTestId} gap={spacings.sm}>
{coingeckoId ? (
<AssetLogo
size={24}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,24 @@ interface NetworkTabsProps {
activeTab: SelectAssetSearchCategory;
setActiveTab: (value: SelectAssetSearchCategory) => void;
networkCount: number;
'data-testid'?: string;
}

export const NetworkTabs = ({ tabs, activeTab, setActiveTab, networkCount }: NetworkTabsProps) => {
export const NetworkTabs = ({
tabs,
activeTab,
setActiveTab,
networkCount,
'data-testid': dataTestId,
}: NetworkTabsProps) => {
const { elevation } = useElevation();

// TODO: FormattedMessage - resolve messages sharing https://github.com/trezor/trezor-suite/issues/5325}
return (
<NetworkTabsWrapper $elevation={elevation}>
<Row gap={spacings.xs} flexWrap="wrap">
<CheckableTag
data-testid={`${dataTestId}/all-networks`}
$elevation={elevation}
$variant={activeTab === null ? 'primary' : 'tertiary'}
onClick={() => {
Expand All @@ -71,6 +79,7 @@ export const NetworkTabs = ({ tabs, activeTab, setActiveTab, networkCount }: Net
</CheckableTag>
{tabs.map(network => (
<CheckableTag
data-testid={`${dataTestId}/${network.symbol}`}
$elevation={elevation}
$variant={
activeTab?.coingeckoId === network.coingeckoId ? 'primary' : 'tertiary'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ interface SearchAssetProps {
searchPlaceholder: string;
search: string;
setSearch: (value: string) => void;
'data-testid'?: string;
}

export const SearchAsset = ({ searchPlaceholder, search, setSearch }: SearchAssetProps) => (
export const SearchAsset = ({
searchPlaceholder,
search,
setSearch,
'data-testid': dataTestId,
}: SearchAssetProps) => (
<Input
data-testid={dataTestId}
placeholder={searchPlaceholder}
value={search}
onChange={event => setSearch(event.target.value)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface SelectAssetModalProps {
searchInput?: ReactNode;
filterTabs?: ReactNode;
noItemsAvailablePlaceholder: { heading: ReactNode; body?: ReactNode };
'data-testid'?: string;
}

export const SelectAssetModal = ({
Expand All @@ -42,6 +43,7 @@ export const SelectAssetModal = ({
filterTabs,
searchInput,
noItemsAvailablePlaceholder,
'data-testid': dataTestId,
}: SelectAssetModalProps) => {
const intl = useIntl();

Expand Down Expand Up @@ -90,6 +92,7 @@ export const SelectAssetModal = ({
shouldTryToFetch,
}: AssetProps) => (
<AssetItem
data-testid={`${dataTestId}/option/${cryptoName}-${symbol}`}
key={`${symbol}${contractAddress ? `-${contractAddress}` : ''}`}
cryptoName={cryptoName}
ticker={ticker}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Locator, Page, expect } from '@playwright/test';
import { TrezorUserEnvLink } from '@trezor/trezor-user-env-link';
import { FiatCurrencyCode } from '@suite-common/suite-config';
import regional from '@trezor/suite/src/constants/wallet/coinmarket/regional';
import { NetworkSymbol } from '@suite-common/wallet-config';

import { step } from '../common';

Expand All @@ -15,28 +16,52 @@ const getCountryLabel = (country: string) => {
return labelWithFlag.substring(labelWithFlag.indexOf(' ') + 1);
};

type paymentMethods =
| 'googlePay'
| 'applePay'
| 'creditCard'
| 'paypal'
| 'bankTransfer'
| 'revolutPay';

export class MarketActions {
readonly offerSpinner: Locator;
readonly section: Locator;
readonly form: Locator;
readonly bestOfferProvider: Locator;
readonly bestOfferYouGet: Locator;
readonly bestOfferSection: Locator;
readonly bestOfferAmount: Locator;
readonly buyBestOfferButton: Locator;
readonly youPayInput: Locator;
readonly youPayCurrencyDropdown: Locator;
readonly youPayCurrencyOption = (currency: FiatCurrencyCode) =>
this.page.getByTestId(`@coinmarket/form/fiat-currency-select/option/${currency}`);
readonly youPayFiatCryptoSwitchButton: Locator;
readonly youPayFractionButton = (amount: '10%' | '25%' | '50%' | 'Max') =>
this.page.getByRole('button', { name: amount });
readonly feeButton = (fee: 'economy' | 'normal' | 'high' | 'custom') =>
this.page.getByTestId(`select-bar/${fee}`);
readonly customFeeInput: Locator;
readonly countryOfResidenceDropdown: Locator;
readonly countryOfResidenceOption = (countryCode: string) =>
this.page.getByTestId(`@coinmarket/form/country-select/option/${countryCode}`);
readonly accountDropdown: Locator;
readonly accountSearchInput: Locator;
readonly accountTabFilter = (tab: 'all-networks' | 'eth' | 'pol' | 'bsc' | 'sol') =>
this.page.getByTestId(`@coinmarket/form/select-crypto/network-tab/${tab}`);
readonly accountOption = (cryptoName: string, symbol: NetworkSymbol) =>
this.page.getByTestId(`@coinmarket/form/select-crypto/option/${cryptoName}-${symbol}`);
readonly paymentMethodDropdown: Locator;
readonly paymentMethodOption = (method: paymentMethods) =>
this.page.getByTestId(`@coinmarket/form/payment-method-select/option/${method}`);
readonly buyOffersPage: Locator;
readonly compareButton: Locator;
readonly quotes: Locator;
readonly quoteOfProvider = (provider: string) =>
this.page.getByTestId(`@coinmarket/offers/quote-${provider}`);
readonly quoteProvider: Locator;
readonly quoteAmount: Locator;
readonly refreshTime: Locator;
readonly selectThisQuoteButton: Locator;
readonly modal: Locator;
readonly buyTermsConfirmButton: Locator;
Expand All @@ -53,21 +78,33 @@ export class MarketActions {
this.section = this.page.getByTestId('@coinmarket');
this.form = this.page.getByTestId('@coinmarket/form');
this.bestOfferProvider = this.page.getByTestId('@coinmarket/offers/quote/provider');
this.bestOfferYouGet = this.page.getByTestId('@coinmarket/best-offer/amount');
this.bestOfferAmount = this.page.getByTestId('@coinmarket/form/offer/crypto-amount');
this.bestOfferSection = this.page.getByTestId('@coinmarket/best-offer');
this.bestOfferAmount = this.page.getByTestId('@coinmarket/best-offer/amount');
this.buyBestOfferButton = this.page.getByTestId('@coinmarket/form/buy-button');
this.youPayInput = this.page.getByTestId('@coinmarket/form/fiat-input');
this.youPayCurrencyDropdown = this.page.getByTestId(
'@coinmarket/form/fiat-currency-select/input',
);
this.youPayFiatCryptoSwitchButton = this.page.getByTestId(
'@coinmarket/form/switch-crypto-fiat',
);
this.customFeeInput = this.page.getByTestId('feePerUnit');
this.countryOfResidenceDropdown = this.page.getByTestId(
'@coinmarket/form/country-select/input',
);
this.accountDropdown = this.page.getByTestId('@coinmarket/form/select-crypto/input');
this.accountSearchInput = this.page.getByTestId(
'@coinmarket/form/select-crypto/search-input',
);
this.paymentMethodDropdown = this.page.getByTestId(
'@coinmarket/form/payment-method-select/input',
);
this.buyOffersPage = this.page.getByTestId('@coinmarket/buy-offers');
this.compareButton = this.page.getByTestId('@coinmarket/form/compare-button');
this.quotes = this.page.getByTestId('@coinmarket/offers/quote');
this.quoteProvider = this.page.getByTestId('@coinmarket/offers/quote/provider');
this.quoteAmount = this.page.getByTestId('@coinmarket/offers/quote/crypto-amount');
this.refreshTime = this.page.getByTestId('@coinmarket/refresh-time');
this.selectThisQuoteButton = this.page.getByTestId(
'@coinmarket/offers/get-this-deal-button',
);
Expand Down Expand Up @@ -120,6 +157,19 @@ export class MarketActions {
await this.youPayCurrencyOption(currencyCode).click();
}

@step()
async selectAccount(cryptoName: string, symbol: NetworkSymbol) {
await this.accountDropdown.click();
await this.accountSearchInput.fill(cryptoName);
await this.accountOption(cryptoName, symbol).click();
}

@step()
async selectPaymentMethod(method: paymentMethods) {
await this.paymentMethodDropdown.click();
await this.paymentMethodOption(method).click();
}

@step()
async setYouPayAmount(
amount: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test.describe('Coin market buy', { tag: ['@group=other'] }, () => {
await test.step('Fill input amount and opens offer comparison', async () => {
await marketPage.setYouPayAmount('1234');
await expect(marketPage.section).toHaveScreenshot('buy-coins-layout.png', {
mask: [marketPage.bestOfferYouGet, marketPage.bestOfferProvider],
mask: [marketPage.bestOfferSection, marketPage.bestOfferProvider],
});
await marketPage.compareButton.click();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ test.describe('Coinmarket Exchange', { tag: ['@group=other'] }, () => {
});

await page
.getByTestId('@coinmarket/form/select-account/input')
.getByTestId('@coinmarket/form/select-crypto/input')
.getByRole('combobox')
.fill('ETH');
await page.getByTestId('@coinmarket/form/select-account/option/ethereum').first().click();
await page.getByTestId('@coinmarket/form/select-crypto/option/ethereum').first().click();

await page.getByTestId('@coinmarket/form/crypto-input').fill('0.005');
await expect(page.getByText('Not enough funds')).toBeVisible();
Expand Down
2 changes: 1 addition & 1 deletion packages/suite-desktop-core/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ export default [
},
},
{
ignores: ['**/playwright-report/'],
ignores: ['**/playwright-report/', '**/test-results/'],
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const CoinmarketFormInputAccount = <
isSelected={context === 'value'}
/>
)}
data-testid="@coinmarket/form/select-account"
data-testid="@coinmarket/form/select-crypto"
isClearable={false}
isSearchable
bottomText={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,13 @@ export const CoinmarketFormInputCryptoSelect = <
<>
{isModalActive && (
<SelectAssetModal
data-testid="@coinmarket/form/select-crypto"
options={filteredData}
onSelectAsset={handleSelectChange}
onClose={() => setIsModalActive(false)}
searchInput={
<SearchAsset
data-testid="@coinmarket/form/select-crypto/search-input"
searchPlaceholder={translationString('TR_SELECT_NAME_OR_ADDRESS')}
search={search}
setSearch={setSearch}
Expand All @@ -227,6 +229,7 @@ export const CoinmarketFormInputCryptoSelect = <
}}
filterTabs={
<NetworkTabs
data-testid="@coinmarket/form/select-crypto/network-tab"
tabs={tabs}
networkCount={getNetworkCount(modalOptions)}
activeTab={activeTab}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const CoinmarketFormSwitcherCryptoFiat = ({
toggleAmountInCrypto,
}: CoinmarketFormSwitcherCryptoFiatProps) => (
<TextButton
data-testid="@coinmarket/form/switch-crypto-fiat"
size="small"
onClick={() => {
toggleAmountInCrypto();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const CoinmarketFormOffer = () => {

return (
<Column gap={spacings.lg}>
<Column gap={spacings.xs} data-testid="@coinmarket/best-offer/amount">
<Column gap={spacings.xs} data-testid="@coinmarket/best-offer">
<Translation id={amountLabels.offerLabel} />
{shouldDisplayFiatAmount ? (
<CoinmarketFormOfferFiatAmount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const CoinmarketFormOfferCryptoAmount = ({
<Row gap={spacings.sm}>
<CoinmarketCoinLogo cryptoId={cryptoId} />
<Text
data-testid="@coinmarket/form/offer/crypto-amount"
data-testid="@coinmarket/best-offer/amount"
typographyStyle="titleMedium"
ellipsisLineCount={2}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ export const CoinmarketFormOfferFiatAmount = ({ amount }: CoinmarketFormOfferFia

return (
<Row gap={spacings.sm}>
<Text typographyStyle="titleMedium" ellipsisLineCount={1}>
<Text
data-testid="@coinmarket/best-offer/amount"
typographyStyle="titleMedium"
ellipsisLineCount={1}
>
{formattedAmount}
</Text>
<CoinmarketFormInputCurrency isClean={false} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const CoinmarketRefreshTime = ({
<ProgressPieWrap>
<ProgressPie valueInPercents={progress} />
</ProgressPieWrap>
<TimerText>
<TimerText data-test="@coinmarket/refresh-time">
<RefreshLabel>{label}</RefreshLabel>
<RefreshTime>{`0:${remaining < 10 ? '0' : ''}${remaining}`}</RefreshTime>
</TimerText>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const CoinmarketVerifyOptions = ({

return (
<Select
data-testid="@coinmarket/verify-options/account"
onChange={(selected: CoinmarketVerifyFormAccountOptionProps) =>
onChangeAccount(selected)
}
Expand Down

0 comments on commit 00a9752

Please sign in to comment.