Adding more tests
This commit is contained in:
@@ -51,12 +51,12 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install
|
||||
working-directory: nym-wallet/webdriver
|
||||
working-directory: nym-wallet/wallet-ui-tests
|
||||
|
||||
- name: Remove existing user datafile
|
||||
uses: JesseTG/rm@v1.0.2
|
||||
with:
|
||||
path: nym-wallet/webdriver/common/data/user-data.json
|
||||
path: nym-wallet/wallet-ui-tests/common/user-data.json
|
||||
|
||||
- name: Create user data json file
|
||||
id: create-json
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
with:
|
||||
name: "user-data.json"
|
||||
json: ${{ secrets.WALLET_USERDATA }}
|
||||
dir: "nym-wallet/webdriver/common/data/"
|
||||
dir: "nym-wallet/wallet-ui-tests/common/"
|
||||
|
||||
- name: Install tauri-driver
|
||||
uses: actions-rs/cargo@v1
|
||||
@@ -73,5 +73,5 @@ jobs:
|
||||
args: tauri-driver
|
||||
|
||||
- name: Launch tests
|
||||
run: xvfb-run yarn test:runall
|
||||
working-directory: nym-wallet/webdriver
|
||||
run: xvfb-run yarn test
|
||||
working-directory: nym-wallet/wallet-ui-tests
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"accounts": [
|
||||
{
|
||||
"id": "default",
|
||||
"account": {
|
||||
"ciphertext": "cq5w4W5ex5eFFRcqLG+824XyUAUoYmrRY3NGw/rue6/mLoQKQE/07+BxzRuKjyYFasC1HBPg41KJwp2IY+/7+80rB9aXPpaKVLUcG9U40qgCw66WhgxTrXOnrt5toefpSTBL7f9N/PVwpuumfAgD9CS0ioB7/9Qoea7nYKkextGX15ex26B/ndQddvUkQ4gx+Vq7OLymv4l+nkdZ2nKMja349zd/BjnzPBB68/iIjyYlivVjtQ7FRbvpNRj6Mjg4905wGlO7bTpkw+RGiaGK4pK8fTWz8gAKr8GYoXPD",
|
||||
"salt": "SPVGdbVyoEayD4ZzM4I+Jg==",
|
||||
"iv": "tjpn/tRjD1gty+fQ"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"accounts": [
|
||||
{
|
||||
"id": "default",
|
||||
"account": {
|
||||
"ciphertext": "3MDgoU2i5QMc9r80yPeq2AMk5wpkke0tXum5NsOE5NcFciF+aHLQW0dvXbGszap1y3nN4+YZD3cgGrmtKh/cChqRGJDkniaxdf3XPHh9RkiWXw2KSHHeyGrFY0INJeiky1ZtUFhWhopcHJWSnfCmVC15YFpnM5xOKpITjHAFhGt98MaYR+mS+3zoUFrjYbaZRh2TR2lFWsbR8YU1uaTYqJZ1HX1PBCub6aS3vjQm0Fwa+hAtR/gMymXJc5qtruTO4NbqYtMj3Z9eIgoVB+56SLAXlIF1Uo1pjvV0mx1hWNNiIc10ujF/wl/nnKF6icOcmrfm9XhOtsvUYBsE/wAIJZw3LKXgSX+hJbOl+zLAwJZK1xiL8n/nM1IJZDn+Wu6z0OzRaj9S7T16+brMw1oaqjk56saM8n5z725fizJj+ur6gnPBWnoyHPaCHgHdB2PKQNY0ZlwRM6dVncRaEWQDLAboyMq3FXxK9UbusNcDFpYw6bdnuJlNVf6y9yxwyvkUrt5YtgfkLyoW42z1PVtVWsV9P8eE/A/tnYjXf34xvba3K8Y1/3DTi7uuydNrSR/XhA+pevz68VWCbY+j746Yi8Lz7altePphkjfJAezodobKvMplXzqInopIWNovyemw/+1E7WZbkQIOAXg1WC1+Y/df+dffRGuGRdDerfRLmA5XLej1M/wE3WQ7b9KwlAo6XJ4hnQKwyDCqYP/ButBXW1AOnnZpCq59gGbiccZJsTMZB4OP95yFPgz8//IeDgma2PDixVmDEp0SGHhN7dlSoNa5eoglblqzJu/TcTA6jmQFA3ef0GiA3QzBjmyB4bz0bFybh8XA1brVIVlsjRwXb3/UYaVqsP6Hy1QDUpZofXIJs5lK0hUd0ECdaNFXXgHd25ifPocp09WLFyK92H6i3ABDZ7pu3b4lTUt6kHt6LTVsKkyylmYf2iMHnCcmfy4uxGTXxRjPjMgKL8pd++OZ3q62jLBuoTjgdj6pccwDvD+NYQ2FFeHmBzxyTLqUyKltYiyFlJHWLKOcXyeDHzRhHic+e/wn3VhM3NdrvtqYWA9m72Ye1L1I7VX7KatGurG6CeiFiY5xHxxpLT7dF0fJ7uxRye4JnRyYQuU7iK72qCKjgYjwjCIha4qPi5Q/x6S+uVe7yX5Eb73L3eB+IlkyW9wPHmSOcE4GpbMU96tK8xoxT0T9eQlj050GDnJ/oI2XHfZTs1bIxsjfZqW03g==",
|
||||
"salt": "wXR3RnPmsoA3ncrixIvaUw==",
|
||||
"iv": "/Zjn1OXsLJhA43n/"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"accounts": [
|
||||
{
|
||||
"id": "first",
|
||||
"account": {
|
||||
"ciphertext": "icnpxLmr/H7FIIOaEf7DYNLuM6uhh7poEppXpYCllQD33TjY+8eLtVvhEQmjX60IQeFOd+1JCcrHa2B12vlBAYlfM4gBxA6d2ZJ8+Dw/vNvBNyChiyUx2euV3vPGOs22r/XDBsmEeF40XZcXftQZa2kzYaPnkbP+eiMOIWkcY4FYOEHwx5SxT4VBPZIrVTC3iDalJLWybVbbw/Bc2zbzEXI1ckg4Ccydj95SMil9BiyDpALfZqwlai7I97S+BjmcVxSCsYqFjTkRUHVMjrEr7fWHKU4DIOM=",
|
||||
"salt": "CtnbfkxTybqz0U4cPHW2jQ==",
|
||||
"iv": "77ZROU6dAMttEWwS"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "second",
|
||||
"account": {
|
||||
"ciphertext": "nsqZHdQFlskglc5izKgnr8sBwdMmd82h2Rnjdos9EUca3cqkUdFYEjZDsK8OGR3GZ9alLTNt/1U97Rvvr2HPAWbzl23FW2YXaLTA6yj6ZwQK5w0MYE061NYbcxNHuzT9f5aQWkGULAk4RWb5t8eUX7y/NdJr3tA5xuGOLhooTfBB98/4RpupDsYGZp1DPC/GMFppOA3GmKs9bacZm805Bhfq5mwhXab1SjJQpFHMHisCMhxo/oLqulKML1tQMetBdqDTjJmPpdUnd1mi",
|
||||
"salt": "J2TMLjKv4dkZ/kXso9FGhg==",
|
||||
"iv": "CTqqoMa4LetvBKCP"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -28,7 +28,7 @@ type ClientAddressProps = {
|
||||
showEntireAddress?: boolean;
|
||||
};
|
||||
|
||||
export const ClientAddressDisplay: FC<ClientAddressProps & { address?: string }> = ({
|
||||
export const ClientAddressDisplay: FC<ClientAddressProps & { address?: string } > = ({
|
||||
withLabel,
|
||||
withCopy,
|
||||
showEntireAddress,
|
||||
@@ -44,7 +44,7 @@ export const ClientAddressDisplay: FC<ClientAddressProps & { address?: string }>
|
||||
)}
|
||||
|
||||
<AddressTooltip address={address} visible={!showEntireAddress}>
|
||||
<Typography variant="body2" component="span" sx={{ mr: 1, color: 'text.primary', fontWeight: 400 }}>
|
||||
<Typography data-testid="accountNumber" variant="body2" component="span" sx={{ mr: 1, color: 'text.primary', fontWeight: 400 }}>
|
||||
{showEntireAddress ? address || '' : splice(6, address)}
|
||||
</Typography>
|
||||
</AddressTooltip>
|
||||
|
||||
@@ -30,6 +30,7 @@ export const CopyToClipboard = ({ text = '', iconButton }: { text?: string; icon
|
||||
return (
|
||||
<Tooltip title={!copied ? 'Copy' : 'Copied!'} leaveDelay={500}>
|
||||
<IconButton
|
||||
data-testid="copyy"
|
||||
onClick={() => handleCopy(text)}
|
||||
size="small"
|
||||
sx={{
|
||||
|
||||
@@ -41,7 +41,7 @@ export const SimpleModal: React.FC<{
|
||||
<Box sx={{ ...modalStyle, ...sx }}>
|
||||
{displayErrorIcon && <ErrorOutline color="error" sx={{ mb: 3 }} />}
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||
<Typography fontSize={20} fontWeight={600} sx={{ color: 'text.primary', ...headerStyles }}>
|
||||
<Typography fontSize={20} fontWeight={600} sx={{ color: 'text.primary', ...headerStyles }} data-header-testid={header}>
|
||||
{header}
|
||||
</Typography>
|
||||
{!hideCloseIcon && <CloseIcon onClick={onClose} cursor="pointer" />}
|
||||
|
||||
@@ -87,7 +87,7 @@ export const Nav = () => {
|
||||
}
|
||||
})
|
||||
.map(({ Icon, onClick, label, route }) => (
|
||||
<ListItem disableGutters key={label} onClick={onClick} sx={{ cursor: 'pointer' }}>
|
||||
<ListItem disableGutters key={label} onClick={onClick} sx={{ cursor: 'pointer' }} data-testid={label}>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: 30,
|
||||
|
||||
@@ -7,8 +7,8 @@ import { config } from '../config';
|
||||
|
||||
const networks: { networkName: Network; name: string }[] = [
|
||||
{ networkName: 'MAINNET', name: 'Nym Mainnet' },
|
||||
{ networkName: 'SANDBOX', name: 'Testnet Sandbox'},
|
||||
{ networkName: 'QA', name: 'QA' },
|
||||
{ networkName: 'SANDBOX', name: 'Testnet Sandbox' },
|
||||
{ networkName: 'QA', name: 'QA' },
|
||||
];
|
||||
|
||||
const NetworkItem: React.FC<{ title: string; isSelected: boolean; onSelect: () => void }> = ({
|
||||
@@ -16,7 +16,7 @@ const NetworkItem: React.FC<{ title: string; isSelected: boolean; onSelect: () =
|
||||
isSelected,
|
||||
onSelect,
|
||||
}) => (
|
||||
<ListItem button onClick={onSelect} data-testid={ title }>
|
||||
<ListItem button onClick={onSelect} data-testid={title}>
|
||||
<ListItemIcon>{isSelected && <CheckSharp color="success" />}</ListItemIcon>
|
||||
<ListItemText>{title}</ListItemText>
|
||||
</ListItem>
|
||||
@@ -38,6 +38,7 @@ export const NetworkSelector = () => {
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
data-testid="networkEnv"
|
||||
variant="text"
|
||||
color="primary"
|
||||
sx={{ color: 'text.primary' }}
|
||||
|
||||
@@ -31,7 +31,7 @@ export const NymCard: React.FC<{
|
||||
{noPadding ? (
|
||||
<CardContentNoPadding>{children}</CardContentNoPadding>
|
||||
) : (
|
||||
<CardContent sx={{ p: 3 }} data-testid="check-balance">{children}</CardContent>
|
||||
<CardContent sx={{ p: 3 }} >{children}</CardContent>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@ export const MnemonicInput: React.FC<{
|
||||
label="Mnemonic"
|
||||
inputProps={{
|
||||
"data-testid": "mnemonicInput",
|
||||
}}
|
||||
}}
|
||||
type={showPassword ? 'input' : 'password'}
|
||||
value={mnemonic}
|
||||
onChange={(e) => onUpdateMnemonic(e.target.value)}
|
||||
@@ -66,6 +66,9 @@ export const PasswordInput: React.FC<{
|
||||
</IconButton>
|
||||
),
|
||||
}}
|
||||
inputProps={{
|
||||
"data-testid": label,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
{error && <Error message={error} />}
|
||||
|
||||
@@ -54,9 +54,7 @@ export const WordTiles = ({
|
||||
<Grid container spacing={3} justifyContent="center">
|
||||
{mnemonicWords.map(({ name, index, disabled }) => (
|
||||
<Grid
|
||||
// data-testid="mnemonicWord"
|
||||
data-testid={name}
|
||||
item xs={2} key={index} onClick={() => onClick?.({ name, index })}>
|
||||
item xs={2} key={index} onClick={() => onClick?.({ name, index })} data-testid="mnemonicWordTile">
|
||||
<WordTile
|
||||
mnemonicWord={name}
|
||||
index={showIndex ? index : undefined}
|
||||
@@ -82,7 +80,7 @@ const HiddenWord = ({ mnemonicWord }: { mnemonicWord: THiddenMnemonicWord }) =>
|
||||
</Box>
|
||||
</Fade>
|
||||
</Box>
|
||||
<Typography data-testid="number">{mnemonicWord.index}.</Typography>
|
||||
<Typography data-testid="wordIndex">{mnemonicWord.index}.</Typography>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ export const ConfirmMnemonic = () => {
|
||||
<Subtitle subtitle="Enter the mnemonic you wish to create a password for" />
|
||||
<MnemonicInput mnemonic={localMnemonic} onUpdateMnemonic={(mnc) => setLocalMnemonic(mnc)} error={error} />
|
||||
<Button
|
||||
data-testid="nextToPasswordCreation"
|
||||
size="large"
|
||||
variant="contained"
|
||||
fullWidth
|
||||
@@ -37,6 +38,7 @@ export const ConfirmMnemonic = () => {
|
||||
Next
|
||||
</Button>
|
||||
<Button
|
||||
data-testid="backToMnemonicSignIn"
|
||||
size="large"
|
||||
color="inherit"
|
||||
fullWidth
|
||||
|
||||
@@ -57,6 +57,7 @@ export const ConnectPassword = () => {
|
||||
label="Confirm password"
|
||||
/>
|
||||
<Button
|
||||
data-testid="createPasswordButton"
|
||||
size="large"
|
||||
variant="contained"
|
||||
disabled={password !== confirmedPassword || password.length === 0 || !isStrongPassword || isLoading}
|
||||
@@ -65,6 +66,7 @@ export const ConnectPassword = () => {
|
||||
{isLoading ? <CircularProgress size={25} /> : 'Create password'}
|
||||
</Button>
|
||||
<Button
|
||||
data-testid="backToStep1PasswordCreation"
|
||||
size="large"
|
||||
color="inherit"
|
||||
onClick={() => {
|
||||
|
||||
@@ -47,7 +47,6 @@ export const CreatePassword = () => {
|
||||
onUpdatePassword={(pswd) => setPassword(pswd)}
|
||||
label="Password"
|
||||
autoFocus
|
||||
data-testid="password"
|
||||
/>
|
||||
<PasswordStrength password={password} onChange={(isStrong) => setIsStrongPassword(isStrong)} />
|
||||
</>
|
||||
@@ -55,7 +54,6 @@ export const CreatePassword = () => {
|
||||
password={confirmedPassword}
|
||||
onUpdatePassword={(pswd) => setConfirmedPassword(pswd)}
|
||||
label="Confirm password"
|
||||
data-testid="confirmPassword"
|
||||
/>
|
||||
<Button
|
||||
size="large"
|
||||
|
||||
@@ -39,7 +39,7 @@ export const SignInMnemonic = () => {
|
||||
>
|
||||
<Stack spacing={2}>
|
||||
<MnemonicInput mnemonic={mnemonic} onUpdateMnemonic={(mnc) => setMnemonic(mnc)} error={error} />
|
||||
<Button variant="contained" size="large" fullWidth type="submit" data-testid="signIn">
|
||||
<Button variant="contained" size="large" fullWidth type="submit" data-testid="signInSubmitButton">
|
||||
Sign in with mnemonic
|
||||
</Button>
|
||||
<Box display="flex" justifyContent={passwordExists ? 'center' : 'space-between'}>
|
||||
@@ -47,7 +47,7 @@ export const SignInMnemonic = () => {
|
||||
Back
|
||||
</Button>
|
||||
{!passwordExists && (
|
||||
<Button color="info" onClick={() => handlePageChange('/confirm-mnemonic')} data-testid="createPassword">
|
||||
<Button color="info" onClick={() => handlePageChange('/confirm-mnemonic')} data-testid="goToCreatePassword">
|
||||
Create a password
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -29,6 +29,7 @@ export const SignInPassword = () => {
|
||||
autoFocus
|
||||
/>
|
||||
<Button
|
||||
data-testid="signInPasswordButton"
|
||||
variant="contained"
|
||||
size="large"
|
||||
fullWidth
|
||||
@@ -38,6 +39,7 @@ export const SignInPassword = () => {
|
||||
</Button>
|
||||
<Box display="flex" justifyContent="space-between">
|
||||
<Button
|
||||
data-testid="backToSignInOptionsFromPassword"
|
||||
color="inherit"
|
||||
disableElevation
|
||||
onClick={() => {
|
||||
@@ -49,6 +51,7 @@ export const SignInPassword = () => {
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
data-testid="forgotPasswordButton"
|
||||
color="info"
|
||||
onClick={() => {
|
||||
setError(undefined);
|
||||
|
||||
@@ -45,15 +45,14 @@ export const VerifyMnemonic = () => {
|
||||
<Subtitle subtitle="Select the words from your mnmonic based on their order" />
|
||||
<HiddenWords mnemonicWords={hiddenRandomWords} />
|
||||
<WordTiles
|
||||
data-testid="number"
|
||||
mnemonicWords={randomWords}
|
||||
onClick={currentSelection !== numberOfRandomWords ? revealWord : undefined}
|
||||
buttons
|
||||
/>
|
||||
<Stack spacing={3} sx={{ width: 300 }} data-testid="randomMnemonicWords">
|
||||
<Stack spacing={3} sx={{ width: 300 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
data-testid="next"
|
||||
data-testid="nextToStep3"
|
||||
fullWidth
|
||||
size="large"
|
||||
disabled={currentSelection !== numberOfRandomWords}
|
||||
|
||||
@@ -99,7 +99,7 @@ const TerminalInner: React.FC = () => {
|
||||
<Box width="100%" display="flex" justifyContent="space-between">
|
||||
<Box display="flex" alignItems="center">
|
||||
<TerminalIcon sx={{ mr: 1 }} />
|
||||
<Typography mr={4}>Terminal</Typography>
|
||||
<Typography mr={4} data-testid='terminal-header'>Terminal</Typography>
|
||||
{!isBusy && <RefreshIcon onClick={refresh} cursor="pointer" />}
|
||||
</Box>
|
||||
<CloseIcon onClick={handleShowTerminal} cursor="pointer" />
|
||||
|
||||
@@ -19,5 +19,5 @@
|
||||
"@assets/*": ["../assets/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist", "jest.config.js", "webpack.config.js", "webpack.prod.js", "webpack.common.js", "target", "webdriver", "wallet-ui-tests"]
|
||||
"exclude": ["node_modules", "dist", "jest.config.js", "webpack.config.js", "webpack.prod.js", "webpack.common.js", "target", "wallet-ui-tests"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
class Helpers {
|
||||
//helper to decode mnemonic so plain 24 character passphrase isn't in sight albeit it is presented when ruunning the scripts
|
||||
// TO=-DO weork on this, figure out what's going on with the decoding bit
|
||||
decodeBase = async (input) => {
|
||||
var m = Buffer.from(input, "base64").toString();
|
||||
return m;
|
||||
};
|
||||
|
||||
navigateAndClick = async (element) => {
|
||||
await element.click();
|
||||
};
|
||||
|
||||
scrollIntoView = async (element) => {
|
||||
await element.scrollIntoView();
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = new Helpers();
|
||||
@@ -0,0 +1,27 @@
|
||||
module.exports = {
|
||||
|
||||
//welcome, sign in, create account
|
||||
homePageErrorMnemonic: "Error parsing bip39 mnemonic",
|
||||
signInWithoutMnemonic: "A mnemonic must be provided",
|
||||
signInRandomString: "mnemonic has a word count that is not a multiple of 6:",
|
||||
signInIncorrectMnemonic: "mnemonic contains an unknown word",
|
||||
incorrectMnemonicPasswordCreation: "The mnemonic provided is not valid. Please check the mnemonic",
|
||||
invalidPasswordOnSignIn: "failed to decrypt the given data with the provided password",
|
||||
signInWithoutPassword: "A password must be provided",
|
||||
failedToFindWalletFile: "The wallet file is not found",
|
||||
|
||||
//homePage
|
||||
qaNetwork: "QA",
|
||||
sandboxNetwork: "Testnet Sandbox",
|
||||
mainnetNetwork: "Nym Mainnet",
|
||||
noNym: "0 NYM",
|
||||
|
||||
|
||||
|
||||
|
||||
// user incorrect data
|
||||
incorrectMnemonic: "giraffe note order sun cradle bottom crime humble able antique rural donkey guess parent potato tongue truly way disagree exile zebra someone else heat",
|
||||
randomString:"thisrandomstring",
|
||||
password:"iAmThePassword1!",
|
||||
incorrectPassword:"123notvalid",
|
||||
};
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"mnemonic": "value",
|
||||
"mnemonic": "giraffe note order sun cradle bottom crime humble able antique rural donkey guess parent potato tongue truly way disagree exile zebra someone else typical",
|
||||
"punk_address": "",
|
||||
"receiver_address": "",
|
||||
"amount_to_send": "",
|
||||
@@ -4,9 +4,10 @@
|
||||
"description": "ui tests for the nym wallet",
|
||||
"scripts": {
|
||||
"test": "wdio run wdio.conf.ts",
|
||||
"test:welcome": "wdio run wdio.conf.ts --suite welcome",
|
||||
"test:signup": "wdio run wdio.conf.ts --suite signup",
|
||||
"test:login": "wdio run wdio.conf.ts --suite login",
|
||||
"test:balance": "wdio run wdio.conf.ts --suite balance"
|
||||
"test:balance": "wdio run wdio.conf.ts --suite balance",
|
||||
"test:nav": "wdio run wdio.conf.ts --suite nav"
|
||||
|
||||
},
|
||||
"author": "",
|
||||
@@ -15,6 +16,7 @@
|
||||
"-": "^0.0.1",
|
||||
"@wdio/cli": "^7.16.16",
|
||||
"save-dev": "^0.0.1-security",
|
||||
"@zxing/browser": "^0.0.9",
|
||||
"ts-node": "^10.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
const { exec } = require("child_process")
|
||||
|
||||
const deleteSavedFile = exec("rm '/home/benedetta/.local/share/nym-wallet/saved-wallet.json'", (err, stdout, stderr) => {
|
||||
if (err) {
|
||||
console.error(`${err.message}`)
|
||||
return
|
||||
} else
|
||||
console.log("File deleted")
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
const { exec } = require("child_process")
|
||||
|
||||
const doesFileExist = exec("test -f /home/benedetta/.local/share/nym-wallet/saved-wallet.json")
|
||||
@@ -0,0 +1,22 @@
|
||||
class Nav {
|
||||
|
||||
get lightMode() { return $("[data-testid='LightModeOutlinedIcon']") }
|
||||
get darkMode() { return $("[data-testid='ModeNightOutlinedIcon']") }
|
||||
get terminalTitle() { return $("[data-testid='terminal-header']") }
|
||||
get terminalIcon() { return $("[data-testid='TerminalIcon']") }
|
||||
|
||||
|
||||
|
||||
get balance() { return $("[data-testid='Balance']") }
|
||||
get send() { return $("[data-testid='Send']") }
|
||||
get receive() { return $("[data-testid='Receive']") }
|
||||
get bond() { return $("[data-testid='Bond']") }
|
||||
get unbond() { return $("[data-testid='Unbond']") }
|
||||
get delegation() { return $("[data-testid='Delegation']") }
|
||||
|
||||
|
||||
|
||||
get closeIcon() { return $("[data-testid='CloseIcon']") }
|
||||
|
||||
}
|
||||
export default new Nav()
|
||||
@@ -1,45 +1,72 @@
|
||||
import Balance from '../pageobjects/balanceScreen'
|
||||
|
||||
class Welcome {
|
||||
//Welcome landing page
|
||||
get signInButton() { return $("[data-testid='signIn']") }
|
||||
get createAccount() { return $("[data-testid='createAccount']") }
|
||||
//Welcome landing page
|
||||
get signInButton() { return $("[data-testid='signIn']") }
|
||||
get createAccount() { return $("[data-testid='createAccount']") }
|
||||
|
||||
// Existing account sign in option page
|
||||
get signInMnemonic() { return $("[data-testid='signInWithMnemonic']") }
|
||||
get signInPassword() { return $("[data-testid='signInWithPassword']") }
|
||||
get backToWelcomePage() { return $("[data-testid='backToWelcomePage']") }
|
||||
get forgotPassword() { return $("[data-testid='forgotPassword']") }
|
||||
// Existing account sign in option page
|
||||
get signInMnemonic() { return $("[data-testid='signInWithMnemonic']") }
|
||||
get signInPassword() { return $("[data-testid='signInWithPassword']") }
|
||||
get backToWelcomePage() { return $("[data-testid='backToWelcomePage']") }
|
||||
get forgotPassword() { return $("[data-testid='forgotPassword']") }
|
||||
|
||||
// Sign in with mnemonic page
|
||||
get mnemonicInput() { return $("[data-testid='mnemonicInput']") }
|
||||
get signIn() { return $("[data-testid='signIn']") }
|
||||
get backToSignInOptions() { return $("[data-testid='backToSignInOptions']") }
|
||||
get createPassword() { return $("[data-testid='createPassword']") }
|
||||
// Sign in with mnemonic page
|
||||
get mnemonicInput() { return $("[data-testid='mnemonicInput']") }
|
||||
get signIn() { return $("[data-testid='signInSubmitButton']") }
|
||||
get backToSignInOptions() { return $("[data-testid='backToSignInOptions']") }
|
||||
get createPassword() { return $("[data-testid='goToCreatePassword']") }
|
||||
|
||||
// Error
|
||||
get error() { return $("[data-testid='error']") }
|
||||
// Create password step 1/2
|
||||
get backToMnemonicSignIn() { return $("[data-testid='backToMnemonicSignIn']") }
|
||||
get nextToPasswordCreation() { return $("[data-testid='nextToPasswordCreation']") }
|
||||
|
||||
// Sign in with password
|
||||
// Create password step 2/2
|
||||
get password() { return $("[data-testid='Password']") }
|
||||
get confirmPassword() { return $("[data-testid='Confirm password']") }
|
||||
get createPasswordButton() { return $("[data-testid='createPasswordButton']") }
|
||||
get backToStep1PasswordCreation() { return $("[data-testid='backToStep1PasswordCreation']") }
|
||||
|
||||
// Create account step 1/3
|
||||
get copyMnemonic() { return $("[data-testid='copyMnemonic']") }
|
||||
get iSavedMnemonic() { return $("[data-testid='iSavedMnemonic']") }
|
||||
get mnemonicPhrase() { return $("[data-testid='mnemonicPhrase']") }
|
||||
get backToWelcomePageFromCreate(){ return $("[data-testid='backToWelcome']")}
|
||||
// Create account step 1/3
|
||||
get copyMnemonic() { return $("[data-testid='copyMnemonic']") }
|
||||
get iSavedMnemonic() { return $("[data-testid='iSavedMnemonic']") }
|
||||
get mnemonicPhrase() { return $("[data-testid='mnemonicPhrase']") }
|
||||
get backToWelcomePageFromCreate() { return $("[data-testid='backToWelcome']") }
|
||||
|
||||
// Create account step 2/3
|
||||
get number() { return $("[data-testid='number']") }
|
||||
get randomMnemonicWords() { return $("[data-testid='randomMnemonicWords']") }
|
||||
//random words // random hidden words (top and bottom row, with name and index each)
|
||||
get mnemonicWord() { return $("[data-testid='mnemonicWord']") }
|
||||
// get randomMnemonicWords() { return $("#root > div > div > div > div:nth-child(6) > div:nth-child(1) > div > div") }
|
||||
get next() { return $("[data-testid='next']") }
|
||||
get backToStep1() { return $("[data-testid='backToStep1']") }
|
||||
// Create account step 2/3
|
||||
get wordIndex() { return $$("[data-testid='wordIndex']") }
|
||||
get mnemonicWordTile() { return $$("[data-testid='mnemonicWordTile']") }
|
||||
get nextToStep3() { return $("[data-testid='nextToStep3']") }
|
||||
get backToStep1() { return $("[data-testid='backToStep1']") }
|
||||
|
||||
// Create account step 3/3
|
||||
get password() { return $("[data-testid='password']") }
|
||||
get confirmpassword() { return $("[data-testid='confirmpassword']") }
|
||||
// get next() { return $("[data-testid='next']") }
|
||||
get skipPasswordAndSignInWithMnemonic() { return $("[data-testid='skipPasswordAndSignInWithMnemonic']") }
|
||||
// Create account step 3/3
|
||||
get next() { return $("[data-testid='next']") } // TO-DO possibly rename this?
|
||||
get skipPasswordAndSignInWithMnemonic() { return $("[data-testid='skipPasswordAndSignInWithMnemonic']") }
|
||||
|
||||
// Enter password to sign in
|
||||
get enterPassword() { return $("[data-testid='Enter password']") }
|
||||
get signInPasswordButton() { return $("[data-testid='signInPasswordButton']") }
|
||||
get backToSignInOptionsFromPassword() { return $("[data-testid='backToSignInOptionsFromPassword']") }
|
||||
get forgotPasswordButton() { return $("[data-testid='forgotPasswordButton']") }
|
||||
|
||||
// Errors
|
||||
get error() { return $("[data-testid='error']") }
|
||||
//TO-DO get this bit below working
|
||||
getErrorMessage = async () => {
|
||||
await (await this.error).waitForDisplayed({ timeout: 1500 })
|
||||
await this.error.getText()
|
||||
}
|
||||
|
||||
|
||||
//login to the application
|
||||
loginWithMnemonic = async (mnemonic) => {
|
||||
await this.signInButton.click()
|
||||
await this.signInMnemonic.click()
|
||||
await this.mnemonicInput.waitForDisplayed()
|
||||
await this.mnemonicInput.addValue(mnemonic);
|
||||
await this.signIn.click();
|
||||
await Balance.nymBalance.isExisting();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,14 @@ class Balance {
|
||||
get checkBalance() { return $("[data-testid='check-balance']") }
|
||||
get nymBalance() { return $("[data-testid='nym-balance']") }
|
||||
|
||||
// TO-DO figure out what's wrong with this copyAccountId locator being intercepted when clicked on
|
||||
get copyAccountId() { return $("[data-testid='ContentCopyIcon']")}
|
||||
get accountId() { return $("[data-testid='']")}
|
||||
// get copyAccountId() { return $("[data-testid='copyy']")}
|
||||
|
||||
get accountNumber() { return $("[data-testid='accountNumber']")}
|
||||
|
||||
get networkDropdown() { return $("[data-testid='ArrowDropDownIcon']") }
|
||||
get networkEnv() { return $("[data-testid='networkEnv']") }
|
||||
get networkSelectQa() { return $("[data-testid='QA']") }
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ class Bond {
|
||||
get mixnodeRadio() { return $("[data-testid='mix-node']") }
|
||||
get gatewayRadio() { return $("[data-testid='gate-way']") }
|
||||
get fundsAlert() { return $("[data-testid='fundsAlert']") }
|
||||
get fundsAlert() { return $("[data-testid='fundsAlert']") }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class Delegation {
|
||||
|
||||
get delegationTitle() { return $("[data-testid='Delegation']") }
|
||||
|
||||
}
|
||||
|
||||
export default new Delegation()
|
||||
@@ -0,0 +1,7 @@
|
||||
class Receive {
|
||||
|
||||
get receiveNymTitle() { return $("[data-testid='Receive NYM']") }
|
||||
|
||||
}
|
||||
|
||||
export default new Receive()
|
||||
@@ -0,0 +1,5 @@
|
||||
class Send {
|
||||
|
||||
get sendHeader() { return $("[data-header-testid='Send']") } // TO-DO see if Send value can be used without changing the key name
|
||||
}
|
||||
export default new Send()
|
||||
@@ -0,0 +1,7 @@
|
||||
class Unbond {
|
||||
|
||||
get unbondTitle() { return $("[data-testid='Unbond']") }
|
||||
|
||||
}
|
||||
|
||||
export default new Unbond()
|
||||
@@ -0,0 +1,37 @@
|
||||
import Balance from '../../pageobjects/balanceScreen'
|
||||
import Auth from '../../pageobjects/authScreens'
|
||||
const textConstants = require("../../../common/text-constants");
|
||||
const userData = require("../../../common/user-data.json");
|
||||
|
||||
|
||||
describe('Balance screen displays correctly', () => {
|
||||
|
||||
it('selecting qa network', async () => {
|
||||
|
||||
//log in
|
||||
await Auth.loginWithMnemonic(userData.mnemonic)
|
||||
|
||||
// select QA network
|
||||
await (await Balance.networkDropdown).waitForDisplayed({ timeout: 4000 })
|
||||
await (await Balance.networkDropdown).click()
|
||||
await (await Balance.networkSelectQa).waitForDisplayed({ timeout: 2500 })
|
||||
await (await Balance.networkSelectQa).click()
|
||||
|
||||
// verifty QA network has been selected properly
|
||||
let network = await (await Balance.networkEnv).getText()
|
||||
expect(network).toStrictEqual(textConstants.qaNetwork)
|
||||
|
||||
})
|
||||
|
||||
it('copy the account id', async () => {
|
||||
// ensure the account number contains *something*
|
||||
await (await Balance.accountNumber).waitForDisplayed({ timeout: 1500 })
|
||||
let accountnumber = await (await Balance.accountNumber).getText()
|
||||
expect(accountnumber[1]).toStrictEqual('1')
|
||||
await (await Balance.copyAccountId).waitForDisplayed({ timeout: 1500 })
|
||||
// TO-DO intercepted error when clicking copy,element exists though
|
||||
await (await Balance.copyAccountId).click()
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
@@ -1,35 +0,0 @@
|
||||
import Balance from '../../pageobjects/balanceScreen'
|
||||
import Auth from '../../pageobjects/authScreens'
|
||||
|
||||
describe('Balance screen displays correctly', () => {
|
||||
const mne = "giraffe note order sun cradle bottom crime humble able antique rural donkey guess parent potato tongue truly way disagree exile zebra someone else typical";
|
||||
|
||||
it('selecting qa network', async () => {
|
||||
await (await Auth.signInButton).click()
|
||||
await (await Auth.signInMnemonic).click()
|
||||
await (await Auth.mnemonicInput).waitForDisplayed()
|
||||
await (await Auth.mnemonicInput).addValue(mne)
|
||||
await (await Auth.signIn).click()
|
||||
|
||||
await (await Balance.networkDropdown).waitForDisplayed({timeout: 1500})
|
||||
await (await Balance.networkDropdown).click()
|
||||
// TO-DO fix the selector below, it's an odd one
|
||||
await (await Balance.networkSelectQa).waitForDisplayed({timeout: 1500})
|
||||
await (await Balance.networkSelectQa).click()
|
||||
let network = await (await Balance.networkDropdown).getText()
|
||||
expect(network).toStrictEqual('QA')
|
||||
|
||||
})
|
||||
|
||||
it('copy the account id', async () => {
|
||||
// await (await Auth.signInButton).click()
|
||||
// await (await Auth.signInMnemonic).click()
|
||||
// await (await Auth.mnemonicInput).waitForDisplayed()
|
||||
// await (await Auth.mnemonicInput).addValue(mne)
|
||||
// await (await Auth.signIn).click()
|
||||
|
||||
// await (await Balance.copyAccountId).click()
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
import Auth from '../../pageobjects/authScreens'
|
||||
import Balance from '../../pageobjects/balanceScreen'
|
||||
import ValidatorClient from '@nymproject/nym-validator-client';
|
||||
const textConstants = require("../../../common/text-constants");
|
||||
const userData = require("../../../common/user-data.json");
|
||||
|
||||
|
||||
describe('Create password for existing account and use it to sign in', () => {
|
||||
|
||||
it('enter incorrect mnemonic', async () => {
|
||||
|
||||
//click through sign in
|
||||
await (await Auth.signInButton).click()
|
||||
await (await Auth.signInMnemonic).click()
|
||||
//instead of entering mnemonic, click on create a password
|
||||
await (await Auth.createPassword).click()
|
||||
//enter incorrect mnemonic
|
||||
await (await Auth.mnemonicInput).addValue(textConstants.incorrectMnemonic)
|
||||
await (await Auth.nextToPasswordCreation).click()
|
||||
// assert error message is correct
|
||||
let getErrorWarning = await (await Auth.error).getText()
|
||||
expect(getErrorWarning).toStrictEqual(textConstants.incorrectMnemonicPasswordCreation)
|
||||
|
||||
})
|
||||
|
||||
it('enter random string', async () => {
|
||||
|
||||
await (await Auth.mnemonicInput).addValue(textConstants.randomString)
|
||||
await (await Auth.nextToPasswordCreation).click()
|
||||
let getErrorWarning = await (await Auth.error).getText()
|
||||
expect(getErrorWarning).toStrictEqual(textConstants.incorrectMnemonicPasswordCreation)
|
||||
|
||||
})
|
||||
|
||||
|
||||
it('enter correct mnemonic', async () => {
|
||||
|
||||
// generate random mnemonic in the backend
|
||||
const randomMnemonic = ValidatorClient.randomMnemonic();
|
||||
// use it to continue with password creation flow
|
||||
await (await Auth.backToMnemonicSignIn).click()
|
||||
await (await Auth.createPassword).click()
|
||||
await (await Auth.mnemonicInput).addValue(randomMnemonic)
|
||||
await (await Auth.nextToPasswordCreation).click()
|
||||
await (await Auth.password).waitForDisplayed({ timeout: 2500 })
|
||||
|
||||
})
|
||||
|
||||
it('create an invalid password', async () => {
|
||||
// type an invalid password in both fields
|
||||
await (await Auth.password).addValue(textConstants.incorrectPassword)
|
||||
await (await Auth.confirmPassword).click()
|
||||
await (await Auth.confirmPassword).addValue(textConstants.incorrectPassword)
|
||||
// ensure the button to proceed is still disabled
|
||||
// TO-DO the next button seems to not be clickable here, despite the locator id existing in the right place
|
||||
const nextButton = await Auth.next
|
||||
const isNextDisabled = await nextButton.getAttribute('disabled')
|
||||
expect(isNextDisabled).toBe(true)
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
+35
-11
@@ -1,8 +1,13 @@
|
||||
import Auth from '../../pageobjects/authScreens'
|
||||
import Balance from '../../pageobjects/balanceScreen'
|
||||
const textConstants = require("../../../common/text-constants");
|
||||
const userData = require("../../../common/user-data.json");
|
||||
|
||||
|
||||
describe('Wallet sign in functionality with mnemonic', () => {
|
||||
|
||||
describe('Wallet login functionality', () => {
|
||||
it('sign in with no mnemonic throws error', async () => {
|
||||
|
||||
//click through sign without entering a mnemonic
|
||||
await (await Auth.signInButton).click()
|
||||
await (await Auth.signInMnemonic).click()
|
||||
@@ -10,17 +15,36 @@ describe('Wallet login functionality', () => {
|
||||
// wait for error
|
||||
await (await Auth.error).waitForDisplayed({ timeout: 1500 })
|
||||
let getErrorWarning = await (await Auth.error).getText()
|
||||
const errorText = 'A mnemonic must be provided'
|
||||
// verify error has the correct message
|
||||
expect(getErrorWarning).toStrictEqual(errorText)
|
||||
|
||||
// TO-DO fix the below so there's no need to go back before the following test
|
||||
await (await Auth.backToSignInOptions).click()
|
||||
await (await Auth.backToWelcomePage).click()
|
||||
expect(getErrorWarning).toStrictEqual(textConstants.signInWithoutMnemonic)
|
||||
|
||||
})
|
||||
|
||||
it('should login with valid credentials', async () => {
|
||||
it('sign in with incorrect mnemonic throws error', async () => {
|
||||
|
||||
// await (await Auth.mnemonicInput).waitForDisplayed()
|
||||
await (await Auth.mnemonicInput).addValue(textConstants.incorrectMnemonic)
|
||||
await (await Auth.signIn).click()
|
||||
let getErrorWarning = await (await Auth.error).getText()
|
||||
expect(getErrorWarning).toContain(textConstants.signInIncorrectMnemonic)
|
||||
|
||||
})
|
||||
|
||||
it('sign in with random string throws error', async () => {
|
||||
|
||||
// await (await Auth.mnemonicInput).waitForDisplayed()
|
||||
await (await Auth.mnemonicInput).addValue(textConstants.randomString)
|
||||
await (await Auth.signIn).click()
|
||||
let getErrorWarning = await (await Auth.error).getText()
|
||||
expect(getErrorWarning).toContain(textConstants.signInRandomString)
|
||||
|
||||
})
|
||||
|
||||
it('should sign in with valid credentials', async () => {
|
||||
|
||||
// go back to create account option
|
||||
await (await Auth.backToSignInOptions).click()
|
||||
await (await Auth.backToWelcomePage).click()
|
||||
// create new mnemonic
|
||||
await (await Auth.createAccount).click()
|
||||
let mnemonic = await (await Auth.mnemonicPhrase).getText()
|
||||
@@ -34,10 +58,10 @@ describe('Wallet login functionality', () => {
|
||||
// verify successful login, balance is visible
|
||||
await (await Balance.balance).waitForDisplayed({ timeout: 4000 })
|
||||
|
||||
// TO-DO the balance is not always caputred, some tests fail with ' ' not equal '0 NYM'
|
||||
// TO-DO the balance is not always caputred, some tests fail with ' ' not equal '0 NYM' ??
|
||||
let balance = await (await Balance.nymBalance).getText()
|
||||
console.log('amountttttttt' + balance)
|
||||
//new accounts will always default to mainnet, so 0 balance
|
||||
expect(balance).toStrictEqual('0 NYM')
|
||||
expect(balance).toStrictEqual(textConstants.noNym)
|
||||
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,53 @@
|
||||
import Auth from '../../pageobjects/authScreens'
|
||||
import Balance from '../../pageobjects/balanceScreen'
|
||||
const textConstants = require("../../../common/text-constants");
|
||||
const userData = require("../../../common/user-data.json");
|
||||
const deleteWallet = require("../../../scripts/deletesavedwallet");
|
||||
const walletExists = require("../../../scripts/savedwalletexists")
|
||||
|
||||
describe('Wallet sign in functionality with password', () => {
|
||||
|
||||
it('sign in with no password throws error', async () => {
|
||||
|
||||
//click through sign without entering a password
|
||||
await (await Auth.signInButton).click()
|
||||
await (await Auth.signInPassword).click()
|
||||
await (await Auth.signInPasswordButton).click()
|
||||
// wait for error
|
||||
await (await Auth.error).waitForDisplayed({ timeout: 1500 })
|
||||
let getErrorWarning = await (await Auth.error).getText()
|
||||
// verify error has the correct message
|
||||
expect(getErrorWarning).toStrictEqual(textConstants.signInWithoutPassword)
|
||||
|
||||
})
|
||||
|
||||
it('sign in with invalid password throws error', async () => {
|
||||
|
||||
// enter invalid password
|
||||
await (await Auth.enterPassword).addValue(textConstants.incorrectPassword)
|
||||
await (await Auth.signInPasswordButton).click()
|
||||
// wait for error
|
||||
await (await Auth.error).waitForDisplayed({ timeout: 1500 })
|
||||
let getErrorWarning = await (await Auth.error).getText()
|
||||
|
||||
// TO-DO GET BACK TO THIS LOGIC. It's currently only searching for the second condition (if the wallet json file doesn't exist)
|
||||
const scriptExist = walletExists.doesFileExist
|
||||
scriptExist ? expect(getErrorWarning).toStrictEqual(textConstants.invalidPasswordOnSignIn) : expect(getErrorWarning).toStrictEqual(textConstants.failedToFindWalletFile)
|
||||
|
||||
})
|
||||
|
||||
it('sign in with invalid password and no saved wallet.json file throws error', async () => {
|
||||
|
||||
// shell script to remove the json file
|
||||
deleteWallet.deleteSavedFile
|
||||
// enter invalid password
|
||||
await (await Auth.enterPassword).addValue(textConstants.incorrectPassword)
|
||||
await (await Auth.signInPasswordButton).click()
|
||||
// wait for error
|
||||
await (await Auth.error).waitForDisplayed({ timeout: 1500 })
|
||||
let getErrorWarning = await (await Auth.error).getText()
|
||||
expect(getErrorWarning).toStrictEqual(textConstants.failedToFindWalletFile)
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
@@ -0,0 +1,72 @@
|
||||
import Auth from '../../pageobjects/authScreens'
|
||||
import Nav from '../../pageobjects/appNavConstants'
|
||||
import Balance from '../../pageobjects/balanceScreen'
|
||||
import Send from '../../pageobjects/sendScreen'
|
||||
import Receive from '../../pageobjects/receiveScreen'
|
||||
import Bond from '../../pageobjects/bondScreen'
|
||||
import Unbond from '../../pageobjects/unbondScreen'
|
||||
import Delegation from '../../pageobjects/delegationScreen'
|
||||
|
||||
const userData = require("../../../common/user-data.json");
|
||||
|
||||
describe('Nav Items behave correctly', () => {
|
||||
|
||||
it('switch from light to dark mode and back', async () => {
|
||||
//log in
|
||||
await Auth.loginWithMnemonic(userData.mnemonic)
|
||||
// click on different modes
|
||||
await (await Nav.lightMode).waitForDisplayed({ timeout: 4000 })
|
||||
await (await Nav.lightMode).click()
|
||||
await (await Nav.darkMode).click()
|
||||
await (await Nav.lightMode).waitForDisplayed({ timeout: 2500 })
|
||||
})
|
||||
|
||||
it('clicking terminal opens the modal', async () => {
|
||||
await (await Nav.terminalIcon).click()
|
||||
let terminalTitle = await (await Nav.terminalTitle).getText()
|
||||
expect(terminalTitle).toContain('Terminal')
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('Menu items lead to correct screen', () => {
|
||||
|
||||
it('check Balance link works', async () => {
|
||||
await (await Nav.balance).click()
|
||||
let balanceTitle = await (await Balance.balance).getText()
|
||||
expect(balanceTitle).toContain('Balance')
|
||||
})
|
||||
|
||||
it('check Send link works', async () => {
|
||||
await (await Nav.send).click()
|
||||
let sendTitle = await (await Send.sendHeader).getText()
|
||||
expect(sendTitle).toContain('Send')
|
||||
await (await Nav.closeIcon).click()
|
||||
})
|
||||
|
||||
it('check Receive link works', async () => {
|
||||
await (await Nav.receive).click()
|
||||
let receiveNymTitle = await (await Receive.receiveNymTitle).getText()
|
||||
expect(receiveNymTitle).toContain('Receive NYM')
|
||||
})
|
||||
|
||||
it('check Bond link works', async () => {
|
||||
await (await Nav.bond).click()
|
||||
let bondTitle = await (await Bond.bondTitle).getText()
|
||||
expect(bondTitle).toContain('Bond')
|
||||
})
|
||||
|
||||
it('check Unbond link works', async () => {
|
||||
await (await Nav.unbond).click()
|
||||
let unbondTitle = await (await Unbond.unbondTitle).getText()
|
||||
expect(unbondTitle).toContain('Unbond')
|
||||
})
|
||||
|
||||
it('check Delegation link works', async () => {
|
||||
await (await Nav.delegation).click()
|
||||
let delegationTitle = await (await Delegation.delegationTitle).getText()
|
||||
expect(delegationTitle).toContain('Delegation')
|
||||
})
|
||||
|
||||
})
|
||||
@@ -0,0 +1,83 @@
|
||||
import Auth from '../../pageobjects/authScreens'
|
||||
import Balance from '../../pageobjects/balanceScreen'
|
||||
const textConstants = require("../../../common/text-constants");
|
||||
const userData = require("../../../common/user-data.json");
|
||||
|
||||
|
||||
describe('Create a new account and verify it exists', () => {
|
||||
|
||||
it('generate new mnemonic and verify mnemonic words', async () => {
|
||||
|
||||
await (await Auth.createAccount).click()
|
||||
await (await Auth.mnemonicPhrase).waitForDisplayed({ timeout: 2500 })
|
||||
let mnemonic = await (await Auth.mnemonicPhrase).getText()
|
||||
let arrayMnemonic = mnemonic.split(" ")
|
||||
await (await Auth.copyMnemonic).click()
|
||||
await (await expect(Auth.iSavedMnemonic).toBeClickable())
|
||||
await (await Auth.iSavedMnemonic).click()
|
||||
|
||||
let mnemonicWordTiles = await (await Auth.mnemonicWordTile)
|
||||
let wordTileIndex = await (await Auth.wordIndex)
|
||||
|
||||
const wordsArray: any[] = []
|
||||
|
||||
for (const word of mnemonicWordTiles) {
|
||||
const wordText = await word.getText()
|
||||
const index = arrayMnemonic.indexOf(wordText)
|
||||
wordsArray.push({ word, index })
|
||||
}
|
||||
|
||||
for (const index of wordTileIndex) {
|
||||
const indexValue = await index.getText()
|
||||
const match = wordsArray.find((word) => +word.index === +indexValue - 1)
|
||||
if (match) {
|
||||
await match.word.click()
|
||||
}
|
||||
}
|
||||
|
||||
const nextButton = await Auth.nextToStep3
|
||||
const isNextDisabled = await nextButton.getAttribute('disabled')
|
||||
expect(isNextDisabled).toBe(null)
|
||||
|
||||
})
|
||||
|
||||
it('click skip password', async () => {
|
||||
await (await Auth.nextToStep3).click()
|
||||
await (await Auth.skipPasswordAndSignInWithMnemonic).click()
|
||||
await (await Auth.mnemonicInput).waitForDisplayed({ timeout: 1500 })
|
||||
await (await Auth.backToSignInOptions).click()
|
||||
})
|
||||
|
||||
it('set up invalid password for new account', async () => {
|
||||
await (await Auth.password).click()
|
||||
await (await Auth.password).addValue(textConstants.incorrectPassword)
|
||||
await (await Auth.confirmPassword).click()
|
||||
await (await Auth.confirmPassword).addValue(textConstants.incorrectPassword)
|
||||
const nextButton = await Auth.next
|
||||
const isNextDisabled = await nextButton.getAttribute('disabled')
|
||||
expect(isNextDisabled).toBe("true")
|
||||
|
||||
})
|
||||
|
||||
it('set up valid password for new account', async () => {
|
||||
await (await Auth.password).click()
|
||||
await (await Auth.password).addValue(textConstants.password)
|
||||
await (await Auth.confirmPassword).click()
|
||||
await (await Auth.confirmPassword).addValue(textConstants.password)
|
||||
const nextButton = await Auth.next
|
||||
const isNextDisabled = await nextButton.getAttribute('disabled')
|
||||
expect(isNextDisabled).toBe(null)
|
||||
})
|
||||
|
||||
it('proceed to login with newly created password', async () => {
|
||||
await (await Auth.next).click()
|
||||
await (await Auth.enterPassword).waitForDisplayed({ timeout: 1500 })
|
||||
await (await Auth.enterPassword).addValue(textConstants.password)
|
||||
await (await Auth.signInPasswordButton).click()
|
||||
|
||||
await (await Balance.balance).waitForDisplayed({ timeout: 4000 })
|
||||
let balance = await (await Balance.nymBalance).getText()
|
||||
//new accounts will always default to mainnet, so 0 balance
|
||||
expect(balance).toStrictEqual(textConstants.noNym)
|
||||
})
|
||||
})
|
||||
@@ -1,74 +0,0 @@
|
||||
import Auth from '../../pageobjects/authScreens'
|
||||
import Balance from '../../pageobjects/balanceScreen'
|
||||
|
||||
|
||||
describe('Create a new account and verify it exists', () => {
|
||||
it('clicking on create account generates new mnemonic', async () => {
|
||||
await (await Auth.createAccount).click()
|
||||
await (await Auth.mnemonicPhrase).waitForDisplayed({ timeout : 1000})()
|
||||
await (await Auth.copyMnemonic).click()
|
||||
await (await expect(Auth.iSavedMnemonic).toBeClickable())
|
||||
})
|
||||
|
||||
it('complete new account creation', async () => {
|
||||
await (await Auth.createAccount).click()
|
||||
let mnemonic = await (await Auth.mnemonicPhrase).getText()
|
||||
let arrayMnemonic = mnemonic.split(" ")
|
||||
// the below will print out the second word of the mnemonic saved
|
||||
console.log(arrayMnemonic[1]);
|
||||
await (await Auth.copyMnemonic).click()
|
||||
await (await Auth.iSavedMnemonic).click()
|
||||
|
||||
// for each number, find the equivalent index from arrayMnemonic, capture word, then find word in mnemonicWord, and click it
|
||||
// OR for each word, find the index+1 and match it to the number seen on the screen
|
||||
|
||||
await (await Auth.number).waitForDisplayed()
|
||||
let itemNumber = await (await Auth.number).getText()
|
||||
let word = await (await Auth.mnemonicWord).getText()
|
||||
|
||||
arrayMnemonic.forEach(function (item, index) {
|
||||
console.log(item, index);
|
||||
for (let num = 0; num < 6; num++) {
|
||||
if ((index + 1) == itemNumber) {
|
||||
console.log('mne word ' + word)
|
||||
Auth.mnemonicWord.click()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// for (let num = 0; num < 6; num++) {
|
||||
// await (await Auth.number).forEach(item => {
|
||||
// let numb = item.getText()
|
||||
// const itemArray = Array.from(numb)
|
||||
// console.log('the numberrr ' + itemArray)
|
||||
// })
|
||||
// }
|
||||
|
||||
// const test = arrayMnemonic.some(word => word.index = itemNumber);
|
||||
// console.log('the test again ' + test);
|
||||
// await (await Auth.mnemonicWord).click()
|
||||
|
||||
|
||||
|
||||
// var values = [];
|
||||
// let numbers = await (await Auth.number).()
|
||||
// for (var i = 0; i < numbers.length; i++) {
|
||||
// values.push(numbers[i].value);
|
||||
// }
|
||||
|
||||
// var numm = (Auth.number).children;
|
||||
// const numarray = Array.from(numm);
|
||||
// numarray.push;
|
||||
// console.log('the numbers ' + numarray)
|
||||
|
||||
|
||||
// the below will print out the text of the first mnemonic button
|
||||
let text = await (await Auth.mnemonicWord).getText([1])
|
||||
console.log('the mnemonic texttttt' + text)
|
||||
|
||||
|
||||
await (await Auth.mnemonicWord).click()
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
@@ -1,7 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"types": ["node", "webdriverio/async", "@wdio/mocha-framework", "expect-webdriverio"],
|
||||
"types": [
|
||||
"node",
|
||||
"webdriverio/async",
|
||||
"@wdio/mocha-framework",
|
||||
"expect-webdriverio"
|
||||
],
|
||||
"target": "ES5"
|
||||
},
|
||||
"include": ["wallet-ui-tests/*"]
|
||||
"include": [
|
||||
"wallet-ui-tests/*"
|
||||
]
|
||||
}
|
||||
@@ -17,7 +17,7 @@ exports.config = {
|
||||
specs: ['./tests/specs/**/*.ts'],
|
||||
|
||||
suites: {
|
||||
welcome: [
|
||||
signup: [
|
||||
'./tests/specs/newaccount/*.ts',
|
||||
],
|
||||
login: [
|
||||
@@ -26,6 +26,9 @@ exports.config = {
|
||||
balance: [
|
||||
'./tests/specs/balance/*.ts',
|
||||
],
|
||||
nav: [
|
||||
'./tests/specs/navbaritems/*.ts',
|
||||
],
|
||||
},
|
||||
// Patterns to exclude.
|
||||
exclude: [
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
reports
|
||||
allure-results
|
||||
node_modules
|
||||
.vscode
|
||||
.idea
|
||||
@@ -1,86 +0,0 @@
|
||||
<!--
|
||||
Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
|
||||
# Nym Wallet Webdriverio testsuite
|
||||
|
||||
A webdriverio test suite implementation using tauri driver
|
||||
with a page object model design. This is to provide quick iterative feedback
|
||||
on the UI of the nym wallet. Currently, tauri-driver is available to run on Windows and Linux machines.
|
||||
|
||||
## Installation prerequisites
|
||||
|
||||
- `Yarn`
|
||||
- `NodeJS >= v16.8.0`
|
||||
- `Rust & cargo >= v1.56.1`
|
||||
- `tauri-driver`
|
||||
- `That you have an existing mnemonic and you can login to the app`
|
||||
- `Have the details listed below to provide the user-data.json file`
|
||||
|
||||
## Key Information
|
||||
|
||||
- Please read the instructions on the `nym/tauri-wallet/README.md` in the root of the project on how to build the application
|
||||
- Please ensure you have the relevant Webdriver kits installed on your machine -
|
||||
|
||||
```
|
||||
linux:
|
||||
sudo apt-get install -y webkit2gtk-driver
|
||||
```
|
||||
|
||||
```
|
||||
windows:
|
||||
download msedgedriver.exe from https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
|
||||
```
|
||||
|
||||
please visit [Tauri Studio](https://tauri.studio/en/docs/usage/guides/webdriver/introduction), this will specify the additional drivers you need
|
||||
|
||||
- The path to run the application is set in the `wdio.conf.js` which lives in the root directory
|
||||
- Before running the suite you need to build the application and check that the application has
|
||||
built successfully, if so, you will have an executable sitting in the target directory in `tauri-wallet/target/*/nym_wallet` (refer to point 1)
|
||||
- The suite will not be able to detect elements on screen if you select a release build, however you can run tests against a release target
|
||||
|
||||
## Installation & usage
|
||||
|
||||
- `test excution happens inside /webdriver directory`
|
||||
- `test data needs to be provided inside the user-data.json`
|
||||
- `check the wdio.conf.cjs to see the test execution along with the path location of the binary`
|
||||
|
||||
```
|
||||
example:
|
||||
//mnemonic is a base64 enconded value, which is your 24 character passphrase, these values are for illustration purposes
|
||||
{
|
||||
"mnemonic" : "dGhpcyBpcyBhIHBhc3NwaHJhc2UK",
|
||||
"punk_address" : "punk1f3dzkhmunma5ze5q952daxca6371989189",
|
||||
"receiver_address" : "punk1p0ce82jxxglpmutvhq4mdwgcwf4avm5n1821982",
|
||||
"amount_to_send" : "1",
|
||||
"identity_key_to_delegate_mix_node": "value",
|
||||
"identity_key_to_delegate_gateway" : "value",
|
||||
"delegate_amount" : "1"
|
||||
}
|
||||
```
|
||||
|
||||
- `yarn test:runall` - the first test run will take some time to spin up be patient
|
||||
- You can run tests individually by passing through the script situated in the package.json for example `yarn test:newuser`
|
||||
|
||||
Tests are categorised and run by their pages, they follow a sequential flow, if one test case fails before the next execution it may derail the next test.
|
||||
|
||||
//todo improve in near future
|
||||
|
||||
## Test reporting
|
||||
|
||||
Currently the tests use allure reporting, the configuration can be altered in the `wdio.conf.cjs`. At present it takes snapshots of any failing tests, the test output run can be seen in the allure-results directory
|
||||
Tests ouput:
|
||||
|
||||
- <guid-testuite.xml>
|
||||
- <guid-attachment.png>
|
||||
|
||||
If any tests fail in their test run it will produce the stack trace error along with the test in question
|
||||
|
||||
## TODO
|
||||
|
||||
_Disclaimer_: Still WIP
|
||||
|
||||
Implement error handling/ beforeTest() - validating json file exists with data for test execution
|
||||
|
||||
Currently this is dev'd against a Linux based OS, not tested against windows yet.
|
||||
@@ -1,12 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
targets: {
|
||||
node: "14",
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
module.exports = {
|
||||
//receivePage
|
||||
recievePageInformation:
|
||||
"You can receive tokens by providing this address to the sender",
|
||||
receivePageHeaderText: "Receive Nym",
|
||||
|
||||
//sendPage
|
||||
sendPunk: "Send punk",
|
||||
|
||||
//homePage
|
||||
homePageErrorMnemonic: "Error parsing bip39 mnemonic",
|
||||
homePageSignIn: "Sign in",
|
||||
createOne: "Create one",
|
||||
walletSuccess:
|
||||
"Please store your mnemonic in a safe place. You'll need it to access your wallet",
|
||||
|
||||
//bondPage // unbondPage
|
||||
bondAlreadyNoded: "Looks like you already have a mixnode bonded.",
|
||||
bondNodeHeaderText: "Bond a node or gateway",
|
||||
unbondNodeHeaderText: "Unbond a mixnode or gateway",
|
||||
unbondMixNodeText: "Looks like you already have a mixnode bonded.",
|
||||
unbondMixNode: "UNBOND",
|
||||
|
||||
//delegatePage // undelegatePage
|
||||
delegateHeaderText: "Delegate\nDelegate to mixnode",
|
||||
nodeIdentityValidationText: "identity is a required field",
|
||||
amountValidationText: "amount is a required field",
|
||||
undelegateHeaderText: "Undelegate from a mixnode or gateway",
|
||||
delegationComplete: "Delegation complete",
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
class Helpers {
|
||||
//helper to decode mnemonic so plain 24 character passphrase isn't in sight albeit it is presented when ruunning the scripts
|
||||
//maybe a show passphrase toggle button?
|
||||
decodeBase = async (input) => {
|
||||
var m = Buffer.from(input, "base64").toString();
|
||||
return m;
|
||||
};
|
||||
|
||||
navigateAndClick = async (element) => {
|
||||
await element.click();
|
||||
};
|
||||
|
||||
scrollIntoView = async (element) => {
|
||||
await element.scrollIntoView();
|
||||
};
|
||||
|
||||
currentBalance = async (value) => {
|
||||
return parseFloat(value.split(/\s+/)[0].toString()).toFixed(5);
|
||||
};
|
||||
|
||||
//todo need to improve calculation - WIP
|
||||
calculateFees = async (beforeBalance, transactionFee, amount, isSend) => {
|
||||
let fee;
|
||||
|
||||
if (isSend) {
|
||||
//send transaction
|
||||
fee = transactionFee.split(/\s+/)[0];
|
||||
} else {
|
||||
//delegate transaction
|
||||
fee = transactionFee.split(/\s+/)[3];
|
||||
}
|
||||
|
||||
const currentBalance = beforeBalance.split(/\s+/)[0];
|
||||
|
||||
const castCurrentBalance = parseFloat(currentBalance).toFixed(5);
|
||||
const transCost = +parseFloat(amount) + +parseFloat(fee).toFixed(5);
|
||||
|
||||
let sum = parseFloat(castCurrentBalance) - parseFloat(transCost);
|
||||
return sum.toFixed(5);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = new Helpers();
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"name": "tauri_nym_wallet",
|
||||
"version": "1.0.0",
|
||||
"private": false,
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test:runall": "wdio run wdio.conf.cjs",
|
||||
"test:sendreceive": "wdio run wdio.conf.cjs --suite sendreceive",
|
||||
"test:home": "wdio run wdio.conf.cjs --suite home",
|
||||
"test:bond": "wdio run wdio.conf.cjs --suite bond",
|
||||
"test:delegate": "wdio run wdio.conf.cjs --suite delegate",
|
||||
"test:newuser": "wdio run wdio.conf.cjs --suite newuser",
|
||||
"run:prettier": "prettier --write .",
|
||||
"test:temp": "wdio run wdio.conf.cjs --suite temp",
|
||||
"test": "wdio run wdio.conf.ts"
|
||||
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "^16.11.0",
|
||||
"@wdio/allure-reporter": "^7.16.1",
|
||||
"@wdio/cli": "^7.9.1",
|
||||
"@zxing/browser": "^0.0.9",
|
||||
"@nymproject/nym-validator-client": "^0.19.0",
|
||||
"ts-node": "^10.6.0"
|
||||
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wdio/local-runner": "^7.14.1",
|
||||
"@wdio/mocha-framework": "^7.14.1",
|
||||
"@wdio/spec-reporter": "^7.14.1",
|
||||
"prettier": "2.4.1",
|
||||
"typescript": "^4.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
class WalletBond {
|
||||
get header() {
|
||||
return $(
|
||||
"#root > div > div:nth-child(2) > div:nth-child(2) > div > div > div > div.MuiCardHeader-root > div > span.MuiTypography-root.MuiCardHeader-subheader.MuiTypography-subtitle1.MuiTypography-colorTextSecondary.MuiTypography-displayBlock"
|
||||
);
|
||||
}
|
||||
get identityKey() {
|
||||
return $("#identityKey");
|
||||
}
|
||||
get sphinxKey() {
|
||||
return $("#sphinxKey");
|
||||
}
|
||||
get amountToBond() {
|
||||
return $("#amount");
|
||||
}
|
||||
get hostInput() {
|
||||
return $("#host");
|
||||
}
|
||||
get versionInput() {
|
||||
return $("version");
|
||||
}
|
||||
get selectAdvancedOptions() {
|
||||
return $("[type='checkbox']");
|
||||
}
|
||||
get mixPort() {
|
||||
return $("#mixPort");
|
||||
}
|
||||
get verlocPort() {
|
||||
return $("#verlocPort");
|
||||
}
|
||||
get httpApiPort() {
|
||||
return $("#httpApiPort");
|
||||
}
|
||||
get bondButton() {
|
||||
return $("[data-testid='bond-button']");
|
||||
}
|
||||
get unBondButton() {
|
||||
return $("[data-testid='un-bond']");
|
||||
}
|
||||
get unBond() {
|
||||
return $("[data-testid='bond-noded']");
|
||||
}
|
||||
get unBondWarning() {
|
||||
return $("div.MuiAlert-message");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new WalletBond();
|
||||
@@ -1,48 +0,0 @@
|
||||
class WalletBond {
|
||||
get header() {
|
||||
return $(
|
||||
"#root > div > div:nth-child(2) > div:nth-child(2) > div > div > div > div.MuiCardHeader-root > div > span.MuiTypography-root.MuiCardHeader-subheader.MuiTypography-subtitle1.MuiTypography-colorTextSecondary.MuiTypography-displayBlock"
|
||||
);
|
||||
}
|
||||
get identityKey() {
|
||||
return $("#identityKey");
|
||||
}
|
||||
get sphinxKey() {
|
||||
return $("#sphinxKey");
|
||||
}
|
||||
get amountToBond() {
|
||||
return $("#amount");
|
||||
}
|
||||
get hostInput() {
|
||||
return $("#host");
|
||||
}
|
||||
get versionInput() {
|
||||
return $("version");
|
||||
}
|
||||
get selectAdvancedOptions() {
|
||||
return $("[type='checkbox']");
|
||||
}
|
||||
get mixPort() {
|
||||
return $("#mixPort");
|
||||
}
|
||||
get verlocPort() {
|
||||
return $("#verlocPort");
|
||||
}
|
||||
get httpApiPort() {
|
||||
return $("#httpApiPort");
|
||||
}
|
||||
get bondButton() {
|
||||
return $("[data-testid='bond-button']");
|
||||
}
|
||||
get unBondButton() {
|
||||
return $("[data-testid='un-bond']");
|
||||
}
|
||||
get unBond() {
|
||||
return $("[data-testid='bond-noded']");
|
||||
}
|
||||
get unBondWarning() {
|
||||
return $("div.MuiAlert-message");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new WalletBond();
|
||||
@@ -1,24 +0,0 @@
|
||||
class WalletCreate {
|
||||
get createAccount() {
|
||||
return $("[href='#']");
|
||||
}
|
||||
get create() {
|
||||
return $("[data-testid='create-button']");
|
||||
}
|
||||
get accountCreatedSuccessfully() {
|
||||
return $("[data-testid='mnemonic-warning']");
|
||||
}
|
||||
get walletMnemonicValue() {
|
||||
return $("[data-testid='mnemonic-phrase']");
|
||||
}
|
||||
get punkAddress() {
|
||||
return $("[data-testid='wallet-address']");
|
||||
}
|
||||
get backToSignIn() {
|
||||
return $("[data-testid='sign-in-button']");
|
||||
}
|
||||
get signInButton() {
|
||||
return $("[type='submit']");
|
||||
}
|
||||
}
|
||||
module.exports = new WalletCreate();
|
||||
@@ -1,60 +0,0 @@
|
||||
class WalletDelegate {
|
||||
get header() {
|
||||
return $("[data-testid='Delegate']");
|
||||
}
|
||||
get nodeIdentity() {
|
||||
return $("#identity");
|
||||
}
|
||||
get amountToDelegate() {
|
||||
return $("#amount");
|
||||
}
|
||||
get identityValidation() {
|
||||
return $("#identity-helper-text");
|
||||
}
|
||||
get amountToDelegateValidation() {
|
||||
return $("#amount-helper-text");
|
||||
}
|
||||
get delegateStakeButton() {
|
||||
return $("[data-testid='delegate-button']");
|
||||
}
|
||||
get mixNodeRadioButton() {
|
||||
return $("[data-testid='mix-node']");
|
||||
}
|
||||
get gateWayRadioButton() {
|
||||
return $("[data-testid='gate-way']");
|
||||
}
|
||||
get successfullyDelegate() {
|
||||
return $("[data-testid='delegate-success']");
|
||||
}
|
||||
get finishButton() {
|
||||
return $("[data-testid='finish-button']");
|
||||
}
|
||||
get transactionFeeAmount() {
|
||||
return $("[data-testid='fee-amount']");
|
||||
}
|
||||
get accountBalance() {
|
||||
return $("[data-testid='account-balance']");
|
||||
}
|
||||
|
||||
//Undelegate
|
||||
get unDelegateHeader() {
|
||||
return $("[data-testid='Undelegate']");
|
||||
}
|
||||
get unNodeIdentity() {
|
||||
return $("[name='identity']");
|
||||
}
|
||||
get unDelegateFeeText() {
|
||||
return $("[data-testid='fee-amount']");
|
||||
}
|
||||
get unDelegateGatewayRadioButton() {
|
||||
return $("[data-testid='gate-way']");
|
||||
}
|
||||
get unMixNodeRadioButton() {
|
||||
return $("[data-testid='mix-node']");
|
||||
}
|
||||
get unDelegateButton() {
|
||||
return $("[data-testid='submit-button']");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new WalletDelegate();
|
||||
@@ -1,42 +0,0 @@
|
||||
class WalletHome {
|
||||
get balanceCheck() {
|
||||
return $(
|
||||
"#root > div > div:nth-child(2) > div:nth-child(2) > div > div > div > div.MuiCardHeader-root > div > span"
|
||||
);
|
||||
}
|
||||
get punkBalance() {
|
||||
return $("");
|
||||
}
|
||||
get punkAddress() {
|
||||
return $("[data-testid='wallet-address']");
|
||||
}
|
||||
get accountBalance() {
|
||||
return $("[data-testid='account-balance']");
|
||||
}
|
||||
get balanceButton() {
|
||||
return $("[href='/balance']");
|
||||
}
|
||||
get sendButton() {
|
||||
return $("[href='/send']");
|
||||
}
|
||||
get receiveButton() {
|
||||
return $("[href='/receive']");
|
||||
}
|
||||
get bondButton() {
|
||||
return $("[href='/bond']");
|
||||
}
|
||||
get unBondButton() {
|
||||
return $("[href='/unbond']");
|
||||
}
|
||||
get delegateButton() {
|
||||
return $("[href='/delegate']");
|
||||
}
|
||||
get unDelegateButton() {
|
||||
return $("[href='/undelegate']");
|
||||
}
|
||||
get logOutButton() {
|
||||
return $("[data-testid='log-out']");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new WalletHome();
|
||||
@@ -1,31 +0,0 @@
|
||||
class WalletLogin {
|
||||
get signInLabel() {
|
||||
return $("[data-testid='sign-in']");
|
||||
}
|
||||
get mnemonic() {
|
||||
return $("#mnemonic");
|
||||
}
|
||||
get signInButton() {
|
||||
return $("[type='submit']");
|
||||
}
|
||||
get errorValidation() {
|
||||
return $("[class='MuiAlert-message']");
|
||||
}
|
||||
get accountBalance() {
|
||||
return $("[data-test-id='account-balance']");
|
||||
}
|
||||
get accountBalanceText() {
|
||||
return $("[class='MuiAlert-message']");
|
||||
}
|
||||
get walletAddress() {
|
||||
return $("[data-testid='wallet-address']");
|
||||
}
|
||||
|
||||
//login to the application
|
||||
enterMnemonic = async (mnemonic) => {
|
||||
await this.mnemonic.addValue(mnemonic);
|
||||
await this.signInButton.click();
|
||||
await this.accountBalance.isExisting();
|
||||
};
|
||||
}
|
||||
module.exports = new WalletLogin();
|
||||
@@ -1,37 +0,0 @@
|
||||
class WalletReceive {
|
||||
get receiveNymHeader() {
|
||||
return $(
|
||||
"#root > div > div:nth-child(2) > div:nth-child(2) > div > div > div > div.MuiCardHeader-root > div > span"
|
||||
);
|
||||
}
|
||||
get receiveNymText() {
|
||||
return $("[data-testid='receive-nym']");
|
||||
}
|
||||
get walletAddress() {
|
||||
return $("[data-testid='client-address']");
|
||||
}
|
||||
get copyButton() {
|
||||
return $("[data-testid='copy-button']");
|
||||
}
|
||||
get qrCode() {
|
||||
return $("[data-testid='qr-code']");
|
||||
}
|
||||
|
||||
WaitForButtonChangeOnCopy = async () => {
|
||||
await this.copyButton.click();
|
||||
|
||||
await this.copyButton.waitForDisplayed({ timeout: 1500 });
|
||||
|
||||
await this.copyButton.waitUntil(
|
||||
async function () {
|
||||
return (await this.getText()) === "COPIED";
|
||||
},
|
||||
{
|
||||
timeout: 1500,
|
||||
timeoutMsg: "expected text to be different after 1.5s",
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = new WalletReceive();
|
||||
@@ -1,52 +0,0 @@
|
||||
class WalletSend {
|
||||
get fromAddress() {
|
||||
return $("#from");
|
||||
}
|
||||
get toAddress() {
|
||||
return $("#to");
|
||||
}
|
||||
get amount() {
|
||||
return $("#amount");
|
||||
}
|
||||
get nextButton() {
|
||||
return $("[data-testid='button");
|
||||
}
|
||||
get sendHeader() {
|
||||
return $("[data-testid='Send punk']");
|
||||
}
|
||||
get accountBalance() {
|
||||
return $("[data-testid='account-balance']");
|
||||
}
|
||||
get amountReviewAndSend() {
|
||||
return $("[data-testid='Amount']");
|
||||
}
|
||||
get toAddressReviewAndSend() {
|
||||
return $("[data-testid='To']");
|
||||
}
|
||||
get fromAddressReviewAndSend() {
|
||||
return $("[data-testid='From']");
|
||||
}
|
||||
get transferFeeAmount() {
|
||||
return $("[data-testid='Transfer fee']");
|
||||
}
|
||||
get reviewAndSendBackButton() {
|
||||
return $("[data-testid='back-button']");
|
||||
}
|
||||
get sendButton() {
|
||||
return $("[data-testid='button']");
|
||||
}
|
||||
get transactionComplete() {
|
||||
return $("[data-testid='transaction-complete']");
|
||||
}
|
||||
get transactionCompleteRecipient() {
|
||||
return $("[data-testid='to-address']");
|
||||
}
|
||||
get transactionCompleteAmount() {
|
||||
return $("[data-testid='send-amount']");
|
||||
}
|
||||
get finishButton() {
|
||||
return $("[data-testid='button']");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new WalletSend();
|
||||
@@ -1,22 +0,0 @@
|
||||
class WallentUndelegate {
|
||||
get transactionFee() {
|
||||
return $("[data-testid='fee-amount']");
|
||||
}
|
||||
get mixNodeRadioButton() {
|
||||
return $("[value='mixnode']");
|
||||
}
|
||||
get gatewayRadionButton() {
|
||||
return $("[value='gateway']");
|
||||
}
|
||||
get nodeIdentity() {
|
||||
return $("#mui-55011");
|
||||
}
|
||||
get identityHelper() {
|
||||
return $("#identity-helper-text");
|
||||
}
|
||||
get delegateButton() {
|
||||
return $("[data-testid='submit-button']");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new WallentUndelegate();
|
||||
@@ -1,54 +0,0 @@
|
||||
const userData = require("../../../common/data/user-data.json");
|
||||
const helper = require("../../../common/helpers/helper");
|
||||
const walletLogin = require("../../pages/wallet.login");
|
||||
const textConstants = require("../../../common/constants/text-constants");
|
||||
const walletHomepage = require("../../pages/wallet.homepage");
|
||||
const bondPage = require("../../pages/wallet.bond");
|
||||
|
||||
describe("bonding and unbonding nodes", () => {
|
||||
it("should have a node already bonded and validate no input fields are enabled", async () => {
|
||||
const mnemonic = await helper.decodeBase(userData.mnemonic);
|
||||
|
||||
await walletLogin.enterMnemonic(mnemonic);
|
||||
|
||||
await helper.navigateAndClick(walletHomepage.bondButton);
|
||||
|
||||
await helper.scrollIntoView(bondPage.selectAdvancedOptions);
|
||||
|
||||
await bondPage.selectAdvancedOptions.click();
|
||||
|
||||
//as bond node is mixed expect all the fields to be disabled
|
||||
const getText = await bondPage.header.getText();
|
||||
const getIdentity = await bondPage.identityKey.isEnabled();
|
||||
const getSphinxKey = await bondPage.sphinxKey.isEnabled();
|
||||
const amountToBond = await bondPage.amountToBond.isEnabled();
|
||||
const hostInput = await bondPage.hostInput.isEnabled();
|
||||
const verlocPort = await bondPage.verlocPort.isEnabled();
|
||||
const httpApiPort = await bondPage.httpApiPort.isEnabled();
|
||||
const mixPort = await bondPage.mixPort.isEnabled();
|
||||
|
||||
//assert all field are not functional
|
||||
expect(getText).toEqual(textConstants.bondNodeHeaderText);
|
||||
expect(getIdentity).toEqual(false);
|
||||
expect(getSphinxKey).toEqual(false);
|
||||
expect(amountToBond).toEqual(false);
|
||||
expect(hostInput).toEqual(false);
|
||||
expect(verlocPort).toEqual(false);
|
||||
expect(httpApiPort).toEqual(false);
|
||||
expect(mixPort).toEqual(false);
|
||||
});
|
||||
|
||||
it("unbond mix monde screen should be present with the option to unbond", async () => {
|
||||
//we do not want to unbond our node, check that elements are selectable
|
||||
await helper.scrollIntoView(walletHomepage.unBondButton);
|
||||
await helper.navigateAndClick(walletHomepage.unBondButton);
|
||||
|
||||
const getText = await bondPage.header.getText();
|
||||
const unbondText = await bondPage.unBondWarning.getText();
|
||||
|
||||
await bondPage.unBondButton.isClickable();
|
||||
//assert all field are not functional
|
||||
expect(getText).toEqual(textConstants.unbondNodeHeaderText);
|
||||
expect(unbondText).toEqual(textConstants.unbondMixNodeText);
|
||||
});
|
||||
});
|
||||
@@ -1,108 +0,0 @@
|
||||
const userData = require("../../../common/data/user-data.json");
|
||||
const helper = require("../../../common/helpers/helper");
|
||||
const walletLogin = require("../../pages/wallet.login");
|
||||
const textConstants = require("../../../common/constants/text-constants");
|
||||
const walletHomepage = require("../../pages/wallet.homepage");
|
||||
const delegatePage = require("../../pages/wallet.delegate");
|
||||
|
||||
describe("delegate to a mix node or gateway", () => {
|
||||
it("ensure that fields are enabled for existing user", async () => {
|
||||
const mnemonic = await helper.decodeBase(userData.mnemonic);
|
||||
|
||||
await walletLogin.enterMnemonic(mnemonic);
|
||||
|
||||
await helper.navigateAndClick(walletHomepage.delegateButton);
|
||||
|
||||
const getText = await delegatePage.header.getText();
|
||||
|
||||
expect(getText).toEqual(textConstants.delegateHeaderText);
|
||||
});
|
||||
|
||||
it("submitting the form without input prompts validation errors", async () => {
|
||||
await delegatePage.delegateStakeButton.click();
|
||||
|
||||
const getIdentityValidation =
|
||||
await delegatePage.identityValidation.getText();
|
||||
const getAmountValidation =
|
||||
await delegatePage.amountToDelegateValidation.getText();
|
||||
|
||||
expect(getIdentityValidation).toEqual(
|
||||
textConstants.nodeIdentityValidationText
|
||||
);
|
||||
expect(getAmountValidation).toEqual(textConstants.amountValidationText);
|
||||
});
|
||||
|
||||
it("input delegate amount to a mix node then broadcast the transaction then check account balances", async () => {
|
||||
const balanceText = await delegatePage.accountBalance.getText();
|
||||
|
||||
const getTransfeeAmount = await delegatePage.transactionFeeAmount.getText();
|
||||
|
||||
await delegatePage.nodeIdentity.setValue(
|
||||
userData.identity_key_to_delegate_mix_node
|
||||
);
|
||||
|
||||
await delegatePage.amountToDelegate.setValue(userData.delegate_amount);
|
||||
|
||||
//transfer fee + amount delegation
|
||||
const sumCost = await helper.calculateFees(
|
||||
balanceText,
|
||||
getTransfeeAmount,
|
||||
userData.delegate_amount,
|
||||
false
|
||||
);
|
||||
|
||||
await delegatePage.delegateStakeButton.click();
|
||||
|
||||
await delegatePage.successfullyDelegate.waitForClickable({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
const getConfirmationText =
|
||||
await delegatePage.successfullyDelegate.getText();
|
||||
expect(getConfirmationText).toContain(textConstants.delegationComplete);
|
||||
|
||||
const availablePunk = await delegatePage.accountBalance.getText();
|
||||
//expect new account balance - the fee calculation above
|
||||
|
||||
await delegatePage.finishButton.click();
|
||||
|
||||
expect(await helper.currentBalance(availablePunk)).toEqual(sumCost);
|
||||
});
|
||||
|
||||
it("input amount to stake to a gateway then broadcast the transaction then check account balances", async () => {
|
||||
const balanceText = await delegatePage.accountBalance.getText();
|
||||
|
||||
const getTransfeeAmount = await delegatePage.transactionFeeAmount.getText();
|
||||
|
||||
await delegatePage.gateWayRadioButton.click();
|
||||
|
||||
await delegatePage.nodeIdentity.setValue(
|
||||
userData.identity_key_to_delegate_gateway
|
||||
);
|
||||
|
||||
await delegatePage.amountToDelegate.setValue(userData.delegate_amount);
|
||||
|
||||
//transfer fee + amount delegation
|
||||
|
||||
const sumCost = await helper.calculateFees(
|
||||
balanceText,
|
||||
getTransfeeAmount,
|
||||
userData.delegate_amount,
|
||||
false
|
||||
);
|
||||
|
||||
await delegatePage.delegateStakeButton.click();
|
||||
|
||||
await delegatePage.successfullyDelegate.waitForClickable({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
const getConfirmationText =
|
||||
await delegatePage.successfullyDelegate.getText();
|
||||
expect(getConfirmationText).toContain(textConstants.delegationComplete);
|
||||
|
||||
const availablePunk = await delegatePage.accountBalance.getText();
|
||||
//expect new account balance - the fee calculation above
|
||||
expect(await helper.currentBalance(availablePunk)).toEqual(sumCost);
|
||||
});
|
||||
});
|
||||
@@ -1,45 +0,0 @@
|
||||
const userData = require("../../../common/data/user-data.json");
|
||||
const helper = require("../../../common/helpers/helper");
|
||||
const walletLogin = require("../../pages/wallet.login");
|
||||
const homepPage = require("../../pages/wallet.homepage");
|
||||
const textConstants = require("../../../common/constants/text-constants");
|
||||
|
||||
describe("wallet splash screen", () => {
|
||||
it("should have the sign in header present", async () => {
|
||||
const signInText = await walletLogin.signInLabel.getText();
|
||||
expect(signInText).toEqual(textConstants.homePageSignIn);
|
||||
});
|
||||
|
||||
it("submitting the sign in button with no input throws a validation error", async () => {
|
||||
await walletLogin.signInButton.click();
|
||||
|
||||
const errorResponseText = await walletLogin.errorValidation.getText();
|
||||
expect(errorResponseText).toEqual(textConstants.homePageErrorMnemonic);
|
||||
});
|
||||
|
||||
//currently the punk_address is not fully displayed on the wallet UI
|
||||
//trim the punk address
|
||||
it("successfully input mnemonic and log in", async () => {
|
||||
const mnemonic = await helper.decodeBase(userData.mnemonic);
|
||||
|
||||
await walletLogin.enterMnemonic(mnemonic);
|
||||
|
||||
await walletLogin.walletAddress.waitForEnabled({ timeout: 5000 });
|
||||
|
||||
const getWalletAddress = await walletLogin.walletAddress.getText();
|
||||
//currently 35 characters are displayed along with three ...
|
||||
//current hack we can assume this is the correct wallet
|
||||
const walletTruncated = userData.punk_address.substring(0, 35);
|
||||
|
||||
expect(walletTruncated + "...").toContain(getWalletAddress);
|
||||
});
|
||||
|
||||
it("successfully log out the application", async () => {
|
||||
await helper.scrollIntoView(homepPage.logOutButton);
|
||||
|
||||
await homepPage.logOutButton.click();
|
||||
|
||||
await walletLogin.signInLabel.waitForEnabled({ timeout: 1500 });
|
||||
expect(await walletLogin.signInLabel.isDisplayed()).toEqual(true);
|
||||
});
|
||||
});
|
||||
@@ -1,28 +0,0 @@
|
||||
const userData = require("../../../common/data/user-data.json");
|
||||
const textConstants = require("../../../common/constants/text-constants");
|
||||
const helper = require("../../../common/helpers/helper");
|
||||
const walletLogin = require("../../pages/wallet.login");
|
||||
const receive = require("../../pages/wallet.receive");
|
||||
const walletHomepage = require("../../pages/wallet.homepage");
|
||||
|
||||
describe("provide the relevant information about a user nym wallet address", () => {
|
||||
it("should have the receivers address and a qr code present", async () => {
|
||||
const mnemonic = await helper.decodeBase(userData.mnemonic);
|
||||
|
||||
await walletLogin.enterMnemonic(mnemonic);
|
||||
|
||||
await helper.navigateAndClick(walletHomepage.receiveButton);
|
||||
|
||||
await receive.receiveNymHeader.waitForDisplayed({ timeout: 1500 });
|
||||
|
||||
await receive.WaitForButtonChangeOnCopy();
|
||||
|
||||
const textHeader = await receive.receiveNymHeader.getText();
|
||||
const getInformationText = await receive.receiveNymText.getText();
|
||||
const getPunkAddress = await receive.walletAddress.getText();
|
||||
|
||||
expect(getPunkAddress).toEqual(userData.punk_address);
|
||||
expect(getInformationText).toEqual(textConstants.recievePageInformation);
|
||||
expect(textConstants.receivePageHeaderText).toEqual(textHeader);
|
||||
});
|
||||
});
|
||||
@@ -1,55 +0,0 @@
|
||||
const userData = require("../../../common/data/user-data.json");
|
||||
const helper = require("../../../common/helpers/helper");
|
||||
const textConstants = require("../../../common/constants/text-constants");
|
||||
const walletLogin = require("../../pages/wallet.login");
|
||||
const sendWallet = require("../../pages/wallet.send");
|
||||
const walletHomepage = require("../../pages/wallet.homepage");
|
||||
|
||||
describe("send punk to another a wallet", () => {
|
||||
it("expect send screen to display the data", async () => {
|
||||
const mnemonic = await helper.decodeBase(userData.mnemonic);
|
||||
|
||||
await walletLogin.enterMnemonic(mnemonic);
|
||||
|
||||
await helper.navigateAndClick(walletHomepage.sendButton);
|
||||
|
||||
const textHeader = await sendWallet.sendHeader.getText();
|
||||
|
||||
expect(textHeader).toContain(textConstants.sendPunk);
|
||||
});
|
||||
|
||||
it("send funds correctly to another punk address", async () => {
|
||||
//already logged in due to the previous test
|
||||
const getCurrentBalance = await walletHomepage.accountBalance.getText();
|
||||
|
||||
await sendWallet.toAddress.addValue(userData.receiver_address);
|
||||
|
||||
await sendWallet.amount.addValue(userData.amount_to_send);
|
||||
|
||||
await sendWallet.nextButton.waitForEnabled({ timeout: 3000 });
|
||||
|
||||
await sendWallet.nextButton.click();
|
||||
|
||||
const transFee = await sendWallet.transferFeeAmount.getText();
|
||||
|
||||
await sendWallet.sendButton.click();
|
||||
|
||||
await sendWallet.finishButton.waitForClickable({ timeout: 10000 });
|
||||
|
||||
let sumCost = await helper.calculateFees(
|
||||
getCurrentBalance,
|
||||
transFee,
|
||||
userData.amount_to_send,
|
||||
true
|
||||
);
|
||||
|
||||
await walletHomepage.accountBalance.isDisplayed();
|
||||
|
||||
const availablePunk = await walletHomepage.accountBalance.getText();
|
||||
|
||||
await sendWallet.finishButton.click();
|
||||
|
||||
//expect new account balance - the fee calculation above
|
||||
expect(await helper.currentBalance(availablePunk)).toEqual(sumCost);
|
||||
});
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
const userData = require("../../../common/data/user-data.json");
|
||||
const helper = require("../../../common/helpers/helper");
|
||||
const walletLogin = require("../../pages/wallet.login");
|
||||
const walletHomepage = require("../../pages/wallet.homepage");
|
||||
const unDelegatePage = require("../../pages/wallet.delegate");
|
||||
|
||||
describe("un-delegate a mix node or gateway", () => {
|
||||
it("ensure that fields are enabled for existing user", async () => {
|
||||
//we are ensuring that the fields are selectable for undelegation
|
||||
//not proceeding to undelegate a node or gateway
|
||||
|
||||
const mnemonic = await helper.decodeBase(userData.mnemonic);
|
||||
|
||||
await walletLogin.enterMnemonic(mnemonic);
|
||||
|
||||
await helper.scrollIntoView(walletHomepage.unDelegateButton);
|
||||
|
||||
await helper.navigateAndClick(walletHomepage.unDelegateButton);
|
||||
|
||||
await unDelegatePage.unDelegateButton.waitForClickable({ timeout: 1500 });
|
||||
|
||||
await unDelegatePage.unDelegateButton.isEnabled();
|
||||
|
||||
await unDelegatePage.unDelegateGatewayRadioButton.click();
|
||||
|
||||
await unDelegatePage.unDelegateGatewayRadioButton.isSelected();
|
||||
|
||||
const mixNodeRadioButton =
|
||||
await unDelegatePage.unMixNodeRadioButton.isSelected();
|
||||
expect(mixNodeRadioButton).toEqual(false);
|
||||
});
|
||||
});
|
||||
@@ -1,39 +0,0 @@
|
||||
const walletLogin = require("../../pages/wallet.login");
|
||||
const walletSignUp = require("../../pages/wallet.create");
|
||||
const textConstants = require("../../../common/constants/text-constants");
|
||||
|
||||
describe("non existing wallet holder", () => {
|
||||
//wallet mnemonic gets pushed here
|
||||
const DATA = [];
|
||||
it("create a new account and wallet", async () => {
|
||||
const signInText = await walletLogin.signInLabel.getText();
|
||||
expect(signInText).toEqual(textConstants.homePageSignIn);
|
||||
|
||||
await walletSignUp.createAccount.click();
|
||||
|
||||
//wallet generation takes some time - apply wait
|
||||
await walletSignUp.create.click();
|
||||
|
||||
await walletSignUp.accountCreatedSuccessfully.waitForEnabled({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
const getWalletText = await walletSignUp.punkAddress.getText();
|
||||
expect(getWalletText.length).toEqual(43);
|
||||
|
||||
const accountCreated =
|
||||
await walletSignUp.accountCreatedSuccessfully.getText();
|
||||
expect(accountCreated).toEqual(textConstants.walletSuccess);
|
||||
|
||||
const getMnemonic = await walletSignUp.walletMnemonicValue.getText();
|
||||
DATA.push(getMnemonic);
|
||||
});
|
||||
|
||||
it("navigate back to sign in screen and validate mnemonic works", async () => {
|
||||
await walletSignUp.backToSignIn.click();
|
||||
|
||||
await walletLogin.enterMnemonic(DATA[0]);
|
||||
|
||||
await walletLogin.walletAddress.isDisplayed();
|
||||
});
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
import ValidatorClient from '@nymproject/nym-validator-client';
|
||||
|
||||
describe('Creating valid account', () => {
|
||||
it('send nyms from one account to another', async () =>{
|
||||
const benny = "giraffe note order sun cradle bottom crime humble able antique rural donkey guess parent potato tongue truly way disagree exile zebra someone else typical";
|
||||
const mnemonic = ValidatorClient.randomMnemonic();
|
||||
console.log(ValidatorClient);
|
||||
const newAccountClient = await ValidatorClient.connect(mnemonic,
|
||||
'https://qa-validator.nymtech.net', 'https://qa-validator-api.nymtech.net/api', 'n', 'n1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsd3qaep', 'n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav', 'nym');
|
||||
const address = newAccountClient.address;
|
||||
console.log({ address, mnemonic });
|
||||
|
||||
const client = await ValidatorClient.connect(
|
||||
benny, 'https://qa-validator.nymtech.net', 'https://qa-validator-api.nymtech.net/api', 'n', 'n1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsd3qaep', 'n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav', 'nym');
|
||||
|
||||
await client.send(address, [{ amount: '10000000', denom: 'unym' }]);
|
||||
const balance = await client.getBalance(address);
|
||||
console.log({ balance });
|
||||
expect(Number.parseFloat(balance.amount)).toBe(10000000);
|
||||
}).timeout(5000);
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
// the newly created address from the test above:
|
||||
|
||||
// address: 'n13l7rwrygs0m3kx3en2eh55dtmwlzm0vskw0hxq',
|
||||
// mnemonic: 'tree upset require kitten inquiry truck emotion ladder reject elbow page ability spot win board frog child much credit pizza picture hover medal zoo'
|
||||
|
||||
// always make sure it's on QA, unless youre on debug branch (~look in nym_path wdio.config.ts to check)
|
||||
// ENABLE_QA_MODE=true target/release/nym-wallet
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"types": ["node", "webdriverio/async", "@wdio/mocha-framework", "expect-webdriverio"],
|
||||
"target": "ES5"
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
const os = require("os");
|
||||
const path = require("path");
|
||||
const { spawn, spawnSync } = require("child_process");
|
||||
//insert path to binary
|
||||
const nym_path = "../target/release/nym-wallet";
|
||||
|
||||
exports.config = {
|
||||
//run sequentially, as using one default user may cause issues for parallel test runs for now
|
||||
specs: [
|
||||
"./tests/specs/existinguser/test.wallet.home.js",
|
||||
"./tests/specs/existinguser/test.wallet.send.js",
|
||||
"./tests/specs/existinguser/test.wallet.receive.js",
|
||||
"./tests/specs/existinguser/test.wallet.bond.js",
|
||||
"./tests/specs/existinguser/test.wallet.delegate.js",
|
||||
"./tests/specs/newuser/test.wallet.create.js",
|
||||
],
|
||||
|
||||
//run tests by providing --suite {{login}}
|
||||
suites: {
|
||||
home: ["./tests/specs/existinguser/test.wallet.home.js"],
|
||||
sendreceive: [
|
||||
"./tests/specs/existinguser/test.wallet.send.js",
|
||||
"./tests/specs/existinguser/test.wallet.receive.js",
|
||||
],
|
||||
bond: ["./tests/specs/existinguser/test.wallet.bond.js"],
|
||||
delegate: [
|
||||
"./tests/specs/existinguser/test.wallet.delegate.js",
|
||||
"./tests/specs/existinguser/test.wallet.undelegate.js",
|
||||
],
|
||||
newuser: ["./tests/specs/newuser/test.wallet.create.js"],
|
||||
temp:["./tests/specs/temp/temp.spec.ts"],
|
||||
},
|
||||
maxInstances: 1,
|
||||
capabilities: [
|
||||
{
|
||||
maxInstances: 1,
|
||||
"tauri:options": {
|
||||
application: nym_path,
|
||||
},
|
||||
},
|
||||
],
|
||||
// ===================
|
||||
// Test Configurations
|
||||
// ===================
|
||||
// Define all options that are relevant for the WebdriverIO instance here
|
||||
// Level of logging verbosity: trace | debug | info | warn | error | silent
|
||||
bail: 0,
|
||||
framework: "mocha",
|
||||
reporters: ["spec"],
|
||||
mochaOpts: {
|
||||
ui: "bdd",
|
||||
timeout: 60000,
|
||||
},
|
||||
logLevel: "silent",
|
||||
|
||||
// ===================
|
||||
// Test Reporters
|
||||
// ===================
|
||||
reporters: [
|
||||
[
|
||||
"allure",
|
||||
{
|
||||
outputDir: "allure-results",
|
||||
disableWebdriverStepsReporting: true,
|
||||
disableWebdriverScreenshotsReporting: true,
|
||||
},
|
||||
],
|
||||
],
|
||||
|
||||
// this is documentented in the readme - you will need to build the project first
|
||||
// ensure the rust project is built since we expect this binary to exist for the webdriver sessions
|
||||
//onPrepare: () => spawnSync("cargo", ["build", "--release"]),
|
||||
|
||||
// ensure we are running `tauri-driver` before the session starts so that we can proxy the webdriver requests
|
||||
beforeSession: () =>
|
||||
(tauriDriver = spawn(
|
||||
path.resolve(os.homedir(), ".cargo", "bin", "tauri-driver"),
|
||||
[],
|
||||
{ stdio: [null, process.stdout, process.stderr] }
|
||||
)),
|
||||
|
||||
afterTest: function (
|
||||
test,
|
||||
context,
|
||||
{ error, result, duration, passed, retries }
|
||||
) {
|
||||
if (error) {
|
||||
browser.takeScreenshot();
|
||||
}
|
||||
},
|
||||
|
||||
// clean up the `tauri-driver` process we spawned at the start of the session
|
||||
afterSession: () => tauriDriver.kill(),
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const { spawn, spawnSync } = require('child_process')
|
||||
//insert path to binary
|
||||
const nym_path = '../target/debug/nym_wallet'
|
||||
|
||||
let tauriDriver: any
|
||||
|
||||
exports.config = {
|
||||
autoCompileOpts: {
|
||||
autoCompile: true,
|
||||
tsNodeOpts: {
|
||||
transpileOnly: true,
|
||||
project: 'tsconfig.json',
|
||||
},
|
||||
},
|
||||
specs: ['./tests/specs/**/*.ts'],
|
||||
|
||||
suites: {
|
||||
welcome: [
|
||||
'./tests/specs/newaccount/*.ts',
|
||||
]},
|
||||
// Patterns to exclude.
|
||||
exclude: [
|
||||
// 'path/to/excluded/files'
|
||||
],
|
||||
maxInstances: 1,
|
||||
capabilities: [
|
||||
{
|
||||
maxInstances: 1,
|
||||
'tauri:options': {
|
||||
application: nym_path,
|
||||
},
|
||||
},
|
||||
],
|
||||
//
|
||||
// ===================
|
||||
// Test Configurations
|
||||
// ===================
|
||||
// Define all options that are relevant for the WebdriverIO instance here
|
||||
//
|
||||
// Level of logging verbosity: trace | debug | info | warn | error | silent
|
||||
logLevel: 'info',
|
||||
bail: 0,
|
||||
framework: 'mocha',
|
||||
reporters: ['spec'],
|
||||
mochaOpts: {
|
||||
ui: 'bdd',
|
||||
timeout: 60000,
|
||||
},
|
||||
// ===================
|
||||
// Test Reporters
|
||||
// ===================
|
||||
// reporters: [
|
||||
// [
|
||||
// "allure",
|
||||
// {
|
||||
// outputDir: "allure-results",
|
||||
// disableWebdriverStepsReporting: true,
|
||||
// disableWebdriverScreenshotsReporting: true,
|
||||
// },
|
||||
// ],
|
||||
// ],
|
||||
|
||||
// this is documentented in the readme - you will need to build the project first
|
||||
// ensure the rust project is built since we expect this binary to exist for the webdriver sessions
|
||||
//onPrepare: () => spawnSync("cargo", ["build", "--release"]),
|
||||
|
||||
// ensure we are running `tauri-driver` before the session starts so that we can proxy the webdriver requests
|
||||
beforeSession: () =>
|
||||
(tauriDriver = spawn(path.resolve(os.homedir(), '.cargo', 'bin', 'tauri-driver'), [], {
|
||||
stdio: [null, process.stdout, process.stderr],
|
||||
})),
|
||||
|
||||
// afterTest: function (
|
||||
// test,
|
||||
// context,
|
||||
// { error, result, duration, passed, retries }
|
||||
// ) {
|
||||
// if (error) {
|
||||
// browser.takeScreenshot();
|
||||
// }
|
||||
// },
|
||||
|
||||
// clean up the `tauri-driver` process we spawned at the start of the session
|
||||
afterSession: () => tauriDriver.kill(),
|
||||
}
|
||||
@@ -27,7 +27,7 @@ export const CopyToClipboard: React.FC<{
|
||||
{showConfirmation ? (
|
||||
<DoneIcon color="success" sx={sx} />
|
||||
) : (
|
||||
<ContentCopyIcon onClick={handleCopy} sx={{ cursor: 'pointer', ...sx }} />
|
||||
<ContentCopyIcon data-testid="ContentCopyIcon" onClick={handleCopy} sx={{ cursor: 'pointer', ...sx }} />
|
||||
)}
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user