From 60076dd65bc5caa6e81ed45a738621d0dc3f4107 Mon Sep 17 00:00:00 2001 From: abefernan Date: Thu, 23 Apr 2020 13:15:37 +0200 Subject: [PATCH 1/9] Adds routes for starnames & iovnames and reorders --- packages/bierzo-wallet/src/routes/index.tsx | 22 +++++++++++++------- packages/bierzo-wallet/src/routes/paths.ts | 23 +++++++++++---------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/packages/bierzo-wallet/src/routes/index.tsx b/packages/bierzo-wallet/src/routes/index.tsx index e3b42dd4d..164143b04 100644 --- a/packages/bierzo-wallet/src/routes/index.tsx +++ b/packages/bierzo-wallet/src/routes/index.tsx @@ -7,6 +7,7 @@ import { AccountDelete, AccountManage, AccountRegister, AccountRenew, AccountUpd import AccountTransfer from "./account/transfer"; import Addresses from "./addresses"; import Balance from "./balance"; +import Iovnames from "./iovnames"; import Login from "./login"; import { ADDRESSES_ROUTE, @@ -14,6 +15,7 @@ import { IOVNAME_EDIT_ROUTE, IOVNAME_MANAGE_ROUTE, IOVNAME_REGISTER_ROUTE, + IOVNAME_ROUTE, IOVNAME_TRANSFER_ROUTE, LOGIN_ROUTE, NAME_DELETE_ROUTE, @@ -28,12 +30,14 @@ import { STARNAME_MANAGE_ROUTE, STARNAME_REGISTER_ROUTE, STARNAME_RENEW_ROUTE, + STARNAME_ROUTE, STARNAME_TRANSFER_ROUTE, TERMS_ROUTE, TRANSACTIONS_ROUTE, } from "./paths"; import Payment from "./payment"; import Policy from "./policy"; +import Starnames from "./starnames"; import Terms from "./terms"; import Transactions from "./transactions"; @@ -45,8 +49,15 @@ const Routes = (): JSX.Element => ( - + + + + + + + + } /> } /> @@ -64,15 +75,10 @@ const Routes = (): JSX.Element => ( } /> } /> - } /> - } /> - } /> - - - - + } /> + } /> diff --git a/packages/bierzo-wallet/src/routes/paths.ts b/packages/bierzo-wallet/src/routes/paths.ts index ee2475a65..1d8275492 100644 --- a/packages/bierzo-wallet/src/routes/paths.ts +++ b/packages/bierzo-wallet/src/routes/paths.ts @@ -1,13 +1,23 @@ -export const PAYMENT_ROUTE = "/payment"; export const LOGIN_ROUTE = "/login"; -export const TRANSACTIONS_ROUTE = "/transactions"; export const BALANCE_ROUTE = "/balance"; export const ADDRESSES_ROUTE = "/addresses"; +export const TRANSACTIONS_ROUTE = "/transactions"; +export const PAYMENT_ROUTE = "/payment"; +export const TERMS_ROUTE = "/terms"; +export const POLICY_ROUTE = "/policy"; // Account: Iovnames paths +export const IOVNAME_ROUTE = "/iovname"; export const IOVNAME_MANAGE_ROUTE = "/iovname/manage"; export const IOVNAME_EDIT_ROUTE = "/iovname/edit"; export const IOVNAME_REGISTER_ROUTE = "/iovname/register"; export const IOVNAME_TRANSFER_ROUTE = "/iovname/transfer"; +// Account: Starnames paths +export const STARNAME_ROUTE = "/starname"; +export const STARNAME_MANAGE_ROUTE = "/starname/manage"; +export const STARNAME_REGISTER_ROUTE = "/starname/register"; +export const STARNAME_TRANSFER_ROUTE = "/starname/transfer"; +export const STARNAME_DELETE_ROUTE = "/starname/delete"; +export const STARNAME_RENEW_ROUTE = "/starname/renew"; // Account: Names paths export const NAME_MANAGE_ROUTE = "/name/manage"; export const NAME_EDIT_ROUTE = "/name/edit"; @@ -15,12 +25,3 @@ export const NAME_REGISTER_ROUTE = "/name/register"; export const NAME_TRANSFER_ROUTE = "/name/transfer"; export const NAME_TRANSFER_BACK_ROUTE = "/name/transfer-back"; export const NAME_DELETE_ROUTE = "/name/delete"; -// Account: Starnames paths -export const STARNAME_MANAGE_ROUTE = "/starname/manage"; -export const STARNAME_REGISTER_ROUTE = "/starname/register"; -export const STARNAME_TRANSFER_ROUTE = "/starname/transfer"; -export const STARNAME_DELETE_ROUTE = "/starname/delete"; -export const STARNAME_RENEW_ROUTE = "/starname/renew"; - -export const TERMS_ROUTE = "/terms"; -export const POLICY_ROUTE = "/policy"; From 9fb76bf30186e05e788777d9b77a77ad8b67594e Mon Sep 17 00:00:00 2001 From: abefernan Date: Thu, 23 Apr 2020 13:16:55 +0200 Subject: [PATCH 2/9] Adds iovnames route code --- .../iovnames/components/IovnamesExists.tsx | 94 ++++++++++++++++ .../iovnames/components/IovnamesNotExists.tsx | 96 +++++++++++++++++ .../src/routes/iovnames/index.e2e.spec.ts | 102 ++++++++++++++++++ .../src/routes/iovnames/index.stories.tsx | 65 +++++++++++ .../src/routes/iovnames/index.tsx | 75 +++++++++++++ .../routes/iovnames/test/operateIovnames.ts | 28 +++++ 6 files changed, 460 insertions(+) create mode 100644 packages/bierzo-wallet/src/routes/iovnames/components/IovnamesExists.tsx create mode 100644 packages/bierzo-wallet/src/routes/iovnames/components/IovnamesNotExists.tsx create mode 100644 packages/bierzo-wallet/src/routes/iovnames/index.e2e.spec.ts create mode 100644 packages/bierzo-wallet/src/routes/iovnames/index.stories.tsx create mode 100644 packages/bierzo-wallet/src/routes/iovnames/index.tsx create mode 100644 packages/bierzo-wallet/src/routes/iovnames/test/operateIovnames.ts diff --git a/packages/bierzo-wallet/src/routes/iovnames/components/IovnamesExists.tsx b/packages/bierzo-wallet/src/routes/iovnames/components/IovnamesExists.tsx new file mode 100644 index 000000000..5c47481f2 --- /dev/null +++ b/packages/bierzo-wallet/src/routes/iovnames/components/IovnamesExists.tsx @@ -0,0 +1,94 @@ +import Paper from "@material-ui/core/Paper"; +import { Block, Image, makeStyles, Typography } from "medulas-react-components"; +import React from "react"; + +import { REGISTER_IOVNAME_LINK } from ".."; +import { history } from "../.."; +import iovnameLogo from "../../../assets/iovname-logo.svg"; +import { BwUsernameWithChainName } from "../../../components/AccountManage"; +import { IOVNAME_MANAGE_ROUTE } from "../../paths"; + +const usePaper = makeStyles({ + rounded: { + borderRadius: "5px", + height: "100%", + }, + elevation1: { + boxShadow: "none", + }, +}); + +interface Props { + readonly iovnames: readonly BwUsernameWithChainName[]; + readonly onRegisterIovname: () => void; +} + +function IovnamesExists({ iovnames, onRegisterIovname }: Props): JSX.Element { + const paperClasses = usePaper(); + + return ( + + + + + Iovname Logo + + + Register a new iovname + + + + Register now + + + + {iovnames + .slice() + .sort((a, b) => a.username.localeCompare(b.username, undefined, { sensitivity: "base" })) + .map(iovname => { + const onManage = (): void => { + history.push(IOVNAME_MANAGE_ROUTE, iovname); + }; + + return ( + + + + + + {iovname.username} + + + Manage + + + + + ); + })} + + ); +} + +export default IovnamesExists; diff --git a/packages/bierzo-wallet/src/routes/iovnames/components/IovnamesNotExists.tsx b/packages/bierzo-wallet/src/routes/iovnames/components/IovnamesNotExists.tsx new file mode 100644 index 000000000..80f808633 --- /dev/null +++ b/packages/bierzo-wallet/src/routes/iovnames/components/IovnamesNotExists.tsx @@ -0,0 +1,96 @@ +import { Theme } from "@material-ui/core"; +import { useTheme } from "@material-ui/styles"; +import { Block, Typography } from "medulas-react-components"; +import React from "react"; +import * as ReactRedux from "react-redux"; + +import { REGISTER_IOVNAME_LINK } from ".."; +import { getRpcEndpointType } from "../../../store/rpcendpoint/selectors"; +import { NoIovnameHeader } from "../../account/register/components/IovnameForm"; + +interface Props { + readonly onRegisterIovname: () => void; +} + +export function GetYourAddressWithExtension({ onRegisterIovname }: Props): JSX.Element { + return ( + + + + + You have no iovnames + + + With Neuma you can choose your easy to read human readable address. No more complicated cryptography + when sending to friends. + + + + Choose Now + + + ); +} + +export function GetYourAddressWithLedger(): JSX.Element { + return ( + + + + + You can not register + + + iovnames + + + + using{" "} + + + Ledger Nano S + + + + ); +} + +export function GetYourAddress({ onRegisterIovname }: Props): JSX.Element { + const rpcEndpointType = ReactRedux.useSelector(getRpcEndpointType); + + switch (rpcEndpointType) { + case "extension": + return ; + case "ledger": + return ; + } +} + +function StarnamesNotExists({ onRegisterIovname }: Props): JSX.Element { + const theme = useTheme(); + + return ( + + + + ); +} + +export default StarnamesNotExists; diff --git a/packages/bierzo-wallet/src/routes/iovnames/index.e2e.spec.ts b/packages/bierzo-wallet/src/routes/iovnames/index.e2e.spec.ts new file mode 100644 index 000000000..aeffd10bc --- /dev/null +++ b/packages/bierzo-wallet/src/routes/iovnames/index.e2e.spec.ts @@ -0,0 +1,102 @@ +import express, { Request, Response } from "express"; +import { Server } from "http"; +import { Browser, Page } from "puppeteer"; +import { sleep } from "ui-logic"; + +import { ACCOUNT_MANAGE_MENU_BUTTON, ACCOUNT_MANAGE_MENU_ITEM } from "../../components/AccountManage"; +import { ACCOUNT_OPERATION_SUBMIT_BUTTON } from "../../components/AccountOperation"; +import { ACCOUNT_TRANSFER_RECIPIENT } from "../../components/AccountTransfer"; +import { closeBrowser, createPage, getElements, launchBrowser } from "../../utils/test/e2e"; +import { acceptEnqueuedRequest } from "../../utils/test/persona"; +import { withChainsDescribe } from "../../utils/test/testExecutor"; +import { TRANSFER_CONFIRMATION_VIEW_ID } from "../account/transfer/components/ConfirmTransfer"; +import { registerIovname, waitForAllBalances } from "../balance/test/operateBalances"; +import { travelToBalanceE2E } from "../balance/test/travelToBalance"; +import { getIovnames, manageFirstIovnameE2E, travelToIovnamesTabE2E } from "./test/operateIovnames"; + +withChainsDescribe("E2E > Iovnames route", () => { + let browser: Browser; + let page: Page; + let server: Server; + let iovname: string; + + beforeAll(() => { + const app = express(); + + app.use(express.static(require("path").join(__dirname, "/../../../build"))); + + app.get("/*", function(_req: Request, res: Response) { + res.sendFile(require("path").join(__dirname, "build", "index.html")); + }); + + server = app.listen(9000); + }); + + beforeEach(async () => { + browser = await launchBrowser(); + page = await createPage(browser); + await travelToBalanceE2E(browser, page); + await waitForAllBalances(page); + + await travelToIovnamesTabE2E(page); + iovname = await registerIovname(browser, page); + await travelToIovnamesTabE2E(page); + }, 60000); + + afterEach(async () => { + await closeBrowser(browser); + }); + + afterAll(() => { + server.close(); + }); + + it("has a register iovname link and shows all registered iovnames", async () => { + const iovname2 = await registerIovname(browser, page); + await sleep(2000); + + await travelToIovnamesTabE2E(page); + + await sleep(2000); + const iovnames = await getIovnames(page); + const expected = [iovname, iovname2].sort((a, b) => + a.localeCompare(b, undefined, { sensitivity: "base" }), + ); + + expect(iovnames).toEqual(expected); + }, 60000); + + it('iovnames have "Manage" links that redirect to the Manage route for that iovname', async () => { + await manageFirstIovnameE2E(page); + await page.$x(`//h6[contains(., '${iovname}')]`); + }, 60000); + + it("iovnames can be transferred", async () => { + await manageFirstIovnameE2E(page); + + const [menuButton] = await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON); + await menuButton.click(); + const [transferLink] = await getElements(page, ACCOUNT_MANAGE_MENU_ITEM); + await transferLink.click(); + + const [recipientParent] = await getElements(page, ACCOUNT_TRANSFER_RECIPIENT); + const recipientField = await recipientParent.$("input"); + if (!recipientField) throw Error("Recipient field for transfer not found"); + await recipientField.type("test1*iov"); + + const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); + await submitButton.click(); + await sleep(2000); + + await acceptEnqueuedRequest(browser); + await sleep(2000); + await page.bringToFront(); + await page.waitForSelector(`#${TRANSFER_CONFIRMATION_VIEW_ID}`); + + await travelToIovnamesTabE2E(page); + + await sleep(2000); + const iovnameMatches = await page.$x(`//h5[contains(., '${iovname}')]`); + expect(iovnameMatches.length).toBe(0); + }, 60000); +}); diff --git a/packages/bierzo-wallet/src/routes/iovnames/index.stories.tsx b/packages/bierzo-wallet/src/routes/iovnames/index.stories.tsx new file mode 100644 index 000000000..b84293d4c --- /dev/null +++ b/packages/bierzo-wallet/src/routes/iovnames/index.stories.tsx @@ -0,0 +1,65 @@ +import { Address, ChainId } from "@iov/bcp"; +import { storiesOf } from "@storybook/react"; +import React from "react"; + +import { RpcEndpoint } from "../../communication/rpcEndpoint"; +import { BwUsernameWithChainName } from "../../components/AccountManage"; +import { ChainAddressPairWithName } from "../../components/AddressesTable"; +import DecoratedStorybook, { bierzoRoot } from "../../utils/storybook"; +import Iovnames from "."; + +const chainAddresses: ChainAddressPairWithName[] = [ + { + chainId: "local-iov-devnet" as ChainId, + address: "tiov1dcg3fat5zrvw00xezzjk3jgedm7pg70y222af3" as Address, + chainName: "IOV Devnet", + }, + { + chainId: "lisk-198f2b61a8" as ChainId, + address: "1349293588603668134L" as Address, + chainName: "Lisk Devnet", + }, + { + chainId: "ethereum-eip155-5777" as ChainId, + address: "0xD383382350F9f190Bd2608D6381B15b4e1cec0f3" as Address, + chainName: "Ganache", + }, +]; + +const rpcEndpoint: RpcEndpoint = { + authorizeGetIdentitiesMessage: "test authorizeGetIdentitiesMessage", + authorizeSignAndPostMessage: "test authorizeSignAndPostMessage", + noMatchingIdentityMessage: "test noMatchingIdentityMessage", + notAvailableMessage: "test notAvailableMessage", + sendGetIdentitiesRequest: _req => Promise.resolve(undefined), + sendSignAndPostRequest: _req => Promise.resolve(undefined), + type: "extension", +}; + +const iovnames: readonly BwUsernameWithChainName[] = [ + { + username: "test1*iov", + addresses: [chainAddresses[0]], + }, + { + username: "test2*iov", + addresses: [chainAddresses[0], chainAddresses[1]], + }, + { + username: "test3*iov", + addresses: [...chainAddresses], + }, +]; + +storiesOf(`${bierzoRoot}/Iovnames`, module) + .addParameters({ viewport: { defaultViewport: "responsive" } }) + .add("Without iovnames", () => ( + + + + )) + .add("With iovnames", () => ( + + + + )); diff --git a/packages/bierzo-wallet/src/routes/iovnames/index.tsx b/packages/bierzo-wallet/src/routes/iovnames/index.tsx new file mode 100644 index 000000000..ab4d1b15e --- /dev/null +++ b/packages/bierzo-wallet/src/routes/iovnames/index.tsx @@ -0,0 +1,75 @@ +import { Block } from "medulas-react-components"; +import React from "react"; +import * as ReactRedux from "react-redux"; + +import { history } from ".."; +import { BwUsernameWithChainName } from "../../components/AccountManage"; +import PageMenu from "../../components/PageMenu"; +import { getChainName } from "../../config"; +import { RootState } from "../../store/reducers"; +import { IOVNAME_REGISTER_ROUTE } from "../paths"; +import IovnamesExists from "./components/IovnamesExists"; +import IovnamesNotExists from "./components/IovnamesNotExists"; + +export const IOVNAMES_VIEW_ID = "iovnames-view-id"; +export const REGISTER_IOVNAME_LINK = IOVNAME_REGISTER_ROUTE.replace(/\//g, "-"); + +function onRegisterIovname(): void { + history.push(IOVNAME_REGISTER_ROUTE); +} + +function Iovnames(): JSX.Element { + const iovnames = ReactRedux.useSelector((state: RootState) => state.usernames); + const [iovnamesWithChain, setIovnamesWithChain] = React.useState([]); + + React.useEffect(() => { + let isSubscribed = true; + async function insertChainNames(): Promise { + if (isSubscribed) { + const bwUsernamesWithChain: BwUsernameWithChainName[] = await Promise.all( + iovnames.map(async name => { + return { + username: name.username, + addresses: await Promise.all( + name.addresses.map(async address => { + return { + chainId: address.chainId, + address: address.address, + chainName: await getChainName(address.chainId), + }; + }), + ), + }; + }), + ); + + setIovnamesWithChain(bwUsernamesWithChain); + } + } + insertChainNames(); + + return () => { + isSubscribed = false; + }; + }, [iovnames]); + + const hasIovnames = iovnamesWithChain.length > 0; + + return ( + + + {hasIovnames && } + {!hasIovnames && } + + + ); +} + +export default Iovnames; diff --git a/packages/bierzo-wallet/src/routes/iovnames/test/operateIovnames.ts b/packages/bierzo-wallet/src/routes/iovnames/test/operateIovnames.ts new file mode 100644 index 000000000..049c25071 --- /dev/null +++ b/packages/bierzo-wallet/src/routes/iovnames/test/operateIovnames.ts @@ -0,0 +1,28 @@ +import { Page } from "puppeteer"; + +import { IOVNAMES_VIEW_ID } from ".."; +import { manageIovnameId } from "../../../components/AccountManage"; +import { IOVNAMES_TAB_TITLE } from "../../../components/Header/components/LinksMenu"; + +export async function travelToIovnamesTabE2E(page: Page): Promise { + // const [addressesLink] = await page.$x(`//h6[contains(., '${IOVNAMES_TAB_TITLE}')]`); + const addressesLink = await page.waitForSelector(`#${IOVNAMES_TAB_TITLE}`); + await addressesLink.click(); + await page.waitForSelector(`#${IOVNAMES_VIEW_ID}`); +} + +export async function getIovnames(page: Page): Promise { + const iovnameEls = (await page.$$("h5")).slice(1); + const names: string[] = []; + for (const el of iovnameEls) { + names.push((await (await el.getProperty("textContent")).jsonValue()) as string); + } + + return names; +} + +export async function manageFirstIovnameE2E(page: Page): Promise { + const [firstStarnameEditLink] = await page.$x(`//h6[contains(., 'Manage')]`); + await firstStarnameEditLink.click(); + await page.waitForSelector(`#${manageIovnameId}`); +} From 9eac6e80c2e7e283a73803aaccb408f56d893f1b Mon Sep 17 00:00:00 2001 From: abefernan Date: Thu, 23 Apr 2020 13:17:05 +0200 Subject: [PATCH 3/9] Adds starnames route code --- .../starnames/components/StarnamesExists.tsx | 119 +++++++ .../components/StarnamesNotExists.tsx | 97 ++++++ .../src/routes/starnames/index.e2e.spec.ts | 313 ++++++++++++++++++ .../src/routes/starnames/index.stories.tsx | 76 +++++ .../src/routes/starnames/index.tsx | 77 +++++ .../routes/starnames/test/operateStarnames.ts | 43 +++ 6 files changed, 725 insertions(+) create mode 100644 packages/bierzo-wallet/src/routes/starnames/components/StarnamesExists.tsx create mode 100644 packages/bierzo-wallet/src/routes/starnames/components/StarnamesNotExists.tsx create mode 100644 packages/bierzo-wallet/src/routes/starnames/index.e2e.spec.ts create mode 100644 packages/bierzo-wallet/src/routes/starnames/index.stories.tsx create mode 100644 packages/bierzo-wallet/src/routes/starnames/index.tsx create mode 100644 packages/bierzo-wallet/src/routes/starnames/test/operateStarnames.ts diff --git a/packages/bierzo-wallet/src/routes/starnames/components/StarnamesExists.tsx b/packages/bierzo-wallet/src/routes/starnames/components/StarnamesExists.tsx new file mode 100644 index 000000000..aae6414a1 --- /dev/null +++ b/packages/bierzo-wallet/src/routes/starnames/components/StarnamesExists.tsx @@ -0,0 +1,119 @@ +import Paper from "@material-ui/core/Paper"; +import { Block, Image, makeStyles, Typography } from "medulas-react-components"; +import React from "react"; + +import { REGISTER_STARNAME_LINK } from ".."; +import { history } from "../.."; +import starnameLogo from "../../../assets/starname-logo.svg"; +import { BwAccountWithChainName } from "../../../components/AccountManage"; +import { NAME_MANAGE_ROUTE, STARNAME_MANAGE_ROUTE } from "../../paths"; + +export const STARNAMES_LIST_EXPIRY_DATE = "starnames-list-expiry-date"; + +const usePaper = makeStyles({ + rounded: { + borderRadius: "5px", + }, + elevation1: { + boxShadow: "none", + }, +}); + +interface Props { + readonly starnames: readonly BwAccountWithChainName[]; + readonly onRegisterStarname: () => void; +} + +function StarnamesExists({ starnames, onRegisterStarname }: Props): JSX.Element { + const paperClasses = usePaper(); + + return ( + + + + + Iovname Logo + + + Register a new starname + + + + Register now + + + + {starnames + .slice() + .sort((a, b) => + `${a.name}*${a.domain}`.localeCompare(`${b.name}*${b.domain}`, undefined, { sensitivity: "base" }), + ) + .map(starname => { + const onManage = (): void => { + if (starname.name) { + history.push(NAME_MANAGE_ROUTE, starname); + } else { + history.push(STARNAME_MANAGE_ROUTE, starname); + } + }; + + const now = new Date(); + const expiryLabel = now < starname.expiryDate ? "Expires on" : "Expired on"; + + return ( + + + + + + + {`${starname.name}*${starname.domain}`} + + {!starname.name && ( + + + + {`${expiryLabel} ${starname.expiryDate.toLocaleDateString()} ${starname.expiryDate.toLocaleTimeString()}`} + + + )} + + + Manage + + + + + ); + })} + + ); +} + +export default StarnamesExists; diff --git a/packages/bierzo-wallet/src/routes/starnames/components/StarnamesNotExists.tsx b/packages/bierzo-wallet/src/routes/starnames/components/StarnamesNotExists.tsx new file mode 100644 index 000000000..13ee63ec2 --- /dev/null +++ b/packages/bierzo-wallet/src/routes/starnames/components/StarnamesNotExists.tsx @@ -0,0 +1,97 @@ +import { Theme } from "@material-ui/core"; +import { useTheme } from "@material-ui/styles"; +import { Block, Typography } from "medulas-react-components"; +import React from "react"; +import * as ReactRedux from "react-redux"; + +import { REGISTER_STARNAME_LINK } from ".."; +import { getRpcEndpointType } from "../../../store/rpcendpoint/selectors"; +import { NoStarnameHeader } from "../../account/register/components/StarnameForm"; + +interface Props { + readonly onRegisterStarname: () => void; +} + +export function GetYourAddressWithExtension({ onRegisterStarname }: Props): JSX.Element { + return ( + + + + + Register your starname + + + A starname is your universal username for the blockchain world. It enables you to receive + crypto-currencies or to log in to blockchain applications in a seamless way. Transferring value + becomes fast an easy. + + + + Register Now + + + ); +} + +export function GetYourAddressWithLedger(): JSX.Element { + return ( + + + + + You can not register + + + starname + + + + using{" "} + + + Ledger Nano S + + + + ); +} + +export function GetYourAddress({ onRegisterStarname }: Props): JSX.Element { + const rpcEndpointType = ReactRedux.useSelector(getRpcEndpointType); + + switch (rpcEndpointType) { + case "extension": + return ; + case "ledger": + return ; + } +} + +function StarnamesNotExists({ onRegisterStarname }: Props): JSX.Element { + const theme = useTheme(); + + return ( + + + + ); +} + +export default StarnamesNotExists; diff --git a/packages/bierzo-wallet/src/routes/starnames/index.e2e.spec.ts b/packages/bierzo-wallet/src/routes/starnames/index.e2e.spec.ts new file mode 100644 index 000000000..65074a2fc --- /dev/null +++ b/packages/bierzo-wallet/src/routes/starnames/index.e2e.spec.ts @@ -0,0 +1,313 @@ +import express, { Request, Response } from "express"; +import { Server } from "http"; +import { Browser, Page } from "puppeteer"; +import { sleep } from "ui-logic"; + +import { ACCOUNT_MANAGE_MENU_BUTTON, ACCOUNT_MANAGE_MENU_ITEM } from "../../components/AccountManage"; +import { ACCOUNT_OPERATION_SUBMIT_BUTTON } from "../../components/AccountOperation"; +import { ACCOUNT_TRANSFER_RECIPIENT } from "../../components/AccountTransfer"; +import { closeBrowser, createPage, getElements, launchBrowser } from "../../utils/test/e2e"; +import { acceptEnqueuedRequest } from "../../utils/test/persona"; +import { withChainsDescribe } from "../../utils/test/testExecutor"; +import { DELETE_CONFIRMATION_VIEW_ID } from "../account/delete/components/ConfirmDelete"; +import { ACCOUNT_MANAGE_TOGGLE_SHOW_NAMES } from "../account/manage/components/AssociatedNamesList"; +import { RENEW_CONFIRMATION_VIEW_ID } from "../account/renew/components/ConfirmRenew"; +import { TRANSFER_CONFIRMATION_VIEW_ID } from "../account/transfer/components/ConfirmTransfer"; +import { registerName, registerStarname, waitForAllBalances } from "../balance/test/operateBalances"; +import { travelToBalanceE2E } from "../balance/test/travelToBalance"; +import { STARNAMES_LIST_EXPIRY_DATE } from "./components/StarnamesExists"; +import { + getStarnames, + manageFirstNameE2E, + manageFirstStarnameE2E, + parseExpiryDateLocaleEnUs, + travelToStarnamesTabE2E, +} from "./test/operateStarnames"; + +withChainsDescribe("E2E > Starnames route", () => { + let server: Server; + let browser: Browser; + let page: Page; + let starname: string; + + beforeAll(() => { + const app = express(); + + app.use(express.static(require("path").join(__dirname, "/../../../build"))); + + app.get("/*", function(_req: Request, res: Response) { + res.sendFile(require("path").join(__dirname, "build", "index.html")); + }); + + server = app.listen(9000); + }); + + beforeEach(async () => { + browser = await launchBrowser(); + page = await createPage(browser); + await travelToBalanceE2E(browser, page); + await waitForAllBalances(page); + + await travelToStarnamesTabE2E(page); + starname = await registerStarname(browser, page); + await sleep(2000); + await travelToStarnamesTabE2E(page); + await sleep(2000); + }, 60000); + + afterEach(async () => { + await closeBrowser(browser); + }); + + afterAll(() => { + server.close(); + }); + + it("has a register starname link and shows all registered starnames", async () => { + const starname2 = await registerStarname(browser, page); + await sleep(2000); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + const starnames = await getStarnames(page); + const expected = [starname, starname2].sort((a, b) => + a.localeCompare(b, undefined, { sensitivity: "base" }), + ); + + expect(starnames).toEqual(expected); + }, 60000); + + it("shows names besides starnames", async () => { + await manageFirstStarnameE2E(page); + await sleep(2000); + const name = await registerName(browser, page); + await sleep(2000); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + const starnamesAndNames = await getStarnames(page); + const expected = [starname, name].sort((a, b) => a.localeCompare(b, undefined, { sensitivity: "base" })); + + expect(starnamesAndNames).toEqual(expected); + }, 60000); + + it('starnames have "Manage" links that redirect to the Manage route for that starname', async () => { + await manageFirstStarnameE2E(page); + await page.$x(`//h6[contains(., '${starname}')]`); + }, 60000); + + it('names have "Manage" links that redirect to the Manage route for that name', async () => { + await manageFirstStarnameE2E(page); + await sleep(2000); + const name = await registerName(browser, page); + await sleep(2000); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + await manageFirstNameE2E(page); + await page.$x(`//h6[contains(., '${name}')]`); + }, 60000); + + it("starnames can be transferred", async () => { + await manageFirstStarnameE2E(page); + + const [menuButton] = await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON); + await menuButton.click(); + const transferLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[1]; + await transferLink.click(); + + const [recipientParent] = await getElements(page, ACCOUNT_TRANSFER_RECIPIENT); + const recipientField = await recipientParent.$("input"); + if (!recipientField) throw Error("Recipient field for transfer not found"); + await recipientField.type("test1*iov"); + + const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); + await submitButton.click(); + await sleep(2000); + + await acceptEnqueuedRequest(browser); + await sleep(2000); + await page.bringToFront(); + await page.waitForSelector(`#${TRANSFER_CONFIRMATION_VIEW_ID}`); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + const starnameMatches = await page.$x(`//h5[contains(., '${starname}')]`); + expect(starnameMatches.length).toBe(0); + }, 60000); + + it("starnames can be renewed", async () => { + const [expiryLabelElement] = await getElements(page, STARNAMES_LIST_EXPIRY_DATE); + const expiryLabelString = (await ( + await expiryLabelElement.getProperty("textContent") + ).jsonValue()) as string; + const expiryDate = parseExpiryDateLocaleEnUs(expiryLabelString); + + await manageFirstStarnameE2E(page); + + const [menuButton] = await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON); + await menuButton.click(); + const renewLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[0]; + await renewLink.click(); + + const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); + await submitButton.click(); + await sleep(2000); + + await acceptEnqueuedRequest(browser); + await sleep(2000); + await page.bringToFront(); + await page.waitForSelector(`#${RENEW_CONFIRMATION_VIEW_ID}`); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + const [newExpiryLabelElement] = await getElements(page, STARNAMES_LIST_EXPIRY_DATE); + const newExpiryLabelString = (await ( + await newExpiryLabelElement.getProperty("textContent") + ).jsonValue()) as string; + const newExpiryDate = parseExpiryDateLocaleEnUs(newExpiryLabelString); + + expect(newExpiryDate > expiryDate).toBeTruthy(); + }, 60000); + + it("starnames can be deleted and delete associated names", async () => { + await manageFirstStarnameE2E(page); + await sleep(2000); + await registerName(browser, page); + await sleep(2000); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + await manageFirstStarnameE2E(page); + + const [menuButton] = await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON); + await menuButton.click(); + const deleteLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[2]; + await deleteLink.click(); + + const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); + await submitButton.click(); + await sleep(2000); + + await acceptEnqueuedRequest(browser); + await sleep(2000); + await page.bringToFront(); + await page.waitForSelector(`#${DELETE_CONFIRMATION_VIEW_ID}`); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + const starnameMatches = await page.$x(`//h5[contains(., '${starname}')]`); + expect(starnameMatches.length).toBe(0); + }, 60000); + + it("names can be transferred and trasferred back", async () => { + // Transfer + await manageFirstStarnameE2E(page); + await sleep(2000); + const name = await registerName(browser, page); + await sleep(2000); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + await manageFirstStarnameE2E(page); + const [toggleShowName] = await getElements(page, ACCOUNT_MANAGE_TOGGLE_SHOW_NAMES); + await toggleShowName.click(); + await sleep(2000); + + const menuButton = (await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON))[1]; + await menuButton.click(); + const transferLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[3]; + await transferLink.click(); + await sleep(2000); + + const [recipientParent] = await getElements(page, ACCOUNT_TRANSFER_RECIPIENT); + const recipientField = await recipientParent.$("input"); + if (!recipientField) throw Error("Recipient field for transfer not found"); + await recipientField.type("test1*iov"); + + const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); + await submitButton.click(); + await sleep(2000); + + await acceptEnqueuedRequest(browser); + await sleep(2000); + await page.bringToFront(); + await page.waitForSelector(`#${TRANSFER_CONFIRMATION_VIEW_ID}`); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + const nameMatches = await page.$x(`//h5[contains(., '${name}')]`); + expect(nameMatches.length).toBe(0); + + // Transfer back + + await manageFirstStarnameE2E(page); + const [toggleShowName2] = await getElements(page, ACCOUNT_MANAGE_TOGGLE_SHOW_NAMES); + await toggleShowName2.click(); + await sleep(2000); + + const menuButton2 = (await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON))[1]; + await menuButton2.click(); + const transferBackLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[4]; + await transferBackLink.click(); + + const [submitButton2] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); + await submitButton2.click(); + await sleep(2000); + + await acceptEnqueuedRequest(browser); + await sleep(2000); + await page.bringToFront(); + await page.waitForSelector(`#${TRANSFER_CONFIRMATION_VIEW_ID}`); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + const nameMatches2 = await page.$x(`//h5[contains(., '${name}')]`); + expect(nameMatches2.length).toBe(1); + }, 60000); + + it("names can be deleted", async () => { + await manageFirstStarnameE2E(page); + await sleep(2000); + const name = await registerName(browser, page); + await sleep(2000); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + await manageFirstStarnameE2E(page); + const [toggleShowName] = await getElements(page, ACCOUNT_MANAGE_TOGGLE_SHOW_NAMES); + await toggleShowName.click(); + await sleep(2000); + + const menuButton = (await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON))[1]; + await menuButton.click(); + const deleteLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[5]; + await deleteLink.click(); + + const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); + await submitButton.click(); + await sleep(2000); + + await acceptEnqueuedRequest(browser); + await sleep(2000); + await page.bringToFront(); + await page.waitForSelector(`#${DELETE_CONFIRMATION_VIEW_ID}`); + + await travelToStarnamesTabE2E(page); + + await sleep(2000); + const nameMatches = await page.$x(`//h5[contains(., '${name}')]`); + expect(nameMatches.length).toBe(0); + }, 60000); +}); diff --git a/packages/bierzo-wallet/src/routes/starnames/index.stories.tsx b/packages/bierzo-wallet/src/routes/starnames/index.stories.tsx new file mode 100644 index 000000000..8c8fd21bf --- /dev/null +++ b/packages/bierzo-wallet/src/routes/starnames/index.stories.tsx @@ -0,0 +1,76 @@ +import { Address, ChainId } from "@iov/bcp"; +import { storiesOf } from "@storybook/react"; +import React from "react"; + +import { RpcEndpoint } from "../../communication/rpcEndpoint"; +import { ChainAddressPairWithName } from "../../components/AddressesTable"; +import { BwAccount } from "../../store/accounts"; +import DecoratedStorybook, { bierzoRoot } from "../../utils/storybook"; +import Starnames from "."; + +const defaultExpiryDate = new Date("June 5, 2120 03:00:00"); + +const chainAddresses: ChainAddressPairWithName[] = [ + { + chainId: "local-iov-devnet" as ChainId, + address: "tiov1dcg3fat5zrvw00xezzjk3jgedm7pg70y222af3" as Address, + chainName: "IOV Devnet", + }, + { + chainId: "lisk-198f2b61a8" as ChainId, + address: "1349293588603668134L" as Address, + chainName: "Lisk Devnet", + }, + { + chainId: "ethereum-eip155-5777" as ChainId, + address: "0xD383382350F9f190Bd2608D6381B15b4e1cec0f3" as Address, + chainName: "Ganache", + }, +]; + +const rpcEndpoint: RpcEndpoint = { + authorizeGetIdentitiesMessage: "test authorizeGetIdentitiesMessage", + authorizeSignAndPostMessage: "test authorizeSignAndPostMessage", + noMatchingIdentityMessage: "test noMatchingIdentityMessage", + notAvailableMessage: "test notAvailableMessage", + sendGetIdentitiesRequest: _req => Promise.resolve(undefined), + sendSignAndPostRequest: _req => Promise.resolve(undefined), + type: "extension", +}; + +const starnames: readonly BwAccount[] = [ + { + domain: "domain1", + name: "name1", + expiryDate: defaultExpiryDate, + addresses: [chainAddresses[0]], + owner: "tiov1dcg3fat5zrvw00xezzjk3jgedm7pg70y222af3" as Address, + }, + { + domain: "domain2", + name: "name2", + expiryDate: defaultExpiryDate, + addresses: [chainAddresses[0]], + owner: "tiov1dcg3fat5zrvw00xezzjk3jgedm7pg70y222af3" as Address, + }, + { + domain: "domain1", + name: "name2", + expiryDate: defaultExpiryDate, + addresses: [chainAddresses[0]], + owner: "tiov1dcg3fat5zrvw00xezzjk3jgedm7pg70y222af3" as Address, + }, +]; + +storiesOf(`${bierzoRoot}/Starnames`, module) + .addParameters({ viewport: { defaultViewport: "responsive" } }) + .add("Without starnames", () => ( + + + + )) + .add("With starnames", () => ( + + + + )); diff --git a/packages/bierzo-wallet/src/routes/starnames/index.tsx b/packages/bierzo-wallet/src/routes/starnames/index.tsx new file mode 100644 index 000000000..98905cda7 --- /dev/null +++ b/packages/bierzo-wallet/src/routes/starnames/index.tsx @@ -0,0 +1,77 @@ +import { Block } from "medulas-react-components"; +import React from "react"; +import * as ReactRedux from "react-redux"; + +import { history } from ".."; +import { BwAccountWithChainName } from "../../components/AccountManage"; +import PageMenu from "../../components/PageMenu"; +import { getChainName } from "../../config"; +import { RootState } from "../../store/reducers"; +import { STARNAME_REGISTER_ROUTE } from "../paths"; +import StarnamesExists from "./components/StarnamesExists"; +import StarnamesNotExists from "./components/StarnamesNotExists"; + +export const STARNAMES_VIEW_ID = "starnames-view-id"; +export const REGISTER_STARNAME_LINK = STARNAME_REGISTER_ROUTE.replace(/\//g, "-"); + +function onRegisterStarname(): void { + history.push(STARNAME_REGISTER_ROUTE); +} + +function Starnames(): JSX.Element { + const starnames = ReactRedux.useSelector((state: RootState) => state.accounts); + const [starnamesWithChain, setStarnamesWithChain] = React.useState([]); + + React.useEffect(() => { + let isSubscribed = true; + async function insertChainNames(): Promise { + if (isSubscribed) { + const bwAccountsWithChain: BwAccountWithChainName[] = await Promise.all( + starnames.map(async name => { + return { + ...name, + addresses: await Promise.all( + name.addresses.map(async address => { + return { + chainId: address.chainId, + address: address.address, + chainName: await getChainName(address.chainId), + }; + }), + ), + }; + }), + ); + + setStarnamesWithChain(bwAccountsWithChain); + } + } + insertChainNames(); + + return () => { + isSubscribed = false; + }; + }, [starnames]); + + const hasStarnames = starnamesWithChain.length > 0; + + return ( + + + {hasStarnames && ( + + )} + {!hasStarnames && } + + + ); +} + +export default Starnames; diff --git a/packages/bierzo-wallet/src/routes/starnames/test/operateStarnames.ts b/packages/bierzo-wallet/src/routes/starnames/test/operateStarnames.ts new file mode 100644 index 000000000..05f2a56bc --- /dev/null +++ b/packages/bierzo-wallet/src/routes/starnames/test/operateStarnames.ts @@ -0,0 +1,43 @@ +import { Page } from "puppeteer"; + +import { STARNAMES_VIEW_ID } from ".."; +import { manageStarnameId } from "../../../components/AccountManage"; +import { STARNAMES_TAB_TITLE } from "../../../components/Header/components/LinksMenu"; + +export async function travelToStarnamesTabE2E(page: Page): Promise { + const [addressesLink] = await page.$x(`//h6[contains(., '${STARNAMES_TAB_TITLE}')]`); + await addressesLink.click(); + await page.waitForSelector(`#${STARNAMES_VIEW_ID}`); +} + +export async function getStarnames(page: Page): Promise { + const starnameEls = (await page.$$("h5")).slice(1); + const names: string[] = []; + for (const el of starnameEls) { + names.push((await (await el.getProperty("textContent")).jsonValue()) as string); + } + + return names; +} + +export async function manageFirstStarnameE2E(page: Page): Promise { + const [firstStarnameEditLink] = await page.$x(`//h6[contains(., 'Manage')]`); + await firstStarnameEditLink.click(); + await page.waitForSelector(`#${manageStarnameId}`); + expect(page.url().endsWith("/starname/manage")).toBe(true); +} + +export async function manageFirstNameE2E(page: Page): Promise { + const firstNameEditLink = (await page.$x(`//h6[contains(., 'Manage')]`))[1]; + await firstNameEditLink.click(); + await page.waitForSelector(`#${manageStarnameId}`); + expect(page.url().endsWith("/name/manage")).toBe(true); +} + +// Expects an expirty date label with the format: Expires on 4/15/2020 8:43:10 AM +export function parseExpiryDateLocaleEnUs(expiryLabel: string): Date { + const [, , dateString, ...timeArray] = expiryLabel.split(" "); + const timeString = timeArray.join(" "); + + return new Date(`${dateString} ${timeString}`); +} From 4333c2ee17d72cba71fb143fd03cf1b2f955dcb0 Mon Sep 17 00:00:00 2001 From: abefernan Date: Thu, 23 Apr 2020 13:17:33 +0200 Subject: [PATCH 4/9] Removes names code from Addresses tab --- .../addresses/components/AddressesTab.tsx | 103 ----- .../routes/addresses/components/Iovnames.tsx | 33 -- .../addresses/components/IovnamesExists.tsx | 94 ---- .../components/IovnamesNotExists.tsx | 96 ---- .../routes/addresses/components/Starnames.tsx | 33 -- .../addresses/components/StarnamesExists.tsx | 119 ----- .../components/StarnamesNotExists.tsx | 100 ----- .../src/routes/addresses/index.e2e.spec.ts | 415 +----------------- .../src/routes/addresses/index.stories.tsx | 116 ----- .../src/routes/addresses/index.tsx | 101 +---- .../routes/addresses/test/operateAddresses.ts | 39 ++ .../addresses/test/operateReceivePayment.ts | 92 ---- .../addresses/test/travelToReceivePayment.ts | 54 --- 13 files changed, 72 insertions(+), 1323 deletions(-) delete mode 100644 packages/bierzo-wallet/src/routes/addresses/components/AddressesTab.tsx delete mode 100644 packages/bierzo-wallet/src/routes/addresses/components/Iovnames.tsx delete mode 100644 packages/bierzo-wallet/src/routes/addresses/components/IovnamesExists.tsx delete mode 100644 packages/bierzo-wallet/src/routes/addresses/components/IovnamesNotExists.tsx delete mode 100644 packages/bierzo-wallet/src/routes/addresses/components/Starnames.tsx delete mode 100644 packages/bierzo-wallet/src/routes/addresses/components/StarnamesExists.tsx delete mode 100644 packages/bierzo-wallet/src/routes/addresses/components/StarnamesNotExists.tsx create mode 100644 packages/bierzo-wallet/src/routes/addresses/test/operateAddresses.ts delete mode 100644 packages/bierzo-wallet/src/routes/addresses/test/operateReceivePayment.ts delete mode 100644 packages/bierzo-wallet/src/routes/addresses/test/travelToReceivePayment.ts diff --git a/packages/bierzo-wallet/src/routes/addresses/components/AddressesTab.tsx b/packages/bierzo-wallet/src/routes/addresses/components/AddressesTab.tsx deleted file mode 100644 index 9224c0be1..000000000 --- a/packages/bierzo-wallet/src/routes/addresses/components/AddressesTab.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import { makeStyles, Theme } from "@material-ui/core"; -import classNames from "classnames"; -import { Block, Typography } from "medulas-react-components"; -import React from "react"; - -import { AddressesTableProps } from "../../../components/AddressesTable"; -import Iovnames, { IovnamesProps } from "./Iovnames"; -import Starnames, { StarnamesProps } from "./Starnames"; -import UserAddresses from "./UserAddresses"; - -export const yourStarnames = "Your starnames"; -export const yourIovnames = "Your iovnames"; -export const yourAddresses = "Your blockchain addresses"; - -const useStyles = makeStyles((theme: Theme) => ({ - item: { - margin: `0px ${theme.spacing(4)}px`, - "&:hover": { - cursor: "pointer", - }, - }, - activated: { - "& $line": { - visibility: "visible", - }, - }, - line: { - visibility: "hidden", - height: "4px", - backgroundColor: theme.palette.primary.main, - borderRadius: "4px", - marginTop: "4px", - }, -})); - -interface TabItemProps { - readonly children: string; - readonly selected: boolean; - readonly onChangeTab: () => void; -} -function TabItem({ children, selected, onChangeTab }: TabItemProps): JSX.Element { - const classes = useStyles(); - const balanceClasses = classNames(classes.item, { [classes.activated]: selected }); - - return ( - - - - {children} - - - - - ); -} - -function AddressesTab({ - chainAddresses, - iovnames, - starnames, - onRegisterIovname, - onRegisterStarname, - rpcEndpointType, -}: AddressesTableProps & IovnamesProps & StarnamesProps): JSX.Element { - const [selectedTab, setSelectedTab] = React.useState<"starnames" | "iovnames" | "addresses">("starnames"); - - const changeTabToStarnames = (): void => setSelectedTab("starnames"); - const changeTabToIovnames = (): void => setSelectedTab("iovnames"); - const changeTabToAddresses = (): void => setSelectedTab("addresses"); - - return ( - - - - {yourStarnames} - - - {yourIovnames} - - - {yourAddresses} - - - {selectedTab === "starnames" && ( - - )} - {selectedTab === "iovnames" && ( - - )} - {selectedTab === "addresses" && } - - ); -} - -export default AddressesTab; diff --git a/packages/bierzo-wallet/src/routes/addresses/components/Iovnames.tsx b/packages/bierzo-wallet/src/routes/addresses/components/Iovnames.tsx deleted file mode 100644 index c996e111b..000000000 --- a/packages/bierzo-wallet/src/routes/addresses/components/Iovnames.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Block } from "medulas-react-components"; -import React from "react"; - -import { RpcEndpointType } from "../../../communication/rpcEndpoint"; -import { BwUsername } from "../../../store/usernames"; -import { IOVNAME_REGISTER_ROUTE } from "../../paths"; -import IovnamesExists from "./IovnamesExists"; -import IovnamesNotExists from "./IovnamesNotExists"; - -export const iovnamesViewId = "iovnames-view-id"; -export const registerIovnameId = IOVNAME_REGISTER_ROUTE.replace(/\//g, "-"); - -export interface IovnamesProps { - readonly iovnames: readonly BwUsername[]; - readonly onRegisterIovname: () => void; - readonly rpcEndpointType: RpcEndpointType; -} - -const Iovnames = ({ iovnames, rpcEndpointType, onRegisterIovname }: IovnamesProps): JSX.Element => { - const hasIovnames = iovnames.length > 0; - - return ( - - - {!hasIovnames && ( - - )} - {hasIovnames && } - - ); -}; - -export default Iovnames; diff --git a/packages/bierzo-wallet/src/routes/addresses/components/IovnamesExists.tsx b/packages/bierzo-wallet/src/routes/addresses/components/IovnamesExists.tsx deleted file mode 100644 index 4b94da527..000000000 --- a/packages/bierzo-wallet/src/routes/addresses/components/IovnamesExists.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import Paper from "@material-ui/core/Paper"; -import { Block, Image, makeStyles, Typography } from "medulas-react-components"; -import React from "react"; - -import { history } from "../.."; -import iovnameLogo from "../../../assets/iovname-logo.svg"; -import { BwUsername } from "../../../store/usernames"; -import { IOVNAME_MANAGE_ROUTE } from "../../paths"; -import { registerIovnameId } from "./Iovnames"; - -interface Props { - readonly iovnames: readonly BwUsername[]; - readonly onRegisterIovname: () => void; -} - -const usePaper = makeStyles({ - rounded: { - borderRadius: "5px", - height: "100%", - }, - elevation1: { - boxShadow: "none", - }, -}); - -function IovnamesExists({ iovnames, onRegisterIovname }: Props): JSX.Element { - const paperClasses = usePaper(); - - return ( - - - - - Iovname Logo - - - Register a new iovname - - - - Register now - - - - {iovnames - .slice() - .sort((a, b) => a.username.localeCompare(b.username, undefined, { sensitivity: "base" })) - .map(iovname => { - const onManage = (): void => { - history.push(IOVNAME_MANAGE_ROUTE, iovname); - }; - - return ( - - - - - - {iovname.username} - - - Manage - - - - - ); - })} - - ); -} - -export default IovnamesExists; diff --git a/packages/bierzo-wallet/src/routes/addresses/components/IovnamesNotExists.tsx b/packages/bierzo-wallet/src/routes/addresses/components/IovnamesNotExists.tsx deleted file mode 100644 index daea38fd1..000000000 --- a/packages/bierzo-wallet/src/routes/addresses/components/IovnamesNotExists.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Theme } from "@material-ui/core"; -import { useTheme } from "@material-ui/styles"; -import { Block, Typography } from "medulas-react-components"; -import React from "react"; - -import { RpcEndpointType } from "../../../communication/rpcEndpoint"; -import { NoIovnameHeader } from "../../account/register/components/IovnameForm"; -import { registerIovnameId } from "./Iovnames"; - -interface StarnamesNotExistsProps { - readonly onRegisterIovname: () => void; - readonly rpcEndpointType: RpcEndpointType; -} - -export function GetYourAddressWithExtension({ - onRegisterIovname, -}: Omit): JSX.Element { - return ( - - - - - You have no iovnames - - - With Neuma you can choose your easy to read human readable address. No more complicated cryptography - when sending to friends. - - - - Choose Now - - - ); -} - -export function GetYourAddressWithLedger(): JSX.Element { - return ( - - - - - You can not register - - - iovnames - - - - using{" "} - - - Ledger Nano S - - - - ); -} - -export function GetYourAddress({ rpcEndpointType, onRegisterIovname }: StarnamesNotExistsProps): JSX.Element { - switch (rpcEndpointType) { - case "extension": - return ; - case "ledger": - return ; - } -} - -function StarnamesNotExists({ onRegisterIovname, rpcEndpointType }: StarnamesNotExistsProps): JSX.Element { - const theme = useTheme(); - - return ( - - - - ); -} - -export default StarnamesNotExists; diff --git a/packages/bierzo-wallet/src/routes/addresses/components/Starnames.tsx b/packages/bierzo-wallet/src/routes/addresses/components/Starnames.tsx deleted file mode 100644 index de81522e3..000000000 --- a/packages/bierzo-wallet/src/routes/addresses/components/Starnames.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Block } from "medulas-react-components"; -import React from "react"; - -import { RpcEndpointType } from "../../../communication/rpcEndpoint"; -import { BwAccount } from "../../../store/accounts"; -import { STARNAME_REGISTER_ROUTE } from "../../paths"; -import StarnamesExists from "./StarnamesExists"; -import StarnamesNotExists from "./StarnamesNotExists"; - -export const starnamesViewId = "starnames-view-id"; -export const registerStarnameId = STARNAME_REGISTER_ROUTE.replace(/\//g, "-"); - -export interface StarnamesProps { - readonly starnames: readonly BwAccount[]; - readonly onRegisterStarname: () => void; - readonly rpcEndpointType: RpcEndpointType; -} - -const Starnames = ({ starnames, rpcEndpointType, onRegisterStarname }: StarnamesProps): JSX.Element => { - const hasStarnames = starnames.length > 0; - - return ( - - - {!hasStarnames && ( - - )} - {hasStarnames && } - - ); -}; - -export default Starnames; diff --git a/packages/bierzo-wallet/src/routes/addresses/components/StarnamesExists.tsx b/packages/bierzo-wallet/src/routes/addresses/components/StarnamesExists.tsx deleted file mode 100644 index 05cca84dd..000000000 --- a/packages/bierzo-wallet/src/routes/addresses/components/StarnamesExists.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import Paper from "@material-ui/core/Paper"; -import { Block, Image, makeStyles, Typography } from "medulas-react-components"; -import React from "react"; - -import { history } from "../.."; -import starnameLogo from "../../../assets/starname-logo.svg"; -import { BwAccount } from "../../../store/accounts"; -import { NAME_MANAGE_ROUTE, STARNAME_MANAGE_ROUTE } from "../../paths"; -import { registerStarnameId } from "./Starnames"; - -export const STARNAMES_LIST_EXPIRY_DATE = "starnames-list-expiry-date"; - -interface Props { - readonly starnames: readonly BwAccount[]; - readonly onRegisterStarname: () => void; -} - -const usePaper = makeStyles({ - rounded: { - borderRadius: "5px", - }, - elevation1: { - boxShadow: "none", - }, -}); - -function StarnamesExists({ starnames, onRegisterStarname }: Props): JSX.Element { - const paperClasses = usePaper(); - - return ( - - - - - Iovname Logo - - - Register a new starname - - - - Register now - - - - {starnames - .slice() - .sort((a, b) => - `${a.name}*${a.domain}`.localeCompare(`${b.name}*${b.domain}`, undefined, { sensitivity: "base" }), - ) - .map(starname => { - const onManage = (): void => { - if (starname.name) { - history.push(NAME_MANAGE_ROUTE, starname); - } else { - history.push(STARNAME_MANAGE_ROUTE, starname); - } - }; - - const now = new Date(); - const expiryLabel = now < starname.expiryDate ? "Expires on" : "Expired on"; - - return ( - - - - - - - {`${starname.name}*${starname.domain}`} - - {!starname.name && ( - - - - {`${expiryLabel} ${starname.expiryDate.toLocaleDateString()} ${starname.expiryDate.toLocaleTimeString()}`} - - - )} - - - Manage - - - - - ); - })} - - ); -} - -export default StarnamesExists; diff --git a/packages/bierzo-wallet/src/routes/addresses/components/StarnamesNotExists.tsx b/packages/bierzo-wallet/src/routes/addresses/components/StarnamesNotExists.tsx deleted file mode 100644 index 022b90abc..000000000 --- a/packages/bierzo-wallet/src/routes/addresses/components/StarnamesNotExists.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { Theme } from "@material-ui/core"; -import { useTheme } from "@material-ui/styles"; -import { Block, Typography } from "medulas-react-components"; -import React from "react"; - -import { RpcEndpointType } from "../../../communication/rpcEndpoint"; -import { NoStarnameHeader } from "../../account/register/components/StarnameForm"; -import { registerStarnameId } from "./Starnames"; - -interface StarnamesNotExistsProps { - readonly onRegisterStarname: () => void; - readonly rpcEndpointType: RpcEndpointType; -} - -export function GetYourAddressWithExtension({ - onRegisterStarname, -}: Omit): JSX.Element { - return ( - - - - - Register your starname - - - A starname is your universal username for the blockchain world. It enables you to receive - crypto-currencies or to log in to blockchain applications in a seamless way. Transferring value - becomes fast an easy. - - - - Register Now - - - ); -} - -export function GetYourAddressWithLedger(): JSX.Element { - return ( - - - - - You can not register - - - starname - - - - using{" "} - - - Ledger Nano S - - - - ); -} - -export function GetYourAddress({ - rpcEndpointType, - onRegisterStarname, -}: StarnamesNotExistsProps): JSX.Element { - switch (rpcEndpointType) { - case "extension": - return ; - case "ledger": - return ; - } -} - -function StarnamesNotExists({ onRegisterStarname, rpcEndpointType }: StarnamesNotExistsProps): JSX.Element { - const theme = useTheme(); - - return ( - - - - ); -} - -export default StarnamesNotExists; diff --git a/packages/bierzo-wallet/src/routes/addresses/index.e2e.spec.ts b/packages/bierzo-wallet/src/routes/addresses/index.e2e.spec.ts index a39997820..8096e56c0 100644 --- a/packages/bierzo-wallet/src/routes/addresses/index.e2e.spec.ts +++ b/packages/bierzo-wallet/src/routes/addresses/index.e2e.spec.ts @@ -2,49 +2,12 @@ import clipboardy from "clipboardy"; import express, { Request, Response } from "express"; import { Server } from "http"; import { Browser, Page } from "puppeteer"; -import { sleep } from "ui-logic"; -import { ACCOUNT_MANAGE_MENU_BUTTON, ACCOUNT_MANAGE_MENU_ITEM } from "../../components/AccountManage"; -import { ACCOUNT_OPERATION_SUBMIT_BUTTON } from "../../components/AccountOperation"; -import { ACCOUNT_TRANSFER_RECIPIENT } from "../../components/AccountTransfer"; -import { - closeBrowser, - closeToast, - createPage, - getElements, - getToastMessage, - launchBrowser, -} from "../../utils/test/e2e"; -import { acceptEnqueuedRequest } from "../../utils/test/persona"; +import { closeBrowser, closeToast, createPage, getToastMessage, launchBrowser } from "../../utils/test/e2e"; import { withChainsDescribe } from "../../utils/test/testExecutor"; -import { DELETE_CONFIRMATION_VIEW_ID } from "../account/delete/components/ConfirmDelete"; -import { ACCOUNT_MANAGE_TOGGLE_SHOW_NAMES } from "../account/manage/components/AssociatedNamesList"; -import { RENEW_CONFIRMATION_VIEW_ID } from "../account/renew/components/ConfirmRenew"; -import { TRANSFER_CONFIRMATION_VIEW_ID } from "../account/transfer/components/ConfirmTransfer"; -import { - registerIovname, - registerName, - registerStarname, - waitForAllBalances, -} from "../balance/test/operateBalances"; +import { waitForAllBalances } from "../balance/test/operateBalances"; import { travelToBalanceE2E } from "../balance/test/travelToBalance"; -import { STARNAMES_LIST_EXPIRY_DATE } from "./components/StarnamesExists"; -import { - copyAddress, - getAddressRow, - getIovnames, - getStarnames, - parseExpiryDateLocaleEnUs, -} from "./test/operateReceivePayment"; -import { - manageFirstIovnameE2E, - manageFirstNameE2E, - manageFirstStarnameE2E, - travelToAddressesE2E, - travelToBlockchainAddressesTabE2E, - travelToIovnamesTabE2E, - travelToStarnamesTabE2E, -} from "./test/travelToReceivePayment"; +import { copyAddress, getAddressRow, travelToAddressesE2E } from "./test/operateAddresses"; withChainsDescribe("E2E > Addresses route", () => { let browser: Browser; @@ -56,7 +19,7 @@ withChainsDescribe("E2E > Addresses route", () => { app.use(express.static(require("path").join(__dirname, "/../../../build"))); - app.get("/*", function(req: Request, res: Response) { + app.get("/*", function(_req: Request, res: Response) { res.sendFile(require("path").join(__dirname, "build", "index.html")); }); @@ -79,363 +42,25 @@ withChainsDescribe("E2E > Addresses route", () => { server.close(); }); - describe("Blockchain addresses tab", () => { - beforeEach(async () => { - await travelToBlockchainAddressesTabE2E(page); - }, 60000); + it("allows copying addresses to clipboard by clicking icon", async () => { + let [chainName, address] = await getAddressRow(page, 1); + expect(chainName).toBe("Ganache"); + expect(address).toMatch(/^0x[a-fA-F0-9]{40}$/); - it("allows copying addresses to clipboard by clicking icon", async () => { - let [chainName, address] = await getAddressRow(page, 1); - expect(chainName).toBe("Ganache"); - expect(address).toMatch(/^0x[a-fA-F0-9]{40}$/); + [chainName, address] = await getAddressRow(page, 2); + expect(chainName).toBe("IOV Devnet"); + expect(address).toMatch(/^tiov1[0-9a-z]{38}$/); - [chainName, address] = await getAddressRow(page, 2); - expect(chainName).toBe("IOV Devnet"); - expect(address).toMatch(/^tiov1[0-9a-z]{38}$/); + [chainName, address] = await getAddressRow(page, 3); + expect(chainName).toBe("Lisk Devnet"); + expect(address).toMatch(/^[0-9]+L$/); - [chainName, address] = await getAddressRow(page, 3); - expect(chainName).toBe("Lisk Devnet"); - expect(address).toMatch(/^[0-9]+L$/); + const blockchainAddress = await copyAddress(page, 1); - const blockchainAddress = await copyAddress(page, 1); + expect(clipboardy.readSync()).toBe(blockchainAddress); - expect(clipboardy.readSync()).toBe(blockchainAddress); - - const toastMessage = await getToastMessage(page); - expect(toastMessage).toBe("Address has been copied to clipboard."); - await closeToast(page); - }, 60000); - }); - - describe("Iovnames tab", () => { - let iovname: string; - - beforeEach(async () => { - await travelToIovnamesTabE2E(page); - iovname = await registerIovname(browser, page); - - await travelToAddressesE2E(page); - await travelToIovnamesTabE2E(page); - }, 60000); - - it("has a register iovname link and shows all registered iovnames", async () => { - const iovname2 = await registerIovname(browser, page); - await sleep(2000); - - await travelToAddressesE2E(page); - await travelToIovnamesTabE2E(page); - - await sleep(2000); - const iovnames = await getIovnames(page); - const expected = [iovname, iovname2].sort((a, b) => - a.localeCompare(b, undefined, { sensitivity: "base" }), - ); - - expect(iovnames).toEqual(expected); - }, 60000); - - it('iovnames have "Manage" links that redirect to the Manage route for that iovname', async () => { - await manageFirstIovnameE2E(page); - await page.$x(`//h6[contains(., '${iovname}')]`); - }, 60000); - - it("iovnames can be transferred", async () => { - await manageFirstIovnameE2E(page); - - const [menuButton] = await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON); - await menuButton.click(); - const [transferLink] = await getElements(page, ACCOUNT_MANAGE_MENU_ITEM); - await transferLink.click(); - - const [recipientParent] = await getElements(page, ACCOUNT_TRANSFER_RECIPIENT); - const recipientField = await recipientParent.$("input"); - if (!recipientField) throw Error("Recipient field for transfer not found"); - await recipientField.type("test1*iov"); - - const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); - await submitButton.click(); - await sleep(2000); - - await acceptEnqueuedRequest(browser); - await sleep(2000); - await page.bringToFront(); - await page.waitForSelector(`#${TRANSFER_CONFIRMATION_VIEW_ID}`); - - await travelToAddressesE2E(page); - await travelToIovnamesTabE2E(page); - - await sleep(2000); - const iovnameMatches = await page.$x(`//h5[contains(., '${iovname}')]`); - expect(iovnameMatches.length).toBe(0); - }, 60000); - }); - - describe("Starnames tab", () => { - let starname: string; - - beforeEach(async () => { - await travelToStarnamesTabE2E(page); - starname = await registerStarname(browser, page); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - }, 60000); - - it("has a register starname link and shows all registered starnames", async () => { - const starname2 = await registerStarname(browser, page); - await sleep(2000); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - const starnames = await getStarnames(page); - const expected = [starname, starname2].sort((a, b) => - a.localeCompare(b, undefined, { sensitivity: "base" }), - ); - - expect(starnames).toEqual(expected); - }, 60000); - - it("shows names besides starnames", async () => { - await manageFirstStarnameE2E(page); - const name = await registerName(browser, page); - await sleep(2000); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - const starnamesAndNames = await getStarnames(page); - const expected = [starname, name].sort((a, b) => - a.localeCompare(b, undefined, { sensitivity: "base" }), - ); - - expect(starnamesAndNames).toEqual(expected); - }, 60000); - - it('starnames have "Manage" links that redirect to the Manage route for that starname', async () => { - await manageFirstStarnameE2E(page); - await page.$x(`//h6[contains(., '${starname}')]`); - }, 60000); - - it('names have "Manage" links that redirect to the Manage route for that name', async () => { - await manageFirstStarnameE2E(page); - const name = await registerName(browser, page); - await sleep(2000); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - await manageFirstNameE2E(page); - await page.$x(`//h6[contains(., '${name}')]`); - }, 60000); - - it("starnames can be transferred", async () => { - await manageFirstStarnameE2E(page); - - const [menuButton] = await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON); - await menuButton.click(); - const transferLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[1]; - await transferLink.click(); - - const [recipientParent] = await getElements(page, ACCOUNT_TRANSFER_RECIPIENT); - const recipientField = await recipientParent.$("input"); - if (!recipientField) throw Error("Recipient field for transfer not found"); - await recipientField.type("test1*iov"); - - const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); - await submitButton.click(); - await sleep(2000); - - await acceptEnqueuedRequest(browser); - await sleep(2000); - await page.bringToFront(); - await page.waitForSelector(`#${TRANSFER_CONFIRMATION_VIEW_ID}`); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - const starnameMatches = await page.$x(`//h5[contains(., '${starname}')]`); - expect(starnameMatches.length).toBe(0); - }, 60000); - - it("starnames can be renewed", async () => { - const [expiryLabelElement] = await getElements(page, STARNAMES_LIST_EXPIRY_DATE); - const expiryLabelString = (await ( - await expiryLabelElement.getProperty("textContent") - ).jsonValue()) as string; - const expiryDate = parseExpiryDateLocaleEnUs(expiryLabelString); - - await manageFirstStarnameE2E(page); - - const [menuButton] = await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON); - await menuButton.click(); - const renewLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[0]; - await renewLink.click(); - - const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); - await submitButton.click(); - await sleep(2000); - - await acceptEnqueuedRequest(browser); - await sleep(2000); - await page.bringToFront(); - await page.waitForSelector(`#${RENEW_CONFIRMATION_VIEW_ID}`); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - const [newExpiryLabelElement] = await getElements(page, STARNAMES_LIST_EXPIRY_DATE); - const newExpiryLabelString = (await ( - await newExpiryLabelElement.getProperty("textContent") - ).jsonValue()) as string; - const newExpiryDate = parseExpiryDateLocaleEnUs(newExpiryLabelString); - - expect(newExpiryDate > expiryDate).toBeTruthy(); - }, 60000); - - it("starnames can be deleted and delete associated names", async () => { - await manageFirstStarnameE2E(page); - await registerName(browser, page); - await sleep(2000); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - await manageFirstStarnameE2E(page); - - const [menuButton] = await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON); - await menuButton.click(); - const deleteLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[2]; - await deleteLink.click(); - - const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); - await submitButton.click(); - await sleep(2000); - - await acceptEnqueuedRequest(browser); - await sleep(2000); - await page.bringToFront(); - await page.waitForSelector(`#${DELETE_CONFIRMATION_VIEW_ID}`); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - const starnameMatches = await page.$x(`//h5[contains(., '${starname}')]`); - expect(starnameMatches.length).toBe(0); - }, 60000); - - it("names can be transferred and trasferred back", async () => { - // Transfer - await manageFirstStarnameE2E(page); - const name = await registerName(browser, page); - await sleep(2000); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - await manageFirstStarnameE2E(page); - const [toggleShowName] = await getElements(page, ACCOUNT_MANAGE_TOGGLE_SHOW_NAMES); - await toggleShowName.click(); - await sleep(2000); - - const menuButton = (await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON))[1]; - await menuButton.click(); - const transferLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[3]; - await transferLink.click(); - await sleep(2000); - - const [recipientParent] = await getElements(page, ACCOUNT_TRANSFER_RECIPIENT); - const recipientField = await recipientParent.$("input"); - if (!recipientField) throw Error("Recipient field for transfer not found"); - await recipientField.type("test1*iov"); - - const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); - await submitButton.click(); - await sleep(2000); - - await acceptEnqueuedRequest(browser); - await sleep(2000); - await page.bringToFront(); - await page.waitForSelector(`#${TRANSFER_CONFIRMATION_VIEW_ID}`); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - const nameMatches = await page.$x(`//h5[contains(., '${name}')]`); - expect(nameMatches.length).toBe(0); - - // Transfer back - - await manageFirstStarnameE2E(page); - const [toggleShowName2] = await getElements(page, ACCOUNT_MANAGE_TOGGLE_SHOW_NAMES); - await toggleShowName2.click(); - await sleep(2000); - - const menuButton2 = (await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON))[1]; - await menuButton2.click(); - const transferBackLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[4]; - await transferBackLink.click(); - - const [submitButton2] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); - await submitButton2.click(); - await sleep(2000); - - await acceptEnqueuedRequest(browser); - await sleep(2000); - await page.bringToFront(); - await page.waitForSelector(`#${TRANSFER_CONFIRMATION_VIEW_ID}`); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - const nameMatches2 = await page.$x(`//h5[contains(., '${name}')]`); - expect(nameMatches2.length).toBe(1); - }, 60000); - - it("names can be deleted", async () => { - await manageFirstStarnameE2E(page); - const name = await registerName(browser, page); - await sleep(2000); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - await manageFirstStarnameE2E(page); - const [toggleShowName] = await getElements(page, ACCOUNT_MANAGE_TOGGLE_SHOW_NAMES); - await toggleShowName.click(); - await sleep(2000); - - const menuButton = (await getElements(page, ACCOUNT_MANAGE_MENU_BUTTON))[1]; - await menuButton.click(); - const deleteLink = (await getElements(page, ACCOUNT_MANAGE_MENU_ITEM))[5]; - await deleteLink.click(); - - const [submitButton] = await getElements(page, ACCOUNT_OPERATION_SUBMIT_BUTTON); - await submitButton.click(); - await sleep(2000); - - await acceptEnqueuedRequest(browser); - await sleep(2000); - await page.bringToFront(); - await page.waitForSelector(`#${DELETE_CONFIRMATION_VIEW_ID}`); - - await travelToAddressesE2E(page); - await travelToStarnamesTabE2E(page); - - await sleep(2000); - const nameMatches = await page.$x(`//h5[contains(., '${name}')]`); - expect(nameMatches.length).toBe(0); - }, 60000); - }); + const toastMessage = await getToastMessage(page); + expect(toastMessage).toBe("Address has been copied to clipboard."); + await closeToast(page); + }, 60000); }); diff --git a/packages/bierzo-wallet/src/routes/addresses/index.stories.tsx b/packages/bierzo-wallet/src/routes/addresses/index.stories.tsx index b75eb94b8..5d9a9ec60 100644 --- a/packages/bierzo-wallet/src/routes/addresses/index.stories.tsx +++ b/packages/bierzo-wallet/src/routes/addresses/index.stories.tsx @@ -1,21 +1,9 @@ import { Address, ChainId } from "@iov/bcp"; -import { linkTo } from "@storybook/addon-links"; import { storiesOf } from "@storybook/react"; import React from "react"; -import { BwUsernameWithChainName } from "../../components/AccountManage"; import { ChainAddressPairWithName } from "../../components/AddressesTable"; -import { BwAccount } from "../../store/accounts"; import DecoratedStorybook, { bierzoRoot } from "../../utils/storybook"; -import { - REGISTER_IOVNAME_REGISTRATION_STORY_PATH, - REGISTER_IOVNAME_STORY_PATH, - REGISTER_STARNAME_REGISTRATION_STORY_PATH, - REGISTER_STARNAME_STORY_PATH, -} from "../account/register/index.stories"; -import AddressesTab from "./components/AddressesTab"; -import Iovnames from "./components/Iovnames"; -import Starnames from "./components/Starnames"; import UserAddresses from "./components/UserAddresses"; const chainAddresses: ChainAddressPairWithName[] = [ @@ -36,114 +24,10 @@ const chainAddresses: ChainAddressPairWithName[] = [ }, ]; -const ivonames: readonly BwUsernameWithChainName[] = [ - { - username: "test1*iov", - addresses: [chainAddresses[0]], - }, - { - username: "test2*iov", - addresses: [chainAddresses[0], chainAddresses[1]], - }, - { - username: "test3*iov", - addresses: [...chainAddresses], - }, -]; - -const defaultExpiryDate = new Date("June 5, 2120 03:00:00"); - -const starnames: readonly BwAccount[] = [ - { - domain: "domain1", - name: "name1", - expiryDate: defaultExpiryDate, - addresses: [chainAddresses[0]], - owner: "tiov1dcg3fat5zrvw00xezzjk3jgedm7pg70y222af3" as Address, - }, - { - domain: "domain2", - name: "name2", - expiryDate: defaultExpiryDate, - addresses: [chainAddresses[0]], - owner: "tiov1dcg3fat5zrvw00xezzjk3jgedm7pg70y222af3" as Address, - }, - { - domain: "domain1", - name: "name2", - expiryDate: defaultExpiryDate, - addresses: [chainAddresses[0]], - owner: "tiov1dcg3fat5zrvw00xezzjk3jgedm7pg70y222af3" as Address, - }, -]; - storiesOf(`${bierzoRoot}/Addresses`, module) .addParameters({ viewport: { defaultViewport: "responsive" } }) - .add("Main with extension", () => ( - - {}} - rpcEndpointType="extension" - /> - - )) - .add("Main with names", () => ( - - {}} - rpcEndpointType="extension" - /> - - )) - .add("Main with ledger", () => ( - - {}} - rpcEndpointType="ledger" - /> - - )) .add("Addresses tab", () => ( - )) - .add("Iovnames tab", () => ( - - - - )) - .add("Iovnames with name tab", () => ( - - - - )) - .add("Starnames with name tab", () => ( - - - )); diff --git a/packages/bierzo-wallet/src/routes/addresses/index.tsx b/packages/bierzo-wallet/src/routes/addresses/index.tsx index 8e86df140..b8f810cd2 100644 --- a/packages/bierzo-wallet/src/routes/addresses/index.tsx +++ b/packages/bierzo-wallet/src/routes/addresses/index.tsx @@ -1,93 +1,16 @@ +import { Block } from "medulas-react-components"; import React from "react"; import * as ReactRedux from "react-redux"; -import { history } from ".."; -import { BwAccountWithChainName, BwUsernameWithChainName } from "../../components/AccountManage"; import PageMenu from "../../components/PageMenu"; -import { getChainName } from "../../config"; import { RootState } from "../../store/reducers"; -import { getRpcEndpointType } from "../../store/rpcendpoint/selectors"; import { getChainAddressPairWithNames } from "../../utils/tokens"; -import { IOVNAME_REGISTER_ROUTE, STARNAME_REGISTER_ROUTE } from "../paths"; -import AddressesTab from "./components/AddressesTab"; +import UserAddresses from "./components/UserAddresses"; -function onRegisterIovname(): void { - history.push(IOVNAME_REGISTER_ROUTE); -} - -function onRegisterStarname(): void { - history.push(STARNAME_REGISTER_ROUTE); -} +export const ADDRESSES_VIEW_ID = "addresses-view-id"; const Addresses = (): JSX.Element => { const identities = ReactRedux.useSelector((state: RootState) => state.identities); - const bwNames = ReactRedux.useSelector((state: RootState) => state.usernames); - const starnames = ReactRedux.useSelector((state: RootState) => state.accounts); - const rpcEndpointType = ReactRedux.useSelector(getRpcEndpointType); - const [bwNamesWithChain, setBwNamesWithChain] = React.useState([]); - const [bwAccountsWithChain, setBwAccountsWithChain] = React.useState([]); - - React.useEffect(() => { - let isSubscribed = true; - async function insertChainNames(): Promise { - if (isSubscribed) { - const bwNamesWithChain: BwUsernameWithChainName[] = await Promise.all( - bwNames.map(async name => { - return { - username: name.username, - addresses: await Promise.all( - name.addresses.map(async address => { - return { - chainId: address.chainId, - address: address.address, - chainName: await getChainName(address.chainId), - }; - }), - ), - }; - }), - ); - - setBwNamesWithChain(bwNamesWithChain); - } - } - insertChainNames(); - - return () => { - isSubscribed = false; - }; - }, [bwNames]); - - React.useEffect(() => { - let isSubscribed = true; - async function insertChainNames(): Promise { - if (isSubscribed) { - const bwAccountsWithChain: BwAccountWithChainName[] = await Promise.all( - starnames.map(async name => { - return { - ...name, - addresses: await Promise.all( - name.addresses.map(async address => { - return { - chainId: address.chainId, - address: address.address, - chainName: await getChainName(address.chainId), - }; - }), - ), - }; - }), - ); - - setBwAccountsWithChain(bwAccountsWithChain); - } - } - insertChainNames(); - - return () => { - isSubscribed = false; - }; - }, [starnames]); const supportedChains = React.useMemo( () => @@ -102,14 +25,16 @@ const Addresses = (): JSX.Element => { return ( - + + + ); }; diff --git a/packages/bierzo-wallet/src/routes/addresses/test/operateAddresses.ts b/packages/bierzo-wallet/src/routes/addresses/test/operateAddresses.ts new file mode 100644 index 000000000..054b4a58c --- /dev/null +++ b/packages/bierzo-wallet/src/routes/addresses/test/operateAddresses.ts @@ -0,0 +1,39 @@ +import { Page } from "puppeteer"; + +import { ADDRESSES_TAB_TITLE } from "../../../components/Header/components/LinksMenu"; +import { whenOnNavigatedToE2eRoute } from "../../../utils/test/navigation"; +import { ADDRESSES_ROUTE } from "../../paths"; + +export async function travelToAddressesE2E(page: Page): Promise { + const [addressesLink] = await page.$x(`//h6[contains(., '${ADDRESSES_TAB_TITLE}')]`); + await addressesLink.click(); + await whenOnNavigatedToE2eRoute(page, ADDRESSES_ROUTE); +} + +export async function getAddressRow(page: Page, dataIndex: number): Promise { + const chainNameEl = await page.$(`tbody tr:nth-of-type(${dataIndex}) td:nth-of-type(1)`); + if (chainNameEl === null) { + throw new Error(`TD element containig chain name with row index: ${dataIndex} not found.`); + } + + const addressEl = await page.$(`tbody tr:nth-of-type(${dataIndex}) td:nth-of-type(2)`); + if (addressEl === null) { + throw new Error(`TD element containig address with row index: ${dataIndex} not found.`); + } + + const chainName = (await (await chainNameEl.getProperty("textContent")).jsonValue()) as string; + const address = (await (await addressEl.getProperty("textContent")).jsonValue()) as string; + + return [chainName, address]; +} + +export async function copyAddress(page: Page, dataIndex: number): Promise { + const addressEl = await page.$(`tbody tr:nth-of-type(${dataIndex}) td:nth-of-type(2)`); + if (addressEl === null) { + throw new Error(`TD element containig address with row index: ${dataIndex} not found.`); + } + + await page.click(`tbody tr:nth-of-type(${dataIndex}) td:nth-of-type(3)`); + + return (await (await addressEl.getProperty("textContent")).jsonValue()) as string; +} diff --git a/packages/bierzo-wallet/src/routes/addresses/test/operateReceivePayment.ts b/packages/bierzo-wallet/src/routes/addresses/test/operateReceivePayment.ts deleted file mode 100644 index 0e3a2ce7c..000000000 --- a/packages/bierzo-wallet/src/routes/addresses/test/operateReceivePayment.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { ElementHandle, Page } from "puppeteer"; - -import { iovnamesViewId as starnamesViewId } from "../components/Iovnames"; - -export async function getAddressRow(page: Page, dataIndex: number): Promise { - const chainNameEl = await page.$(`tbody tr:nth-of-type(${dataIndex}) td:nth-of-type(1)`); - if (chainNameEl === null) { - throw new Error(`TD element containig chain name with row index: ${dataIndex} not found.`); - } - - const addressEl = await page.$(`tbody tr:nth-of-type(${dataIndex}) td:nth-of-type(2)`); - if (addressEl === null) { - throw new Error(`TD element containig address with row index: ${dataIndex} not found.`); - } - - const chainName = (await (await chainNameEl.getProperty("textContent")).jsonValue()) as string; - const address = (await (await addressEl.getProperty("textContent")).jsonValue()) as string; - - return [chainName, address]; -} - -export async function copyAddress(page: Page, dataIndex: number): Promise { - const addressEl = await page.$(`tbody tr:nth-of-type(${dataIndex}) td:nth-of-type(2)`); - if (addressEl === null) { - throw new Error(`TD element containig address with row index: ${dataIndex} not found.`); - } - - await page.click(`tbody tr:nth-of-type(${dataIndex}) td:nth-of-type(3)`); - - return (await (await addressEl.getProperty("textContent")).jsonValue()) as string; -} - -export async function copyIovname(page: Page): Promise { - const iovnameEl = await page.$(`#${starnamesViewId} h4`); - if (iovnameEl === null) { - throw new Error(`Iovname element was not found.`); - } - - await page.click(`#${starnamesViewId} img`); -} - -export async function getIovnames(page: Page): Promise { - const iovnameEls = (await page.$$("h5")).slice(1); - const names: string[] = []; - for (const el of iovnameEls) { - names.push((await (await el.getProperty("textContent")).jsonValue()) as string); - } - - return names; -} - -export async function copyStarname(page: Page): Promise { - const starnameEl = await page.$(`#${starnamesViewId} h4`); - if (starnameEl === null) { - throw new Error(`Starname element was not found.`); - } - - await page.click(`#${starnamesViewId} img`); -} - -export async function getStarnames(page: Page): Promise { - const starnameEls = (await page.$$("h5")).slice(1); - const names: string[] = []; - for (const el of starnameEls) { - names.push((await (await el.getProperty("textContent")).jsonValue()) as string); - } - - return names; -} - -export async function getRemoveActions(page: Page): Promise[]> { - return await page.$x(`//p[contains(., 'Remove')]`); -} - -export async function getLinkedAddresses(page: Page): Promise { - const addressesRows = await page.$$("tr"); - const addresses: string[] = []; - for (const el of addressesRows) { - addresses.push((await (await el.getProperty("textContent")).jsonValue()) as string); - } - - addresses.splice(0, 1); - return addresses; -} - -// Expects an expirty date label with the format: Expires on 4/15/2020 8:43:10 AM -export function parseExpiryDateLocaleEnUs(expiryLabel: string): Date { - const [, , dateString, ...timeArray] = expiryLabel.split(" "); - const timeString = timeArray.join(" "); - - return new Date(`${dateString} ${timeString}`); -} diff --git a/packages/bierzo-wallet/src/routes/addresses/test/travelToReceivePayment.ts b/packages/bierzo-wallet/src/routes/addresses/test/travelToReceivePayment.ts deleted file mode 100644 index fb4983a67..000000000 --- a/packages/bierzo-wallet/src/routes/addresses/test/travelToReceivePayment.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Page } from "puppeteer"; - -import { manageIovnameId, manageStarnameId } from "../../../components/AccountManage"; -import { ADDRESSES_TEXT } from "../../../components/Header/components/LinksMenu"; -import { whenOnNavigatedToE2eRoute } from "../../../utils/test/navigation"; -import { ADDRESSES_ROUTE } from "../../paths"; -import { yourAddresses, yourIovnames, yourStarnames } from "../components/AddressesTab"; -import { iovnamesViewId } from "../components/Iovnames"; -import { starnamesViewId } from "../components/Starnames"; -import { yourBlockchainAddressesId } from "../components/UserAddresses"; - -export async function travelToAddressesE2E(page: Page): Promise { - const [addressesLink] = await page.$x(`//h6[contains(., '${ADDRESSES_TEXT}')]`); - await addressesLink.click(); - await whenOnNavigatedToE2eRoute(page, ADDRESSES_ROUTE); -} - -export async function travelToBlockchainAddressesTabE2E(page: Page): Promise { - const [addressesLink] = await page.$x(`//h6[contains(., '${yourAddresses}')]`); - await addressesLink.click(); - await page.waitForSelector(`#${yourBlockchainAddressesId}`); -} - -export async function travelToIovnamesTabE2E(page: Page): Promise { - const [addressesLink] = await page.$x(`//h6[contains(., '${yourIovnames}')]`); - await addressesLink.click(); - await page.waitForSelector(`#${iovnamesViewId}`); -} - -export async function travelToStarnamesTabE2E(page: Page): Promise { - const [addressesLink] = await page.$x(`//h6[contains(., '${yourStarnames}')]`); - await addressesLink.click(); - await page.waitForSelector(`#${starnamesViewId}`); -} - -export async function manageFirstIovnameE2E(page: Page): Promise { - const [firstStarnameEditLink] = await page.$x(`//h6[contains(., 'Manage')]`); - await firstStarnameEditLink.click(); - await page.waitForSelector(`#${manageIovnameId}`); -} - -export async function manageFirstStarnameE2E(page: Page): Promise { - const [firstStarnameEditLink] = await page.$x(`//h6[contains(., 'Manage')]`); - await firstStarnameEditLink.click(); - await page.waitForSelector(`#${manageStarnameId}`); - expect(page.url().endsWith("/starname/manage")).toBe(true); -} - -export async function manageFirstNameE2E(page: Page): Promise { - const firstNameEditLink = (await page.$x(`//h6[contains(., 'Manage')]`))[1]; - await firstNameEditLink.click(); - await page.waitForSelector(`#${manageStarnameId}`); - expect(page.url().endsWith("/name/manage")).toBe(true); -} From 2cbe68f4b8d9ebe2a48466b2eac58af84613974e Mon Sep 17 00:00:00 2001 From: abefernan Date: Thu, 23 Apr 2020 13:18:07 +0200 Subject: [PATCH 5/9] Adds names links to header component --- .../Header/components/LinksMenu/index.tsx | 70 ++++++++++++------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/packages/bierzo-wallet/src/components/Header/components/LinksMenu/index.tsx b/packages/bierzo-wallet/src/components/Header/components/LinksMenu/index.tsx index aa783ac11..cc007bef8 100644 --- a/packages/bierzo-wallet/src/components/Header/components/LinksMenu/index.tsx +++ b/packages/bierzo-wallet/src/components/Header/components/LinksMenu/index.tsx @@ -1,11 +1,16 @@ import { makeStyles, Theme } from "@material-ui/core"; -import classNames from "classnames"; import { Badge, Block, Typography } from "medulas-react-components"; import * as React from "react"; import { ProcessedTx } from "../../../../logic/transactions/types/BwParser"; import { history } from "../../../../routes"; -import { ADDRESSES_ROUTE, BALANCE_ROUTE, TRANSACTIONS_ROUTE } from "../../../../routes/paths"; +import { + ADDRESSES_ROUTE, + BALANCE_ROUTE, + IOVNAME_ROUTE, + STARNAME_ROUTE, + TRANSACTIONS_ROUTE, +} from "../../../../routes/paths"; import { getLastTx, TxMeta } from "../../../../utils/localstorage/transactions"; const useStyles = makeStyles((theme: Theme) => ({ @@ -21,13 +26,7 @@ const useStyles = makeStyles((theme: Theme) => ({ cursor: "pointer", }, }, - activated: { - "& $line": { - visibility: "visible", - }, - }, line: { - visibility: "hidden", height: "4px", backgroundColor: theme.palette.primary.main, borderRadius: "4px", @@ -39,14 +38,22 @@ const onBalance = (): void => { history.push(BALANCE_ROUTE); }; -const onAddresses = (): void => { - history.push(ADDRESSES_ROUTE); +const onStarnames = (): void => { + history.push(STARNAME_ROUTE); +}; + +const onIovnames = (): void => { + history.push(IOVNAME_ROUTE); }; const onTransactions = (): void => { history.push(TRANSACTIONS_ROUTE); }; +const onAddresses = (): void => { + history.push(ADDRESSES_ROUTE); +}; + const lastTxNewer = (lastTx: TxMeta, lastStoredTx: TxMeta): boolean => { return lastTx.time.getTime() > lastStoredTx.time.getTime(); }; @@ -75,9 +82,11 @@ const calcTxBadgeVisibilityState = ( return false; }; -const BALANCE_TEXT = "Balances"; -export const ADDRESSES_TEXT = "Addresses"; -export const TRANSACTIONS_TEXT = "Transactions"; +export const BALANCES_TAB_TITLE = "Balances"; +export const STARNAMES_TAB_TITLE = "Starnames"; +export const IOVNAMES_TAB_TITLE = "iovnames"; +export const TRANSACTIONS_TAB_TITLE = "Transactions"; +export const ADDRESSES_TAB_TITLE = "Addresses"; interface MenuItemProps { readonly showBadge?: boolean; @@ -108,34 +117,41 @@ interface Props { const LinksMenu = ({ path, lastTx }: Props): JSX.Element => { const classes = useStyles(); - const showBalance = path === BALANCE_ROUTE; + + const showBalances = path === BALANCE_ROUTE; + const showStarnames = path === STARNAME_ROUTE; + const showIovnames = path === IOVNAME_ROUTE; const showTransactions = path === TRANSACTIONS_ROUTE; const showAddresses = path === ADDRESSES_ROUTE; - const balanceClasses = classNames(classes.item, showBalance ? classes.activated : undefined); - const addressesClasses = classNames(classes.item, showAddresses ? classes.activated : undefined); - const transactionsClasses = classNames(classes.item, showTransactions ? classes.activated : undefined); - const showBadge = calcTxBadgeVisibilityState(lastTx, getLastTx()); return ( - - - + + + {showBalances && } + + + + {showStarnames && } - - - + + + {showIovnames && } - + - + {showTransactions && } + + + + {showAddresses && } ); From 95efe0a77ca7505a0e4425dd3dfa1131c0d500e2 Mon Sep 17 00:00:00 2001 From: abefernan Date: Thu, 23 Apr 2020 13:20:09 +0200 Subject: [PATCH 6/9] Removes unneeded prop --- .../src/routes/balance/components/index.tsx | 8 +++----- packages/bierzo-wallet/src/routes/balance/index.tsx | 9 +-------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/bierzo-wallet/src/routes/balance/components/index.tsx b/packages/bierzo-wallet/src/routes/balance/components/index.tsx index 8fe1b8aef..ce9909267 100644 --- a/packages/bierzo-wallet/src/routes/balance/components/index.tsx +++ b/packages/bierzo-wallet/src/routes/balance/components/index.tsx @@ -5,9 +5,8 @@ import { Block, Image, Typography } from "medulas-react-components"; import React from "react"; import { amountToString } from "ui-logic"; -import { RpcEndpointType } from "../../../communication/rpcEndpoint"; import PageContent from "../../../components/PageContent"; -import { GetYourAddress } from "../../addresses/components/IovnamesNotExists"; +import { GetYourAddress } from "../../iovnames/components/IovnamesNotExists"; import wallet from "../assets/wallet.svg"; const walletIcon = wallet ico; @@ -16,10 +15,9 @@ interface Props { readonly iovAddress?: string; readonly balances: { [token: string]: Amount }; readonly onRegisterIovname: () => void; - readonly rpcEndpointType: RpcEndpointType; } -const BalanceLayout = ({ iovAddress, balances, onRegisterIovname, rpcEndpointType }: Props): JSX.Element => { +const BalanceLayout = ({ iovAddress, balances, onRegisterIovname }: Props): JSX.Element => { const tickersList = Object.keys(balances).sort(); const hasTokens = tickersList.length > 0; const theme = useTheme(); @@ -38,7 +36,7 @@ const BalanceLayout = ({ iovAddress, balances, onRegisterIovname, rpcEndpointTyp textAlign="center" border="1px solid #F3F3F3" > - + )} diff --git a/packages/bierzo-wallet/src/routes/balance/index.tsx b/packages/bierzo-wallet/src/routes/balance/index.tsx index 74544b77b..e1da3dd7f 100644 --- a/packages/bierzo-wallet/src/routes/balance/index.tsx +++ b/packages/bierzo-wallet/src/routes/balance/index.tsx @@ -4,7 +4,6 @@ import * as ReactRedux from "react-redux"; import { history } from ".."; import PageMenu from "../../components/PageMenu"; import { RootState } from "../../store/reducers"; -import { getRpcEndpointType } from "../../store/rpcendpoint/selectors"; import { getFirstUsername } from "../../store/usernames/selectors"; import { IOVNAME_REGISTER_ROUTE } from "../paths"; import Layout from "./components"; @@ -16,17 +15,11 @@ function onRegisterIovname(): void { const Balance = (): JSX.Element => { const tokens = ReactRedux.useSelector((state: RootState) => state.balances); const bnsUsername = ReactRedux.useSelector(getFirstUsername); - const rpcEndpointType = ReactRedux.useSelector(getRpcEndpointType); const iovAddress = bnsUsername ? bnsUsername.username : undefined; return ( - + ); }; From 604af59d0a5d57c853165fc9cca587cfdcb820da Mon Sep 17 00:00:00 2001 From: abefernan Date: Thu, 23 Apr 2020 13:20:26 +0200 Subject: [PATCH 7/9] Hides show names link when no names --- .../manage/components/AssociatedNamesList.tsx | 96 ++++++++++--------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/packages/bierzo-wallet/src/routes/account/manage/components/AssociatedNamesList.tsx b/packages/bierzo-wallet/src/routes/account/manage/components/AssociatedNamesList.tsx index fb0273d52..f38640c1e 100644 --- a/packages/bierzo-wallet/src/routes/account/manage/components/AssociatedNamesList.tsx +++ b/packages/bierzo-wallet/src/routes/account/manage/components/AssociatedNamesList.tsx @@ -55,6 +55,8 @@ const AssociatedNamesList: React.FunctionComponent = ({ setShow(show => !show); }; + const hasAssociatedNames = names.length > 0; + return ( @@ -74,55 +76,59 @@ const AssociatedNamesList: React.FunctionComponent = ({ - - - - - Names associated with this starname - + {hasAssociatedNames && ( + + + + + + Names associated with this starname + + + arrow + - arrow - - - - {names - .slice() - .sort((a, b) => - `${a.name}*${a.domain}`.localeCompare(`${b.name}*${b.domain}`, undefined, { - sensitivity: "base", - }), - ) - .map(name => { - const onEdit = (): void => { - history.push(NAME_EDIT_ROUTE, name); - }; + + {names + .slice() + .sort((a, b) => + `${a.name}*${a.domain}`.localeCompare(`${b.name}*${b.domain}`, undefined, { + sensitivity: "base", + }), + ) + .map(name => { + const onEdit = (): void => { + history.push(NAME_EDIT_ROUTE, name); + }; - const accountState: AccountLocationState = { - domain: domain, - account: name, - }; + const accountState: AccountLocationState = { + domain: domain, + account: name, + }; - const menuItems: readonly ActionMenuItem[] = [ - { title: "Transfer name", action: () => history.push(NAME_TRANSFER_ROUTE, accountState) }, - { - title: "Transfer it back to me", - action: () => history.push(NAME_TRANSFER_BACK_ROUTE, accountState), - }, - { title: "Delete name", action: () => history.push(NAME_DELETE_ROUTE, accountState) }, - ]; + const menuItems: readonly ActionMenuItem[] = [ + { title: "Transfer name", action: () => history.push(NAME_TRANSFER_ROUTE, accountState) }, + { + title: "Transfer it back to me", + action: () => history.push(NAME_TRANSFER_BACK_ROUTE, accountState), + }, + { title: "Delete name", action: () => history.push(NAME_DELETE_ROUTE, accountState) }, + ]; - return ( - - ); - })} - + return ( + + ); + })} + + + )} ); From eb29d924ce5b2e237ca43a953404f43104940c61 Mon Sep 17 00:00:00 2001 From: abefernan Date: Thu, 23 Apr 2020 13:22:01 +0200 Subject: [PATCH 8/9] Adapts misc tests --- .../src/routes/balance/index.dom.spec.ts | 6 ++-- .../src/routes/balance/index.stories.tsx | 28 +++++++++++++++---- .../routes/balance/test/operateBalances.ts | 15 +++++----- .../src/routes/transactions/index.e2e.spec.ts | 4 +-- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/packages/bierzo-wallet/src/routes/balance/index.dom.spec.ts b/packages/bierzo-wallet/src/routes/balance/index.dom.spec.ts index aa3431bfa..38ccebd20 100644 --- a/packages/bierzo-wallet/src/routes/balance/index.dom.spec.ts +++ b/packages/bierzo-wallet/src/routes/balance/index.dom.spec.ts @@ -5,7 +5,7 @@ import { DeepPartial, Store } from "redux"; import { extensionRpcEndpoint } from "../../communication/extensionRpcEndpoint"; import { ledgerRpcEndpoint } from "../../communication/ledgerRpcEndpoint"; -import { TRANSACTIONS_TEXT } from "../../components/Header/components/LinksMenu"; +import { TRANSACTIONS_TAB_TITLE } from "../../components/Header/components/LinksMenu"; import { aNewStore } from "../../store"; import { BalanceState } from "../../store/balances"; import { ExtendedIdentity, IdentitiesState } from "../../store/identities"; @@ -77,10 +77,10 @@ describe("The /balance route", () => { it("redirects to the /transactions route when clicked", async () => { const transactionsCard = (await findRenderedDOMComponentWithId( balanceDom, - TRANSACTIONS_TEXT, + TRANSACTIONS_TAB_TITLE, )) as Element; - expect(transactionsCard.textContent).toBe(TRANSACTIONS_TEXT); + expect(transactionsCard.textContent).toBe(TRANSACTIONS_TAB_TITLE); await click(transactionsCard); expectRoute(TRANSACTIONS_ROUTE); diff --git a/packages/bierzo-wallet/src/routes/balance/index.stories.tsx b/packages/bierzo-wallet/src/routes/balance/index.stories.tsx index f3b947270..f1aeef24c 100644 --- a/packages/bierzo-wallet/src/routes/balance/index.stories.tsx +++ b/packages/bierzo-wallet/src/routes/balance/index.stories.tsx @@ -3,6 +3,7 @@ import { linkTo } from "@storybook/addon-links"; import { storiesOf } from "@storybook/react"; import React from "react"; +import { RpcEndpoint } from "../../communication/rpcEndpoint"; import PageMenu from "../../components/PageMenu"; import { BalanceState } from "../../store/balances"; import DecoratedStorybook, { bierzoRoot } from "../../utils/storybook"; @@ -32,6 +33,26 @@ const NO_BALANCE = {}; const ACCOUNT_NAME = "adolfo*iov"; +const extensionRpcEndpoint: RpcEndpoint = { + authorizeGetIdentitiesMessage: "test authorizeGetIdentitiesMessage", + authorizeSignAndPostMessage: "test authorizeSignAndPostMessage", + noMatchingIdentityMessage: "test noMatchingIdentityMessage", + notAvailableMessage: "test notAvailableMessage", + sendGetIdentitiesRequest: _req => Promise.resolve(undefined), + sendSignAndPostRequest: _req => Promise.resolve(undefined), + type: "extension", +}; + +const ledgerRpcEndpoint: RpcEndpoint = { + authorizeGetIdentitiesMessage: "test authorizeGetIdentitiesMessage", + authorizeSignAndPostMessage: "test authorizeSignAndPostMessage", + noMatchingIdentityMessage: "test noMatchingIdentityMessage", + notAvailableMessage: "test notAvailableMessage", + sendGetIdentitiesRequest: _req => Promise.resolve(undefined), + sendSignAndPostRequest: _req => Promise.resolve(undefined), + type: "ledger", +}; + storiesOf(BALANCE_STORY_PATH, module) .addParameters({ viewport: { defaultViewport: "responsive" } }) .add(BALANCE_STORY_VIEW_PATH, () => ( @@ -39,7 +60,6 @@ storiesOf(BALANCE_STORY_PATH, module) @@ -47,11 +67,10 @@ storiesOf(BALANCE_STORY_PATH, module) )) .add("View without tokens and without name", () => ( - + @@ -59,11 +78,10 @@ storiesOf(BALANCE_STORY_PATH, module) )) .add("View on ledger and without name", () => ( - + diff --git a/packages/bierzo-wallet/src/routes/balance/test/operateBalances.ts b/packages/bierzo-wallet/src/routes/balance/test/operateBalances.ts index 93c1e480a..5746033fe 100644 --- a/packages/bierzo-wallet/src/routes/balance/test/operateBalances.ts +++ b/packages/bierzo-wallet/src/routes/balance/test/operateBalances.ts @@ -5,19 +5,19 @@ import { acceptEnqueuedRequest } from "../../../utils/test/persona"; import { REGISTER_IOVNAME_FIELD } from "../../account/register/components/IovnameForm"; import { REGISTER_NAME_FIELD, REGISTER_NAME_VIEW_ID } from "../../account/register/components/NameForm"; import { REGISTER_STARNAME_FIELD } from "../../account/register/components/StarnameForm"; -import { registerIovnameId } from "../../addresses/components/Iovnames"; -import { registerStarnameId } from "../../addresses/components/Starnames"; +import { REGISTER_IOVNAME_LINK } from "../../iovnames"; +import { REGISTER_STARNAME_LINK } from "../../starnames"; const mainMenuH6Elements = 3; const numberOfTokensFromFaucet = 4; export const getNoFundsMessage = (h6Elements: Element[]): string => { - const index = mainMenuH6Elements + 4; + const index = mainMenuH6Elements + 6; return h6Elements[index].textContent || ""; }; export const getIovUsername = (h6Elements: Element[]): string => { - const index = mainMenuH6Elements + 2; + const index = mainMenuH6Elements + 4; return h6Elements[index].textContent || ""; }; @@ -40,12 +40,12 @@ export function waitForAllBalances(page: Page): Promise { } export const getAddressCreationPromptE2E = async (h6Elements: ElementHandle[]): Promise => { - const index = mainMenuH6Elements + 2; + const index = mainMenuH6Elements + 4; return ((await (await h6Elements[index].getProperty("textContent")).jsonValue()) as string) || ""; }; export const registerIovname = async (browser: Browser, page: Page): Promise => { - await page.click(`#${registerIovnameId}`); + await page.click(`#${REGISTER_IOVNAME_LINK}`); // Fill the form await sleep(1000); @@ -63,7 +63,7 @@ export const registerIovname = async (browser: Browser, page: Page): Promise => { - await page.click(`#${registerStarnameId}`); + await page.click(`#${REGISTER_STARNAME_LINK}`); // Fill the form await sleep(1000); @@ -84,6 +84,7 @@ export const registerName = async (browser: Browser, page: Page): Promise Transactions route", () => { it("contains faucet transactions", async () => { await waitForAllBalances(page); - const [txLink] = await page.$x(`//h6[contains(., '${TRANSACTIONS_TEXT}')]`); + const [txLink] = await page.$x(`//h6[contains(., '${TRANSACTIONS_TAB_TITLE}')]`); await txLink.click(); await whenOnNavigatedToE2eRoute(page, TRANSACTIONS_ROUTE); From 1e2558e149593d1a9504790bff4392b2b2c5e841 Mon Sep 17 00:00:00 2001 From: abefernan Date: Thu, 23 Apr 2020 13:22:10 +0200 Subject: [PATCH 9/9] Updates storybook snapshots --- .../src/__snapshots__/Storyshots.test.js.snap | 3343 ++++++++++------- 1 file changed, 1897 insertions(+), 1446 deletions(-) diff --git a/packages/valdueza-storybook/src/__snapshots__/Storyshots.test.js.snap b/packages/valdueza-storybook/src/__snapshots__/Storyshots.test.js.snap index b20d46535..0136c3c71 100644 --- a/packages/valdueza-storybook/src/__snapshots__/Storyshots.test.js.snap +++ b/packages/valdueza-storybook/src/__snapshots__/Storyshots.test.js.snap @@ -210,9 +210,6 @@ exports[`Storyshots Bierzo Wallet Policy 1`] = ` -
- Addresses + Starnames
+ +
+ className="MuiBox-root MuiBox-root" + > +
+
+ iovnames +
+
+
+ +
+ className="MuiBox-root MuiBox-root" + > +
+
+ Addresses +
+
+
-
- Addresses + Starnames
+ +
+ className="MuiBox-root MuiBox-root" + > +
+
+ iovnames +
+
+
+ +
+ className="MuiBox-root MuiBox-root" + > +
+
+ Addresses +
+
+
`; -exports[`Storyshots Bierzo Wallet/Addresses Iovnames tab 1`] = ` +exports[`Storyshots Bierzo Wallet/Balance View 1`] = `
-
+ Logo
+
-
- yourname*iov -
+
+
+ Balances +
+
+
-
- You have no iovnames -
-

+

+
+ Starnames +
+
+
+
+
- With Neuma you can choose your easy to read human readable address. No more complicated cryptography when sending to friends. -

+
+
+
+ iovnames +
+
+
+
-
- Choose Now -
+
+
+
+ Transactions +
+
+
+
+
+
+
+
+ Addresses +
+
+
+
-
-
-`; - -exports[`Storyshots Bierzo Wallet/Addresses Iovnames with name tab 1`] = ` -
-
-
+
- Iovname Logo -
-
- Register a new iovname -
+ Hi! + +
-

- Register now -

-
-
- test1*iov -
-
- Manage -
-
-
-
-
-
-
- test2*iov -
-
- Manage -
-
-
-
-
-
-
- test3*iov -
-
+
+
- Manage -
+
+
+
+
+ wallet ico +
+
+
+ Your currencies +
+
+
+ 8.25 BASH +
+
+ 12.26775 CASH +
+
+
+
+
+
+
`; -exports[`Storyshots Bierzo Wallet/Addresses Main with extension 1`] = ` +exports[`Storyshots Bierzo Wallet/Balance View on ledger and without name 1`] = `
+ Logo
+
-
- Your starnames -
+
+
+ Balances +
+
+
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ Starnames +
+
+
-
-
-
- Your iovnames -
+
+
+ iovnames +
+
+
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ Transactions +
+
+
+
+
+
+
+
+ Addresses +
+
+
+
- Your blockchain addresses + Hi!
-
+
-
+
-
-
- *yourstarname -
-
-
- Register your starname -
-

