Skip to content

Commit

Permalink
Added faucet and issue token tests
Browse files Browse the repository at this point in the history
  • Loading branch information
razvantomegea committed Oct 16, 2024
1 parent 00a35aa commit 75c25ee
Show file tree
Hide file tree
Showing 19 changed files with 459 additions and 71 deletions.
17 changes: 13 additions & 4 deletions .github/workflows/pre-merge-e2e-pptr-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,18 @@ jobs:
with:
timeout_minutes: 120
retry_on: error
max_attempts: 5
max_attempts: 3
command: yarn install
- name: Build devnet MSW
run: yarn build:devnet-msw
- name: Run Puppeteer tests
- name: Setup chrome
uses: browser-actions/setup-chrome@v1
id: setup-chrome
with:
chrome-version: 128
- name: Set Chrome Path
run: echo "CHROME_PATH=${{ steps.setup-chrome.outputs.chrome-path }}" >> $GITHUB_ENV
- name: Build sovereign msw
run: yarn build:sovereign-msw
- name: Run Puppeteer test
env:
CHROME_PATH: ${{ steps.setup-chrome.outputs.chrome-path }}
run: yarn test:pptr-headless
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- [Added faucet and issue token tests](https://github.com/multiversx/mx-lite-wallet-dapp/pull/57)
- [Allow only tokens and collections with prefix to be registered](https://github.com/multiversx/mx-lite-wallet-dapp/pull/56)

## [[1.0.2](https://github.com/multiversx/mx-lite-wallet-dapp/pull/54)] - 2024-10-03
Expand Down
124 changes: 73 additions & 51 deletions jest-puppeteer.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,79 +2,101 @@
/* tslint:disable */
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

const getChromeExecutablePath = () => {
const chromeHeadlessShellPath = './chrome-headless-shell';
const platform = process.platform; // Get the platform

if (platform === 'linux') {
const dirs = fs.readdirSync(chromeHeadlessShellPath);
const chromeDirectory = dirs.find((dir) => dir.startsWith('linux-'));

if (chromeDirectory) {
return path.resolve(
__dirname,
chromeHeadlessShellPath,
chromeDirectory,
'chrome-headless-shell-linux64/chrome-headless-shell'
);
} else {
throw new Error('Chrome headless shell directory not found');
const isLinux = process.platform === 'linux';
const isHeadless = process.env.HEADLESS !== 'false';
const chromePath = process.env.CHROME_PATH;

const findFile = (folderPath, fileName) => {
const files = fs.readdirSync(folderPath);

for (const file of files) {
const filePath = path.join(folderPath, file);
const stats = fs.statSync(filePath);

if (stats.isDirectory()) {
const found = findFile(filePath, fileName);
if (found) return found;
} else if (file === fileName) {
return filePath;
}
}

return null;
};

const getLinuxChromiumPath = () => {
try {
// Try to get the path using 'which' command
try {
return execSync('which chromium-browser', { encoding: 'utf8' }).trim();
} catch (e) {
// If 'which chromium-browser' fails, try 'which chromium'
try {
return execSync('which chromium', { encoding: 'utf8' }).trim();
} catch (e) {
// If both fail, continue to next method
}
}
} else if (platform === 'darwin') {
// macOS
const dirs = fs.readdirSync(chromeHeadlessShellPath);
const chromeDirectory = dirs.find((dir) => dir.startsWith('mac_arm-'));

if (chromeDirectory) {
return path.resolve(
__dirname,
chromeHeadlessShellPath,
chromeDirectory,
'chrome-headless-shell-mac-arm64/chrome-headless-shell'
);
} else {
throw new Error('Chrome headless shell directory not found');

// Check common snap installation path
const snapPath = '/snap/bin/chromium';

if (fs.existsSync(snapPath)) {
return snapPath;
}
} else {
throw new Error('Unsupported platform');

// Check another common installation path
const commonPath = '/usr/bin/chromium-browser';

if (fs.existsSync(commonPath)) {
return commonPath;
}

// If all attempts fail, return null
return null;
} catch (error) {
console.error('Error finding Chromium path:', error);
return null;
}
};

const isHeadless = process.env.HEADLESS !== 'false';
const getChromeExecutablePath = () => {
if (chromePath) {
return chromePath;
}

return !isHeadless && isLinux ? getLinuxChromiumPath() : undefined;
};

const args = [
'--disable-gpu',
'--disable-dev-shm-usage',
'--no-sandbox',
'--disable-setuid-sandbox',
'--start-maximized', // Required to start in full screen
'--disable-web-security', // Required for iframe to work
'--ignore-certificate-errors' // Required for HTTPS to work
];

if (isHeadless) {
args.unshift(
'--disable-gpu',
'--disable-dev-shm-usage',
'--no-sandbox',
'--disable-setuid-sandbox',
`--headless=new`
);
}

const config = {
preset: 'jest-puppeteer',
testMatch: ['**/src/**/*.e2e.ts'],
setupFilesAfterEnv: ['./src/setupPuppeteerTests.ts'],
roots: ['<rootDir>/src'],
modulePaths: ['<rootDir>/src'],
bail: 1,
workerIdleMemoryLimit: '512MB', // Memory used per worker. Required to prevent memory leaks
// maxWorkers: '50%', // Maximum tests ran in parallel. Required to prevent CPU usage at 100%
workerIdleMemoryLimit: '512MB',
maxWorkers: isHeadless ? '100%' : 1,
launch: {
headless: false,
headless: isHeadless,
dumpio: false, // Enable to see machine logs
product: 'chrome',
defaultViewport: { width: 1600, height: 800 },
defaultViewport: isHeadless ? { width: 1600, height: 800 } : null,
args,
executablePath: getChromeExecutablePath(), // optional locally, required on Git Action
devtools: !isHeadless
executablePath: getChromeExecutablePath(),
devtools: false // Enable to see browser console
},
server: {
command: 'vite preview'
Expand All @@ -84,7 +106,7 @@ const config = {
browserPerWorker: true
};

if (!isHeadless) {
if (!isHeadless && !isLinux && !chromePath) {
delete config.launch.executablePath;
}

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
"build": "tsc && npm run set-storage-persist && vite build",
"build:devnet": "npm run copy:devnet-config && npm run build",
"build:sovereign": "npm run copy:sovereign-config && npm run build",
"build:devnet-msw": "npm run copy:devnet-config & VITE_APP_MSW=true npm run build",
"build:sovereign-msw": "npm run copy:sovereign-config & VITE_APP_MSW=true npm run build",
"build:testnet": "npm run copy:testnet-config & npm run build",
"build:mainnet": "npm run copy:mainnet-config & npm run build",
"postbuild": "node src/scripts/createVersionFile/index",
"copy:devnet-config": "cp ./src/config/config.devnet.ts ./src/config/index.ts",
"copy:testnet-config": "cp ./src/config/config.testnet.ts ./src/config/index.ts",
"copy:mainnet-config": "cp ./src/config/config.mainnet.ts ./src/config/index.ts",
"copy:sovereign-config": "cp ./src/config/config.sovereign.ts ./src/config/index.ts",
"test:pptr-headless": "npx @puppeteer/browsers install [email protected] && jest --config=jest-puppeteer.config.js",
"test:pptr-headless": "HEADLESS=true jest --config=jest-puppeteer.config.js",
"test:pptr": "JEST_PPTR_RETRY_TIMES=0 HEADLESS=false jest --config=jest-puppeteer.config.js",
"test": "jest",
"preview": "vite preview"
Expand Down
15 changes: 8 additions & 7 deletions src/__mocks__/data/dappConfig.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
export const dappConfig = {
id: 'devnet',
name: 'Devnet',
egldLabel: 'xEGLD',
id: 'sovereign',
name: 'Sovereign',
egldLabel: 'WEGLD',
decimals: '4',
egldDenomination: '18',
gasPerDataByte: '1500',
apiTimeout: '4000',
walletConnectDeepLink:
'https://maiar.page.link/?apn=com.multiversx.maiar.wallet&isi=1519405832&ibi=com.multiversx.maiar.wallet&link=https://maiar.com/',
walletConnectBridgeAddresses: ['https://bridge.walletconnect.org'],
walletAddress: 'https://devnet-wallet.multiversx.com',
apiAddress: 'https://devnet-api.multiversx.com',
explorerAddress: 'http://devnet-explorer.multiversx.com',
chainId: 'D'
walletAddress: 'https://wallet-sovereign-test.elrond.ro/',
apiAddress: 'https://api-sovereign-test.elrond.ro',
explorerAddress:
'https://api-sovereign-test.internal-explorer.multiversx.com',
chainId: 'local-testnet'
};
5 changes: 5 additions & 0 deletions src/__mocks__/data/faucetSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const faucetSettings = {
address: 'erd1xgzak3d6wcpyk83c3ne0n05khdz026e8p0rg8qu65dly706kfmxs0qecax',
amount: '40000000000000000000',
recaptchaBypass: true
};
2 changes: 2 additions & 0 deletions src/__mocks__/data/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export * from './constants';
export * from './dappConfig';
export * from './emptyWallet';
export * from './faucetSettings';
export * from './networkConfig';
export * from './testKeystoreWallet';
export * from './testNetwork';
export * from './testPemWallet';
export * from './testPemWalletGuarded';
3 changes: 2 additions & 1 deletion src/__mocks__/data/testNetwork.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const testNetwork = {
apiAddress: 'https://devnet-api.multiversx.com'
apiAddress: 'https://api-sovereign-test.elrond.ro',
extrasApiAddress: 'https://extras-api-sovereign-test.elrond.ro'
};
5 changes: 5 additions & 0 deletions src/__mocks__/data/testPemWalletGuarded/account.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY for erd1dc3yzxxeq69wvf583gw0h67td226gu2ahpk3k50qdgzzym8npltq7ndgha-----
YjMzODcyMjMzMjFjNTg3YzM1MTE5OGFkYzI1MzFjODIwYTM3OGQzNzQ4OTU2YjNk
YWUyZTBmNWExZGFhN2NhMTZlMjI0MTE4ZDkwNjhhZTYyNjg3OGExY2ZiZWJjYjZh
OTVhNDcxNWRiODZkMWI1MWUwNmEwNDIyNmNmMzBmZDY=
-----END PRIVATE KEY for erd1dc3yzxxeq69wvf583gw0h67td226gu2ahpk3k50qdgzzym8npltq7ndgha-----
1 change: 1 addition & 0 deletions src/__mocks__/data/testPemWalletGuarded/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './pemAccountGuarded';
18 changes: 18 additions & 0 deletions src/__mocks__/data/testPemWalletGuarded/pemAccountGuarded.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { emptyWalletAccount } from '../emptyWallet';

export const pemAccountGuarded = {
address: 'erd1dc3yzxxeq69wvf583gw0h67td226gu2ahpk3k50qdgzzym8npltq7ndgha',
balance: '4559443050404540691',
nonce: 71,
timestamp: 1685712294,
shard: 1,
rootHash: 'cB9GBtevo98yZf906jxVI++W6U68+V+22NnUJEpOs8c=',
txCount: 74,
scrCount: 64,
developerReward: '0',
activeGuardianActivationEpoch: 1119,
activeGuardianAddress: emptyWalletAccount.address,
activeGuardianServiceUid: 'MultiversXTCSService',
pendingGuardianAddress: undefined,
isGuarded: true
};
26 changes: 25 additions & 1 deletion src/__mocks__/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import {
pemWalletTokens,
pemWalletNfts,
dappConfig,
networkConfig
networkConfig,
pemAccountGuarded,
faucetSettings
} from './data';
import { mockResponse } from './serverUtils';

Expand Down Expand Up @@ -43,6 +45,28 @@ export const handlers = [
http.get(
`${testNetwork.apiAddress}/accounts/${pemAccount.address}/nfts`,
mockResponse(pemWalletNfts)
),
http.get(
`${testNetwork.apiAddress}/accounts/${pemAccountGuarded.address}`,
mockResponse(pemAccount)
),
http.get(
`${testNetwork.apiAddress}/accounts/${pemAccountGuarded.address}/tokens`,
mockResponse(pemWalletTokens)
),
http.get(
`${testNetwork.apiAddress}/accounts/${pemAccountGuarded.address}/nfts`,
mockResponse(pemWalletNfts)
),
http.get(
`${testNetwork.extrasApiAddress}/faucet/settings`,
mockResponse(faucetSettings)
),
http.post(
`${testNetwork.extrasApiAddress}/faucet`,
mockResponse({
status: 'success'
})
)
];

Expand Down
3 changes: 2 additions & 1 deletion src/localConstants/dataTestIds.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export enum DataTestIdsEnum {
dappModal = 'dappModal',
dataInput = 'dataInput',
disclaimerCheck = 'disclaimerCheck',
faucetBtn = 'faucetBtn',
gasLimitError = 'gasLimitError',
gasLimitInput = 'gasLimitInput',
goToCheckMnemonic = 'goToCheckMnemonic',
Expand Down Expand Up @@ -66,7 +67,7 @@ export enum DataTestIdsEnum {
recoverWalletBtn = 'recoverWalletBtn',
registerTokenBtn = 'registerTokenBtn',
removeTokenBtn = 'removeTokenBtn',
requestTokensButton = 'requestTokensButton',
requestFundsButton = 'requestFundsButton',
royaltiesError = 'royaltiesError',
royaltiesInput = 'royaltiesInput',
sendBtn = 'sendBtn',
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Faucet/Faucet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const Faucet = () => {
<>
<Button
className='inline-block rounded-lg bg-blue-600 px-4 py-2 text-sm text-white'
data-testid={DataTestIdsEnum.sovereignTransferBtn}
data-testid={DataTestIdsEnum.faucetBtn}
onClick={handleShow}
>
Request funds
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Faucet/components/FaucetScreen/FaucetScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ export const FaucetScreen = ({
)}

<Button
data-testid={DataTestIdsEnum.requestTokensButton}
data-testid={DataTestIdsEnum.requestFundsButton}
disabled={requestDisabled}
id={DataTestIdsEnum.requestTokensButton}
id={DataTestIdsEnum.requestFundsButton}
onClick={handleRequestTokens}
>
Request Tokens
Expand Down
34 changes: 34 additions & 0 deletions src/pages/Faucet/tests/RequestFunds.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { DEFAULT_DELAY_MS, WALLET_SOURCE_ORIGIN } from '__mocks__/data';
import {
expectElementToContainText,
getByDataTestId,
loginWithPem,
sleep
} from 'utils/testUtils/puppeteer';
import { DataTestIdsEnum } from 'localConstants/dataTestIds.enum';

describe('Request funds tests', () => {
it('should receive 40 WEGLD successfully', async () => {
await page.goto(`${WALLET_SOURCE_ORIGIN}/logout`, {
waitUntil: 'domcontentloaded'
});

await loginWithPem();
const requestFundsButton = await page.waitForSelector(
getByDataTestId(DataTestIdsEnum.faucetBtn)
);

await requestFundsButton.click();
await expectElementToContainText({
dataTestId: DataTestIdsEnum.modalSubtitle,
text: 'You can request 40 WEGLD every 24 hours'
});

await page.click(getByDataTestId(DataTestIdsEnum.requestFundsButton));
await sleep(DEFAULT_DELAY_MS);
await expectElementToContainText({
dataTestId: DataTestIdsEnum.modalSubtitle,
text: '40 WEGLD have been sent to your address.'
});
});
});
Loading

0 comments on commit 75c25ee

Please sign in to comment.