Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/web3authcoresdk' into seedless-n…
Browse files Browse the repository at this point in the history
…ew-config
  • Loading branch information
usame-algan committed Nov 3, 2023
2 parents 7cbb240 + c81b9fb commit ab9fdc7
Show file tree
Hide file tree
Showing 13 changed files with 217 additions and 86 deletions.
18 changes: 11 additions & 7 deletions cypress/e2e/pages/create_wallet.pages.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as constants from '../../support/constants'

const welcomeLoginScreen = '[data-testid="welcome-login"]'
const expandMoreIcon = 'svg[data-testid="ExpandMoreIcon"]'
const nameInput = 'input[name="name"]'
const selectNetworkBtn = '[data-cy="create-safe-select-network"]'
const ownerInput = 'input[name^="owners"][name$="name"]'
Expand All @@ -12,11 +14,11 @@ const connectWalletBtn = 'Connect wallet'

const changeNetworkWarningStr = 'Change your wallet network'
const safeAccountSetupStr = 'Safe Account setup'
const policy1_2 = '1/2 policy'
const policy1_2 = '1/1 policy'
export const walletName = 'test1-sepolia-safe'
export const defaltSepoliaPlaceholder = 'sepolia-safe'
export const defaltSepoliaPlaceholder = 'Sepolia Safe'