- A starname is your universal username for the blockchain world. It enables you to receive crypto-currencies or to log in to blockchain applications in a seamless way. Transferring value becomes fast an easy. -

+
+
+ yourname*iov +
+
+
+

+ You can not register +

+

+ iovnames +

+
+

+ using + +

+

+ Ledger Nano S +

+
+
+
+
+
-
- Register Now -
+
+
+
+ wallet ico +
+
+
+ You have no funds available +
+
+
+
+
+
+
`; -exports[`Storyshots Bierzo Wallet/Addresses Main with ledger 1`] = ` +exports[`Storyshots Bierzo Wallet/Balance View without tokens and without name 1`] = `
+ Logo
-
-
- Your starnames -
-
-
-
+ />
-
- Your iovnames -
-
-
-
-
-
- Your blockchain addresses -
-
+
+
+ Balances +
+
+
-
-
-
-
-
-
- *yourstarname -
+
+ Starnames +
+
-
-

- You can not register -

-

- starname -

+
+
-

- using - -

-

- Ledger Nano S -

+
+ iovnames +
+
-
-
-
-`; - -exports[`Storyshots Bierzo Wallet/Addresses Main with names 1`] = ` -
-
-
-
- Your starnames -
+ className="MuiBox-root MuiBox-root" + > +
+
+ Transactions +
+
+
-
-
-
- Your iovnames -
+ className="MuiBox-root MuiBox-root" + > +
+
+ Addresses +
+
+
+
- Your blockchain addresses + Hi!
-
+
-
+
- Iovname Logo +
+
+ yourname*iov +
+
-
- Register a new starname -
-
-

- Register now -

-
-
-
-
-
-
-
+

- name1*domain1 -

+ With Neuma you can choose your easy to read human readable address. No more complicated cryptography when sending to friends. +

+
+
+ Choose Now +
-
- Manage -
-
-
-
-
-
- name2*domain1 -
-
-
- Manage -
-
-
-
-
+ />
-
- name2*domain2 -
+
+
+ wallet ico +
+
+
+ You have no funds available +
+
+
+
+
+
-
- Manage -
`; -exports[`Storyshots Bierzo Wallet/Addresses Starnames with name tab 1`] = ` +exports[`Storyshots Bierzo Wallet/BillboardMessage Ledger 1`] = `
-
+ ledger
-
- Iovname Logo -
-
- Register a new starname -
-

