Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feat/lw-12231-govarna…
Browse files Browse the repository at this point in the history
…nce-placeholder-tab
  • Loading branch information
vetalcore committed Feb 13, 2025
2 parents f514360 + c611eec commit 7832d0c
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
padding-bottom:size_unit(2);
display: flex;
flex-direction: column;
gap: size-unit(2);
}
.content::-webkit-scrollbar {
width: 0;
Expand Down Expand Up @@ -91,3 +92,8 @@
}
}
}

.grid {
row-gap: 0;
column-gap: 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export const Nfts = withNftsFoldersContext((): React.ReactElement => {
columns={2}
scrollableTargetId={extensionScrollableContainerID}
items={isLoadingFirstTime ? [] : nftstoDisplay}
gridClassName={styles.grid}
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactElement, useState } from 'react';
import React, { ReactElement, useEffect, useState } from 'react';
import { Button, Drawer, DrawerHeader, DrawerNavigation } from '@lace/common';
import styles from './RenameFolderDrawer.module.scss';
import { NameForm } from '@views/browser/features/nfts/components/CreateFolder/NameForm';
Expand All @@ -18,7 +18,7 @@ interface RenameFolderDrawerProps {

export const RenameFolderDrawer = withNftsFoldersContext(
({ folderToRename, visible, onClose, isPopupView = false }: RenameFolderDrawerProps): ReactElement => {
const [name, setName] = useState('');
const [name, setName] = useState(folderToRename?.name || '');
const {
list: nftFolders,
utils: { updateRecord }
Expand Down Expand Up @@ -52,6 +52,10 @@ export const RenameFolderDrawer = withNftsFoldersContext(
setIsExitModalVisible(false);
};

useEffect(() => {
setName(folderToRename?.name || '');
}, [folderToRename?.name]);

const footer = (
<div className={styles.actionButtons}>
<Button
Expand Down Expand Up @@ -93,7 +97,7 @@ export const RenameFolderDrawer = withNftsFoldersContext(
<NameForm
onSetIsFormValid={setIsFormValid}
usedFolderNames={usedFolderNames}
name={name || folderToRename?.name}
name={name}
onSetName={setName}
/>
</Drawer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type GridProps<T> = VirtuosoGridProps<T, null> & {
testId?: string;
tableReference?: React.Ref<HTMLDivElement>;
columns?: VirtualisedGridColumns;
gridClassName?: string;
};

/**
Expand Down Expand Up @@ -66,14 +67,15 @@ export const VirtualisedGrid = <T extends Record<string, unknown> | undefined>({
tableReference,
testId,
columns,
gridClassName,
...props
}: GridProps<T>): React.ReactElement => {
const [scrollableTargetReference] = useQuerySelectorRef(`#${scrollableTargetId}`);

return (
<div ref={tableReference} data-testid={testId}>
<VirtuosoGrid<T>
listClassName={cn(styles.grid, { [styles[`grid-${columns}`]]: columns })}
listClassName={cn(styles.grid, gridClassName, { [styles[`grid-${columns}`]]: columns })}
data={items}
customScrollParent={scrollableTargetReference.current}
totalCount={items.length}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/ui/components/Nft/NftGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { NftItem, NftItemProps } from './NftItem';

export type NftGridProps = Omit<GridProps<NftItemProps | NftFolderItemProps | PlaceholderItem>, 'itemContent'> & {
isSearching?: boolean;
gridClassName?: string;
};

export const NftGrid = ({
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/ui/components/Nft/NftItem.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
opacity: 0.24;
}
&:hover {
background: var(--light-mode-light-grey, var(--dark-mode-mid-grey));
background: var(--light-mode-light-grey, var(--dark-mode-grey));
}
&:active,
&:focus {
Expand Down Expand Up @@ -123,11 +123,11 @@

.folderContainer {
position: relative;
height: 100%;
}

.folderWrapper {
border: 1px solid var(--light-mode-light-grey-plus, var(--dark-mode-mid-grey));
background-color: var(--light-mode-light-grey);
background-color: var(--light-mode-light-grey, var(--dark-mode-grey));
border-radius: 11px;
display: grid;
flex: 1;
Expand All @@ -140,7 +140,7 @@
@media (max-width: $breakpoint-popup) {
width: 147px;
height: 147px;
min-width: 147px;
max-width: 100%;
min-height: 147px;
}

Expand Down
4 changes: 3 additions & 1 deletion packages/e2e-tests/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ module.exports = exports = {
'new-cap': ['error', { capIsNew: false }],
'no-magic-numbers': ['off'],
'wdio/no-pause': ['off'],
'@typescript-eslint/no-explicit-any': ['off']
'@typescript-eslint/no-explicit-any': ['off'],
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error'
},
'env': {
'node': true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,60 @@
/* global WebdriverIO */
import TokenSelectionPage from '../../elements/newTransaction/tokenSelectionPage';
import { TokenSearchResult } from '../../elements/newTransaction/tokenSearchResult';
import { expect } from 'chai';
import { t } from '../../utils/translationService';
import { scanVirtualizedList } from '../../utils/virtualizedListUtils';

class TransactionAssetSelectionAssert {
async assertAssetIsPresentInTokenList(assetName: string, shouldBeDisplayed: boolean) {
await new TokenSearchResult(assetName).container.waitForDisplayed({ reverse: !shouldBeDisplayed });
}

async assertAssetsAreSelected(shouldBeSelected: boolean, amount: number, assetType: string) {
for (let i = 1; i <= amount; i++) {
await this.assertSpecificAssetSelected(shouldBeSelected, assetType, i);
}
async assertAssetsAreSelected(shouldBeSelected: boolean, expectedAmount: number, assetType: 'Tokens' | 'NFTs') {
await (assetType === 'Tokens'
? this.assertTokensSelected(shouldBeSelected, expectedAmount)
: this.assertNFTsSelected(shouldBeSelected, expectedAmount));
}

async assertSpecificAssetSelected(shouldBeSelected: boolean, assetType: string, index: number) {
if (assetType === 'Tokens') {
await TokenSelectionPage.tokenItem(index).grayedOutTokenIcon.waitForDisplayed({
reverse: !shouldBeSelected
});
await TokenSelectionPage.tokenItem(index).checkmarkInSelectedToken.waitForDisplayed({
reverse: !shouldBeSelected
});
} else {
await TokenSelectionPage.grayedOutNFT(index).waitForDisplayed({
reverse: !shouldBeSelected
});
await TokenSelectionPage.checkmarkInSelectedNFT(index).waitForDisplayed({
reverse: !shouldBeSelected
});
async assertTokensSelected(shouldBeSelected: boolean, expectedAmount: number) {
for (let i = 1; i <= expectedAmount; i++) {
await this.assertTokenSelectedAtIndex(shouldBeSelected, i);
}
}

async assertTokenSelectedAtIndex(shouldBeSelected: boolean, index: number) {
await TokenSelectionPage.tokenItem(index).grayedOutTokenIcon.waitForDisplayed({
reverse: !shouldBeSelected
});
await TokenSelectionPage.tokenItem(index).checkmarkInSelectedToken.waitForDisplayed({
reverse: !shouldBeSelected
});
}

assertNFTsSelected(shouldBeSelected: boolean, expectedAmount: number) {
return scanVirtualizedList(
expectedAmount,
() => TokenSelectionPage.nftContainers,
(nft) => TokenSelectionPage.getNftName(nft),
(nextNFT) => this.assertNFTSelected(shouldBeSelected, nextNFT)
);
}

async assertNFTSelected(shouldBeSelected: boolean, nft: WebdriverIO.Element) {
await TokenSelectionPage.grayedOutNFT(nft).waitForDisplayed({
reverse: !shouldBeSelected
});
await TokenSelectionPage.checkmarkInSelectedNFT(nft).waitForDisplayed({
reverse: !shouldBeSelected
});
}

async assertNFTSelectedAtIndex(shouldBeSelected: boolean, index: number) {
const nft = await TokenSelectionPage.getNftAtIndex(index);
if (!nft) return Promise.reject(new Error(`NFT at index ${index} not found`));
return await this.assertNFTSelected(shouldBeSelected, nft);
}

async assertSelectedAssetsCounter(shouldBeDisplayed: boolean, amount: number) {
await TokenSelectionPage.assetsCounter.waitForDisplayed({ reverse: !shouldBeDisplayed });
if (shouldBeDisplayed) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { TokenSearchResult } from './tokenSearchResult';
import { browser } from '@wdio/globals';
import { scrollDownWithOffset } from '../../utils/scrollUtils';
import { ChainablePromiseElement } from 'webdriverio';
import { getVirtualizedListElementAtIndex, scanVirtualizedList } from '../../utils/virtualizedListUtils';

class TokenSelectionPage extends CommonDrawerElements {
private TOKENS_BUTTON = '//input[@data-testid="asset-selector-button-tokens"]';
Expand Down Expand Up @@ -67,22 +68,31 @@ class TokenSelectionPage extends CommonDrawerElements {
return this.assetSelectorContainer.$$(this.NFT_ITEM_NAME);
}

getNftAtIndex = (index: number) =>
getVirtualizedListElementAtIndex(
index,
() => this.nftContainers,
(nft) => this.getNftName(nft)
);

getNftContainer = async (name: string) =>
(await this.nftContainers.find(
async (item) => (await item.$(this.NFT_ITEM_NAME).getText()) === name
)) as WebdriverIO.Element;

getNftName = async (name: string) => {
getNftNameElement = async (name: string) => {
const nftContainer = await this.getNftContainer(name);
return nftContainer.$(this.NFT_ITEM_NAME);
};

grayedOutNFT(index: number) {
return this.nftContainers[index].$(this.NFT_ITEM_OVERLAY);
getNftName = async (nft: WebdriverIO.Element) => nft.$(this.NFT_ITEM_NAME).getText();

grayedOutNFT(nft: WebdriverIO.Element): ChainablePromiseElement<WebdriverIO.Element> {
return nft.$(this.NFT_ITEM_OVERLAY);
}

checkmarkInSelectedNFT(index: number) {
return this.nftContainers[index].$(this.NFT_ITEM_SELECTED_CHECKMARK);
checkmarkInSelectedNFT(nft: WebdriverIO.Element): ChainablePromiseElement<WebdriverIO.Element> {
return nft.$(this.NFT_ITEM_SELECTED_CHECKMARK);
}

get assetsCounter(): ChainablePromiseElement<WebdriverIO.Element> {
Expand Down Expand Up @@ -119,7 +129,7 @@ class TokenSelectionPage extends CommonDrawerElements {

clickNftItemInAssetSelector = async (nftName: string) => {
await this.waitForNft(nftName);
const nftNameElement = await this.getNftName(nftName);
const nftNameElement = await this.getNftNameElement(nftName);
await nftNameElement.waitForClickable();
await nftNameElement.click();
};
Expand All @@ -144,26 +154,39 @@ class TokenSelectionPage extends CommonDrawerElements {
}
};

deselectToken = async (assetType: string, index: number) => {
assetType === 'Tokens' ? await this.tokenItem(Number(index)).container.click() : await this.nftNames[index].click();
deselectAsset = (assetType: string, index: number) =>
assetType === 'Tokens' ? this.tokenItem(Number(index)).container.click() : this.deselectNFTAtIndex(index);

deselectNFTAtIndex = async (index: number): Promise<void> => {
const nft = await this.getNftAtIndex(index);
if (!nft) return Promise.reject(new Error(`No NFT at index ${index} found`));
await nft.waitForClickable();
return nft.click();
};

saveSelectedTokens = async (assetType: string, bundle: number) => {
const amountOfAssets = Number(await this.assetsCounter.getText());
testContext.save(`amountOfAssetsInBundle${String(bundle)}`, amountOfAssets);

for (let i = 1; i <= amountOfAssets; i++) {
if (assetType === 'Tokens') {
if (assetType === 'Tokens') {
for (let i = 1; i <= amountOfAssets; i++) {
const tokenName = String(await this.tokenItem(i).name.getText()).slice(0, 6);
const asset =
tokenName === 'asset1'
? String(await this.tokenItem(i).name.getText()).slice(0, 10)
: String(await this.tokenItem(i).ticker.getText()).slice(0, 10);
testContext.save(`bundle${String(bundle)}asset${String(i)}`, asset);
} else {
const asset = String(await this.nftNames[i].getText()).slice(0, 10);
testContext.save(`bundle${String(bundle)}asset${String(i)}`, asset);
}
} else {
await scanVirtualizedList(
amountOfAssets,
() => this.nftContainers,
(nft) => this.getNftName(nft),
async (_, index, nftName) => {
const asset = String(nftName).slice(0, 10);
testContext.save(`bundle${String(bundle)}asset${String(index)}`, asset);
}
);
}
};

Expand Down Expand Up @@ -217,30 +240,17 @@ class TokenSelectionPage extends CommonDrawerElements {
}

async selectNFTs(numberOfNFTs: number) {
let selectedCount = 0;

while (selectedCount < numberOfNFTs) {
const nfts = await this.nftContainers;

for (const nft of nfts) {
await scanVirtualizedList(
numberOfNFTs,
() => this.nftContainers,
(nft) => this.getNftName(nft),
async (nft) => {
const isSelected = await nft.$(this.NFT_ITEM_SELECTED_CHECKMARK).isExisting();
if (isSelected) {
continue;
}

if (isSelected) return;
await nft.waitForClickable();
await nft.click();
selectedCount++;

if (selectedCount >= numberOfNFTs) {
return;
}
}

if (selectedCount < numberOfNFTs) {
await scrollDownWithOffset(nfts);
}
}
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ Feature: Send - Multiple selection for Extended Browser View
Background:
Given Wallet is synced

@LW-5043 @Pending
@issue=LW-12151
@LW-5043
Scenario Outline: Extended view - Send - Multiple tokens selection - <assetsType> - happy path
And I click "Send" button on page header
When I enter a valid "shelley" address in the bundle 1 recipient's address
Expand Down Expand Up @@ -66,8 +65,7 @@ Feature: Send - Multiple selection for Extended Browser View
| Tokens |
| NFTs |

@LW-5046 @Pending
@issue=LW-12151
@LW-5046
Scenario Outline: Extended view - Send - Multiple tokens selection - <assetsType> - clear and cancel
And I click "Send" button on page header
When I enter a valid "shelley" address in the bundle 1 recipient's address
Expand All @@ -93,8 +91,7 @@ Feature: Send - Multiple selection for Extended Browser View
| Tokens |
| NFTs |

@LW-5267 @Pending
@issue=LW-12151
@LW-5267
Scenario Outline: Extended view - Send - Multiple tokens selection - <assetsType> - Maximum amount to select is 30
And I click "Send" button on page header
When I enter a valid "shelley" address in the bundle 1 recipient's address
Expand Down
Loading

0 comments on commit 7832d0c

Please sign in to comment.