export function verifyPolicy1_2() {
export function verifyPolicy1_1() {
cy.contains(policy1_2).should('exist')
// TOD: Need data-cy for containers
}
Expand Down Expand Up @@ -50,8 +52,10 @@ export function clickOnCreateNewSafeBtn() {
cy.get(createNewSafeBtn).click().wait(1000)
}

export function clickOnConnectWalletAndCreateBtn() {
cy.contains('[data-testid="welcome-login"]', connectWalletBtn).click().wait(1000)
export function clickOnConnectWalletBtn() {
cy.get(welcomeLoginScreen).within(() => {
cy.get('button').contains(connectWalletBtn).should('be.visible').should('be.enabled').click().wait(1000)
})
}

export function typeWalletName(name) {
Expand All @@ -64,7 +68,7 @@ export function clearWalletName() {

export function selectNetwork(network, regex = false) {
cy.wait(1000)
cy.get(selectNetworkBtn).should('be.visible').click()
cy.get(expandMoreIcon).eq(1).parents('div').eq(1).click()
cy.wait(1000)
cy.get('li').contains(network).click()
cy.get('body').click()
Expand Down Expand Up @@ -100,7 +104,7 @@ export function typeOwnerAddress(address, index, clearOnly = false) {
}

export function clickOnAddNewOwnerBtn() {
cy.contains('button', 'Add new owner').click()
cy.contains('button', 'Add new owner').click().wait(700)
}

export function addNewOwner(name, address, index) {
Expand Down
7 changes: 4 additions & 3 deletions cypress/e2e/pages/owners.pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const thresholdDropdown = 'div[aria-haspopup="listbox"]'
const thresholdOption = 'li[role="option"]'
const existingOwnerAddressInput = (index) => `input[name="owners.${index}.address"]`
const existingOwnerNameInput = (index) => `input[name="owners.${index}.name"]`
const singleOwnerNameInput = 'input[name="name"]'

const disconnectBtnStr = 'Disconnect'
const notConnectedStatus = 'Connect'
Expand Down Expand Up @@ -57,9 +58,9 @@ export function verifyExistingOwnerName(index, name) {
cy.get(existingOwnerNameInput(index)).should('have.value', name)
}

export function typeExistingOwnerName(index, name) {
cy.get(existingOwnerNameInput(index)).clear().type(name)
main.verifyInputValue(existingOwnerNameInput(index), name)
export function typeExistingOwnerName(name) {
cy.get(singleOwnerNameInput).clear().type(name)
main.verifyInputValue(singleOwnerNameInput, name)
}

export function verifyOwnerDeletionWindowDisplayed() {
Expand Down
35 changes: 24 additions & 11 deletions cypress/e2e/smoke/create_safe_simple.cy.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import * as constants from '../../support/constants'
import * as main from '../../e2e/pages/main.page'
import * as createwallet from '../pages/create_wallet.pages'

import * as owner from '../pages/owners.pages'

describe('Safe creation tests', () => {
before(() => {
cy.visit(constants.welcomeUrl + '?chain=sep')
})
beforeEach(() => {
cy.visit(constants.welcomeUrl + '?chain=sep')
cy.clearLocalStorage()
main.acceptCookies()
})
Expand All @@ -17,15 +14,14 @@ describe('Safe creation tests', () => {
createwallet.clickOnCreateNewSafeBtn()
owner.clickOnWalletExpandMoreIcon()
owner.clickOnDisconnectBtn()
cy.url().should('include', constants.welcomeUrl)
createwallet.clickOnConnectWalletAndCreateBtn()
createwallet.clickOnConnectWalletBtn()
createwallet.connectWallet()
cy.url().should('include', constants.createNewSafeSepoliaUrl)
})

it('Verify Next button is disabled until switching to network is done [C56102]', () => {
owner.waitForConnectionStatus()
createwallet.selectNetwork(constants.networks.ethereum)
createwallet.clickOnCreateNewSafeBtn()
createwallet.checkNetworkChangeWarningMsg()
createwallet.verifyNextBtnIsDisabled()
createwallet.selectNetwork(constants.networks.sepolia)
Expand All @@ -34,42 +30,50 @@ describe('Safe creation tests', () => {

it('Verify that a new Wallet has default name related to the selected network [C56099]', () => {
owner.waitForConnectionStatus()
createwallet.clickOnCreateNewSafeBtn()
createwallet.verifyDefaultWalletName(createwallet.defaltSepoliaPlaceholder)
})

it('Verify error message is displayed if wallet name input exceeds 50 characters [C56098]', () => {
owner.waitForConnectionStatus()
createwallet.clickOnCreateNewSafeBtn()
createwallet.typeWalletName(main.generateRandomString(51))
owner.verifyErrorMsgInvalidAddress(constants.addressBookErrrMsg.exceedChars)
createwallet.clearWalletName()
})

it('Verify there is no error message is displayed if wallet name input contains less than 50 characters [C56100]', () => {
owner.waitForConnectionStatus()
createwallet.clickOnCreateNewSafeBtn()
createwallet.typeWalletName(main.generateRandomString(50))
owner.verifyValidWalletName(constants.addressBookErrrMsg.exceedChars)
})

it('Verify current connected account is shown as default owner [C56091]', () => {
owner.waitForConnectionStatus()
createwallet.clickOnCreateNewSafeBtn()
owner.clickOnNextBtn()
owner.verifyExistingOwnerAddress(0, constants.DEFAULT_OWNER_ADDRESS)
})

it('Verify error message is displayed if owner name input exceeds 50 characters [C56092]', () => {
owner.waitForConnectionStatus()
owner.typeExistingOwnerName(0, main.generateRandomString(51))
createwallet.clickOnCreateNewSafeBtn()
owner.typeExistingOwnerName(main.generateRandomString(51))
owner.verifyErrorMsgInvalidAddress(constants.addressBookErrrMsg.exceedChars)
})

it('Verify there is no error message is displayed if owner name input contains less than 50 characters [C56093]', () => {
owner.waitForConnectionStatus()
owner.typeExistingOwnerName(0, main.generateRandomString(50))
createwallet.clickOnCreateNewSafeBtn()
owner.typeExistingOwnerName(main.generateRandomString(50))
owner.verifyValidWalletName(constants.addressBookErrrMsg.exceedChars)
})

it('Verify Add and Remove Owner Row works as expected [C56094]', () => {
owner.waitForConnectionStatus()
createwallet.clickOnCreateNewSafeBtn()
owner.clickOnNextBtn()
createwallet.clickOnAddNewOwnerBtn()
owner.verifyNumberOfOwners(2)
owner.verifyExistingOwnerAddress(1, '')
Expand All @@ -82,6 +86,9 @@ describe('Safe creation tests', () => {

it('Verify Threshold Setup [C56096]', () => {
owner.waitForConnectionStatus()
createwallet.clickOnCreateNewSafeBtn()
owner.clickOnNextBtn()
createwallet.clickOnAddNewOwnerBtn()
createwallet.clickOnAddNewOwnerBtn()
owner.verifyNumberOfOwners(3)
createwallet.clickOnAddNewOwnerBtn()
Expand All @@ -98,6 +105,9 @@ describe('Safe creation tests', () => {
it('Verify data persistence [C56103]', () => {
const ownerName = 'David'
owner.waitForConnectionStatus()
createwallet.clickOnCreateNewSafeBtn()
owner.clickOnNextBtn()
createwallet.clickOnAddNewOwnerBtn()
createwallet.typeOwnerName(ownerName, 1)
createwallet.typeOwnerAddress(constants.SEPOLIA_OWNER_2, 1)
owner.clickOnBackBtn()
Expand Down Expand Up @@ -127,12 +137,15 @@ describe('Safe creation tests', () => {

it('Verify tip is displayed on right side for threshold 1/1 [C56097]', () => {
owner.waitForConnectionStatus()
owner.clickOnBackBtn()
createwallet.verifyPolicy1_2()
createwallet.clickOnCreateNewSafeBtn()
owner.clickOnNextBtn()
createwallet.verifyPolicy1_1()
})

it('Verify address input validation rules [C56095]', () => {
owner.waitForConnectionStatus()
createwallet.clickOnCreateNewSafeBtn()
owner.clickOnNextBtn()
createwallet.clickOnAddNewOwnerBtn()
createwallet.typeOwnerAddress(main.generateRandomString(10), 1)
owner.verifyErrorMsgInvalidAddress(constants.addressBookErrrMsg.invalidFormat)
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/ConnectWallet/WalletDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const WalletDetails = ({ onConnect }: { onConnect: () => void }): ReactElement =
</Typography>
</Divider>

<SocialSigner />
<SocialSigner onRequirePassword={onConnect} />
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ describe('SocialSignerLogin', () => {
/>,
)

expect(
result.getByText('Currently only supported on Goerli. More network support coming soon.'),
).toBeInTheDocument()
expect(result.getByText('Currently only supported on Goerli')).toBeInTheDocument()
expect(await result.findByRole('button')).toBeDisabled()
})

Expand Down
82 changes: 46 additions & 36 deletions src/components/common/SocialSigner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Button, SvgIcon, Typography } from '@mui/material'
import { Box, Button, SvgIcon, Tooltip, Typography } from '@mui/material'
import { useCallback, useContext, useMemo, useState } from 'react'
import { PasswordRecovery } from '@/components/common/SocialSigner/PasswordRecovery'
import GoogleLogo from '@/public/images/welcome/logo-google.svg'
Expand All @@ -18,6 +18,8 @@ import { TxModalContext } from '@/components/tx-flow'
import { COREKIT_STATUS } from '@web3auth/mpc-core-kit'
import useSocialWallet from '@/hooks/wallets/mpc/useSocialWallet'
import madProps from '@/utils/mad-props'
import { asError } from '@/services/exceptions/utils'
import ErrorMessage from '@/components/tx/ErrorMessage'

export const _getSupportedChains = (chains: ChainInfo[]) => {
return chains
Expand All @@ -44,6 +46,7 @@ type SocialSignerLoginProps = {
supportedChains: ReturnType<typeof useGetSupportedChains>
isMPCLoginEnabled: ReturnType<typeof useIsSocialWalletEnabled>
onLogin?: () => void
onRequirePassword?: () => void
}

export const SocialSigner = ({
Expand All @@ -52,8 +55,10 @@ export const SocialSigner = ({
supportedChains,
isMPCLoginEnabled,
onLogin,
onRequirePassword,
}: SocialSignerLoginProps) => {
const [loginPending, setLoginPending] = useState<boolean>(false)
const [loginError, setLoginError] = useState<string | undefined>(undefined)
const { setTxFlow } = useContext(TxModalContext)
const userInfo = socialWalletService?.getUserInfo()
const isDisabled = loginPending || !isMPCLoginEnabled
Expand All @@ -76,39 +81,39 @@ export const SocialSigner = ({
if (!socialWalletService) return

setLoginPending(true)
setLoginError(undefined)
try {
const status = await socialWalletService.loginAndCreate()

const status = await socialWalletService.loginAndCreate()
if (status === COREKIT_STATUS.LOGGED_IN) {
onLogin?.()
setLoginPending(false)
return
}

if (status === COREKIT_STATUS.LOGGED_IN) {
onLogin?.()
setLoginPending(false)
return
}
if (status === COREKIT_STATUS.REQUIRED_SHARE) {
onRequirePassword?.()

if (status === COREKIT_STATUS.REQUIRED_SHARE) {
setTxFlow(
<PasswordRecovery
recoverFactorWithPassword={recoverPassword}
onSuccess={() => {
onLogin?.()
setLoginPending(false)
}}
/>,
() => {},
false,
)
return
setTxFlow(
<PasswordRecovery recoverFactorWithPassword={recoverPassword} onSuccess={onLogin} />,
() => setLoginPending(false),
false,
)
return
}
} catch (err) {
const error = asError(err)
setLoginError(error.message)
} finally {
setLoginPending(false)
}

// TODO: Show error if login fails
setLoginPending(false)
}

const isSocialLogin = isSocialLoginWallet(wallet?.label)

return (
<>
<Box sx={{ width: '100%' }}>
<Box display="flex" flexDirection="column" gap={2} sx={{ width: '100%' }}>
{isSocialLogin && userInfo ? (
<Track {...CREATE_SAFE_EVENTS.CONTINUE_TO_CREATION}>
<Button
Expand Down Expand Up @@ -152,21 +157,26 @@ export const SocialSigner = ({
</Button>
</Track>
)}
{loginError && <ErrorMessage className={css.loginError}>{loginError}</ErrorMessage>}
</Box>

{!isMPCLoginEnabled && (
<Typography variant="body2" color="text.secondary" display="flex" gap={1} alignItems="center">
<SvgIcon
component={InfoIcon}
inheritViewBox
color="border"
fontSize="small"
sx={{
verticalAlign: 'middle',
ml: 0.5,
}}
/>
Currently only supported on {supportedChains.join(', ')}. More network support coming soon.
<Typography variant="body2" color="text.secondary" display="flex" gap={1}>
<Tooltip title="More network support coming soon." arrow placement="top">
<span>
<SvgIcon
component={InfoIcon}
inheritViewBox
color="border"
fontSize="small"
sx={{
verticalAlign: 'middle',
ml: 0.5,
}}
/>
</span>
</Tooltip>
<span>Currently only supported on {supportedChains.join(supportedChains.length === 2 ? ' and ' : ', ')}</span>
</Typography>
)}
</>
Expand Down
13 changes: 8 additions & 5 deletions src/components/new-safe/create/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { type ReactElement, useMemo, useState } from 'react'
import ExternalLink from '@/components/common/ExternalLink'
import { HelpCenterArticle } from '@/config/constants'
import { isSocialLoginWallet } from '@/services/mpc/SocialLoginModule'
import { useMnemonicSafeName } from '@/hooks/useMnemonicName'

export type NewSafeFormData = {
name: string
Expand Down Expand Up @@ -157,17 +158,19 @@ const CreateSafe = () => {

const staticHint = useMemo(() => staticHints[activeStep], [activeStep])

const mnemonicSafeName = useMnemonicSafeName()

// Jump to review screen when using social login
const isSocialLogin = isSocialLoginWallet(wallet?.label)
const initialStep = isSocialLogin ? 2 : 0

const initialData: NewSafeFormData = {
name: '',
name: isSocialLogin ? mnemonicSafeName : '',
owners: [defaultOwner],
threshold: 1,
saltNonce: Date.now(),
}

// Jump to review screen when using social login
const isSocialLogin = isSocialLoginWallet(wallet?.label)
const initialStep = isSocialLogin ? 2 : 0

const onClose = () => {
router.push(AppRoutes.welcome.index)
}
Expand Down
Loading

0 comments on commit ab9fdc7

Please sign in to comment.