- Register now + Waiting for Ledger device to provide identity...

+
+`; + +exports[`Storyshots Bierzo Wallet/BillboardMessage Neuma 1`] = ` +
-
+ toolbar + zoom + logoZoom
-
- name1*domain1 -
+ 1
-
- Manage -
-
-
-
-
-
-
- name2*domain1 -
+ arrow + arrow
-
- Manage -
-
-
-
-
-
-
- name2*domain2 -
-
-
- Manage -
-
+ Please authorize request in Neuma Browser Extension to continue. +

+

+ Use the Neuma Browser Extension located in the Browser menu in order to authorize your request. +

`; -exports[`Storyshots Bierzo Wallet/Balance View 1`] = ` +exports[`Storyshots Bierzo Wallet/Components Header 1`] = `
+
+ Txs Header +
@@ -5668,9 +5885,25 @@ exports[`Storyshots Bierzo Wallet/Balance View 1`] = `
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ Starnames +
+
+
- Addresses + iovnames
+
+
+ className="MuiBox-root MuiBox-root" + > +
+ +
+ Transactions +
+ + new + +
+
+
- Transactions + Addresses
-
+
+
-
-
-
-
-
-
-
-
- wallet ico -
-
-
- Your currencies -
-
-
- 8.25 BASH -
-
- 12.26775 CASH -
-
-
-
-
-
-
-
-
-
-`; - -exports[`Storyshots Bierzo Wallet/Balance View on ledger and without name 1`] = ` -
+ Empty Header +
@@ -5866,9 +6061,6 @@ exports[`Storyshots Bierzo Wallet/Balance View on ledger and without name 1`] =
-
- Addresses + Starnames
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ iovnames +
+
+
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ Addresses +
+
+
+
+
+`; + +exports[`Storyshots Bierzo Wallet/Components PageMenuColumn 1`] = ` +
+
+ Logo
+
-
- yourname*iov + Balances
+
+
+
+
-

- You can not register -

-

- iovnames -

+
+ Starnames +
+
+
+
+
+
-

- using - -

-

- Ledger Nano S -

+ iovnames +
-
-
-
- wallet ico -
-
+ -
- You have no funds available -
-
-
-
-
+ new +
+ +
+
+
+
+
+
+
+ Addresses +
+
+
+
+
+ Hi! +
+ +
+
+
+
+
+
+
+
+ What is Lorem Ipsum? +
+

+ + Lorem Ipsum + + is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. +

+
+
+
`; -exports[`Storyshots Bierzo Wallet/Balance View without tokens and without name 1`] = ` +exports[`Storyshots Bierzo Wallet/Components/PageMenu With padding 1`] = `
@@ -6100,9 +6433,25 @@ exports[`Storyshots Bierzo Wallet/Balance View without tokens and without name 1
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ Starnames +
+
+
- Addresses + iovnames
+
+
+ className="MuiBox-root MuiBox-root" + > +
+ +
+ Transactions +
+ + new + +
+
+
- Transactions + Addresses
-
+
+ What is Lorem Ipsum? +
+

+ + Lorem Ipsum + + is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. +

+
+
+`; + +exports[`Storyshots Bierzo Wallet/Components/PageMenu Without padding 1`] = ` +
+
+ Logo
+
-
- yourname*iov + Balances
-
-
- You have no iovnames -
-

- With Neuma you can choose your easy to read human readable address. No more complicated cryptography when sending to friends. -

-
-
- Choose Now -
-
-
-
-
-
-
-
-
- wallet ico -
-
-
- You have no funds available -
-
-
-
-
-
-
-
-
-`; - -exports[`Storyshots Bierzo Wallet/BillboardMessage Ledger 1`] = ` -
-
- ledger -
-

- Waiting for Ledger device to provide identity... -

-
-
-
-`; - -exports[`Storyshots Bierzo Wallet/BillboardMessage Neuma 1`] = ` -
-
-
- toolbar - zoom - logoZoom -
- 1 -
-
- arrow - arrow -
-
-

- Please authorize request in Neuma Browser Extension to continue. -

-

- Use the Neuma Browser Extension located in the Browser menu in order to authorize your request. -

-
-
-`; - -exports[`Storyshots Bierzo Wallet/Components Header 1`] = ` -
-
- Txs Header -
-
- Logo -
-
@@ -6420,16 +6634,13 @@ exports[`Storyshots Bierzo Wallet/Components Header 1`] = ` >
- Balances + Starnames
-
- Addresses + iovnames
-
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ Addresses +
+
+
-
-
- Empty Header -
-
- Logo -
-
-
+

+ + Lorem Ipsum + + is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. +

+
+
+`; + +exports[`Storyshots Bierzo Wallet/Iovnames With iovnames 1`] = ` +
+
+ Logo +
+
+
-
- Addresses + Starnames
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ iovnames +
+
+
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ Addresses +
+
+
-
+ > +
+
+
+
+
+ yourname*iov +
+
+
+
+ You have no iovnames +
+

+ With Neuma you can choose your easy to read human readable address. No more complicated cryptography when sending to friends. +

+
+
+ Choose Now +
+
+
+
+
`; -exports[`Storyshots Bierzo Wallet/Components PageMenuColumn 1`] = ` +exports[`Storyshots Bierzo Wallet/Iovnames Without iovnames 1`] = `
@@ -6714,9 +7023,6 @@ exports[`Storyshots Bierzo Wallet/Components PageMenuColumn 1`] = `
-
- Addresses + Starnames
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ iovnames +
+
+
- -
- Transactions -
- - new - -
+ Transactions +
+
+
+ className="MuiBox-root MuiBox-root" + > +
+
+ Addresses +
+
+
-
-
- What is Lorem Ipsum? -
-

- - Lorem Ipsum - - is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. -

+
+
+ yourname*iov +
+
+
+
+ You have no iovnames +
+

+ With Neuma you can choose your easy to read human readable address. No more complicated cryptography when sending to friends. +

+
+
+ Choose Now +
+
-
`; -exports[`Storyshots Bierzo Wallet/Components/PageMenu With padding 1`] = ` +exports[`Storyshots Bierzo Wallet/Payment Confirmation 1`] = `
- Logo
-
-
-
- Balances -
-
+ Tick
-
-
-
+
+ Your transaction was successfully signed and sent to the network. +
-
-
- Addresses -
-
+ Transaction ID +
-
-
-
+
+ 0x2be250c978013e0b3af09916c421511a07fac45bce16cdd891b7001a150cde0e +
- -
- Transactions -
- - new - -
+ Copy
-
-
-
- Hi! -
+ + New Payment + + +
+
-
-
- What is Lorem Ipsum? -
-

- - Lorem Ipsum - - is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. -

-
`; -exports[`Storyshots Bierzo Wallet/Components/PageMenu Without padding 1`] = ` -
- Logo
-
- + +
-
-
-
-
-
+
+ Send tokens +
- Addresses + Amount
-
-
-
-
-
-
-
- -
- Transactions -
- - new - -
-
-
-
-
-
-
-
-
-
- Hi! -
- -
-
-
-
-
- What is Lorem Ipsum? -
-

- - Lorem Ipsum - - is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. -

-
-
-`; - -exports[`Storyshots Bierzo Wallet/Payment Confirmation 1`] = ` -
-
-
-
-
- Tick -
-
- Your transaction was successfully signed and sent to the network. -
-
-
- Transaction ID -
-
-
-
- 0x2be250c978013e0b3af09916c421511a07fac45bce16cdd891b7001a150cde0e -
-
- Copy -
-
-
-
-
-
- -
-
- -
-
-
-
-`; - -exports[`Storyshots Bierzo Wallet/Payment No balance 1`] = ` -
-
-
-
-
-
- -
-
- Send tokens -
-
-
- Amount -
-
-
- +
+
+ +
+
+
+
+ +`; + +exports[`Storyshots Bierzo Wallet/Registration confirmation Registration confirmation 1`] = ` +
+
+
+
+
+ Tick +
+
+ Your registration request was successfully signed and sent to the network. +
+
+
+ Transaction ID +
+
+
+
+ 0x2be250c978013e0b3af09916c421511a07fac45bce16cdd891b7001a150cde0e +
+
+ Copy +
+
+
+
+
+
+ +
+
+
+
+`; + +exports[`Storyshots Bierzo Wallet/Starnames With starnames 1`] = ` +
+
+ Logo +
+
+
+
+
+
+ Balances +
+
+
+
+
+
+
+
+ Starnames +
+
+
+
+
+
+
+
+ iovnames +
+
+
+
+
+
+
+
+ Transactions +
+
+
+
+
+
+
+
+ Addresses +
+
+
+
+
+
+
+
+
+ Hi! +
+ +
+
+
+
+
+
+
+
- - Register - - -
-
-
+
+
+ Register your starname +
+

+ A starname is your universal username for the blockchain world. It enables you to receive crypto-currencies or to log in to blockchain applications in a seamless way. Transferring value becomes fast an easy. +

+
+
- - Cancel - - + Register Now +
- +
`; -exports[`Storyshots Bierzo Wallet/Registration confirmation Registration confirmation 1`] = ` +exports[`Storyshots Bierzo Wallet/Starnames Without starnames 1`] = `
+ Logo
+
- Tick +
+
+ Balances +
+
-
+
+
- Your registration request was successfully signed and sent to the network. -
+
+
+ Starnames +
+
+
+
+
-
- Transaction ID -
+
+ iovnames +
+
+
+
-
- 0x2be250c978013e0b3af09916c421511a07fac45bce16cdd891b7001a150cde0e -
+
+ Transactions +
+
+
+
+
+
- Copy +
+ Addresses +
+
+
+ Hi! +
+
+
+
+
+
+
+ *yourstarname +
+
+
+
+ Register your starname +
+

+ A starname is your universal username for the blockchain world. It enables you to receive crypto-currencies or to log in to blockchain applications in a seamless way. Transferring value becomes fast an easy. +

+
+
+ Register Now +
+
+
+
+
`;