diff --git a/.storybook/storybook.requires.js b/.storybook/storybook.requires.js
index 5ed706010c..2e3608a206 100644
--- a/.storybook/storybook.requires.js
+++ b/.storybook/storybook.requires.js
@@ -69,7 +69,7 @@ const getStories = () => {
"./app/screens/earns-screen/earns-sections.stories.tsx": require("../app/screens/earns-screen/earns-sections.stories.tsx"),
"./app/screens/earns-screen/section-completed.stories.tsx": require("../app/screens/earns-screen/section-completed.stories.tsx"),
"./app/screens/email-login-screen/email-login-flow.stories.tsx": require("../app/screens/email-login-screen/email-login-flow.stories.tsx"),
- "./app/screens/email-login-screen/email-login-validation.stories.tsx": require("../app/screens/email-login-screen/email-login-validation.stories.tsx"),
+ "./app/screens/email-login-screen/email-login-validate.stories.tsx": require("../app/screens/email-login-screen/email-login-validate.stories.tsx"),
"./app/screens/email-registration-screen/email-registration-initiate.stories.tsx": require("../app/screens/email-registration-screen/email-registration-initiate.stories.tsx"),
"./app/screens/email-registration-screen/email-registration-validate.stories.tsx": require("../app/screens/email-registration-screen/email-registration-validate.stories.tsx"),
"./app/screens/error-screen/error-screen.stories.tsx": require("../app/screens/error-screen/error-screen.stories.tsx"),
diff --git a/app/i18n/en/index.ts b/app/i18n/en/index.ts
index 8a7ba3c262..b8503a170b 100644
--- a/app/i18n/en/index.ts
+++ b/app/i18n/en/index.ts
@@ -429,7 +429,7 @@ const en: BaseTranslation = {
logInCreateAccount: "Log in / create account",
createAccount: "Create new account",
exploreWallet: "Explore wallet",
- loginBackInWith: "Login back in with",
+ logBackInWith: "Log back in with",
headline: "Wallet powered by Galoy",
startTrialAccount: "Start with a trial account",
iUnderstand: "I understand, continue",
@@ -796,13 +796,13 @@ const en: BaseTranslation = {
header: "To confirm your email address, enter the code we just sent you on {email: string}",
success: "Email {email: string} confirmed successfully",
},
- EmailLoginInputScreen: {
+ EmailLoginInitiateScreen: {
title: "Login via email",
header: "Enter your email address, and we'll send you an access code.",
invalidEmail: "Invalid email address. Are you sure you entered the right email?",
send: "Send code",
},
- EmailLoginValidationScreen: {
+ EmailLoginValidateScreen: {
title: "Code confirmation",
header: "If there is an account attached to {email: string}, you should have received 6 digits code to enter below.\n\nIf you are not receiving anything, it's probably either because this is not the right email, the email is in your spam folder.",
success: "Email {email: string} confirmed successfully",
diff --git a/app/i18n/i18n-types.ts b/app/i18n/i18n-types.ts
index 18ee1a8fb4..a0df62cbe6 100644
--- a/app/i18n/i18n-types.ts
+++ b/app/i18n/i18n-types.ts
@@ -1399,7 +1399,7 @@ type RootTranslation = {
/**
* Login back in with
*/
- loginBackInWith: string
+ logBackInWith: string
/**
* Wallet powered by Galoy
*/
@@ -2684,7 +2684,7 @@ type RootTranslation = {
*/
success: RequiredParams<'email'>
}
- EmailLoginInputScreen: {
+ EmailLoginInitiateScreen: {
/**
* Login via email
*/
@@ -2702,7 +2702,7 @@ type RootTranslation = {
*/
send: string
}
- EmailLoginValidationScreen: {
+ EmailLoginValidateScreen: {
/**
* Code confirmation
*/
@@ -4663,7 +4663,7 @@ export type TranslationFunctions = {
/**
* Login back in with
*/
- loginBackInWith: () => LocalizedString
+ logBackInWith: () => LocalizedString
/**
* Wallet powered by Galoy
*/
@@ -5901,7 +5901,7 @@ export type TranslationFunctions = {
*/
success: (arg: { email: string }) => LocalizedString
}
- EmailLoginInputScreen: {
+ EmailLoginInitiateScreen: {
/**
* Login via email
*/
@@ -5919,7 +5919,7 @@ export type TranslationFunctions = {
*/
send: () => LocalizedString
}
- EmailLoginValidationScreen: {
+ EmailLoginValidateScreen: {
/**
* Code confirmation
*/
diff --git a/app/navigation/root-navigator.tsx b/app/navigation/root-navigator.tsx
index 834d1aec0e..5d3c4af11f 100644
--- a/app/navigation/root-navigator.tsx
+++ b/app/navigation/root-navigator.tsx
@@ -62,8 +62,8 @@ import {
EmailRegistrationValidateScreen,
} from "@app/screens/email-registration-screen"
import {
- EmailLoginInputScreen,
- EmailLoginValidationScreen,
+ EmailLoginInitiateScreen,
+ EmailLoginValidateScreen,
} from "@app/screens/email-login-screen"
const useStyles = makeStyles(({ colors }) => ({
@@ -337,19 +337,19 @@ export const RootStack = () => {
}}
/>
diff --git a/app/navigation/stack-param-lists.ts b/app/navigation/stack-param-lists.ts
index 4492eccf23..3ed6b38653 100644
--- a/app/navigation/stack-param-lists.ts
+++ b/app/navigation/stack-param-lists.ts
@@ -79,8 +79,8 @@ export type RootStackParamList = {
transactionLimitsScreen: undefined
emailRegistrationInitiate: undefined
emailRegistrationValidate: { email: string; emailRegistrationId: string }
- emailLoginInput: undefined
- emailLoginValidation: { email: string; emailLoginId: string }
+ emailLoginInitiate: undefined
+ emailLoginValidate: { email: string; emailLoginId: string }
}
export type ContactStackParamList = {
diff --git a/app/screens/email-login-screen/email-login-flow.stories.tsx b/app/screens/email-login-screen/email-login-flow.stories.tsx
index 3ec4a08c59..39c687163a 100644
--- a/app/screens/email-login-screen/email-login-flow.stories.tsx
+++ b/app/screens/email-login-screen/email-login-flow.stories.tsx
@@ -7,7 +7,7 @@ import {
CaptchaRequestAuthCodeDocument,
UserEmailRegistrationInitiateDocument,
} from "../../graphql/generated"
-import { EmailLoginInputScreen } from "./email-login-input"
+import { EmailLoginInitiateScreen } from "./email-login-initiate"
const mocks = [
{
@@ -79,7 +79,7 @@ const mocks = [
export default {
title: "EmailLoginFlow",
- component: EmailLoginInputScreen,
+ component: EmailLoginInitiateScreen,
decorators: [
(Story) => (
@@ -89,4 +89,4 @@ export default {
],
}
-export const Default = () =>
+export const Default = () =>
diff --git a/app/screens/email-login-screen/email-login-input.tsx b/app/screens/email-login-screen/email-login-initiate.tsx
similarity index 87%
rename from app/screens/email-login-screen/email-login-input.tsx
rename to app/screens/email-login-screen/email-login-initiate.tsx
index 12326616e3..473b8f489e 100644
--- a/app/screens/email-login-screen/email-login-input.tsx
+++ b/app/screens/email-login-screen/email-login-initiate.tsx
@@ -11,8 +11,8 @@ import { View } from "react-native"
import validator from "validator"
import { Screen } from "../../components/screen"
import { useAppConfig } from "@app/hooks"
+import { testProps } from "@app/utils/testProps"
-const PLACEHOLDER_EMAIL = "hal@finney.org"
const useStyles = makeStyles(({ colors }) => ({
screenStyle: {
padding: 20,
@@ -47,7 +47,7 @@ const useStyles = makeStyles(({ colors }) => ({
},
}))
-export const EmailLoginInputScreen: React.FC = () => {
+export const EmailLoginInitiateScreen: React.FC = () => {
const styles = useStyles()
const {
appConfig: {
@@ -58,7 +58,7 @@ export const EmailLoginInputScreen: React.FC = () => {
const urlEmailCodeRequest = `${authUrl}/auth/email/code`
const navigation =
- useNavigation>()
+ useNavigation>()
const [emailInput, setEmailInput] = React.useState("")
const [errorMessage, setErrorMessage] = React.useState("")
@@ -73,7 +73,7 @@ export const EmailLoginInputScreen: React.FC = () => {
const submit = async () => {
if (!validator.isEmail(emailInput)) {
- setErrorMessage(LL.EmailLoginInputScreen.invalidEmail())
+ setErrorMessage(LL.EmailLoginInitiateScreen.invalidEmail())
return
}
@@ -92,7 +92,8 @@ export const EmailLoginInputScreen: React.FC = () => {
const emailLoginId = res.data.result
if (emailLoginId) {
- navigation.navigate("emailLoginValidation", { emailLoginId, email: emailInput })
+ console.log({ emailLoginId })
+ navigation.navigate("emailLoginValidate", { emailLoginId, email: emailInput })
} else {
console.warn("no flow returned")
}
@@ -124,13 +125,14 @@ export const EmailLoginInputScreen: React.FC = () => {
>
- {LL.EmailLoginInputScreen.header()}
+ {LL.EmailLoginInitiateScreen.header()}
{
(
@@ -26,6 +26,6 @@ export default {
),
],
-} as Meta
+} as Meta
-export const Main = () =>
+export const Main = () =>
diff --git a/app/screens/email-login-screen/email-login-validation.tsx b/app/screens/email-login-screen/email-login-validate.tsx
similarity index 91%
rename from app/screens/email-login-screen/email-login-validation.tsx
rename to app/screens/email-login-screen/email-login-validate.tsx
index 0a2af6a1de..e10b99c1a9 100644
--- a/app/screens/email-login-screen/email-login-validation.tsx
+++ b/app/screens/email-login-screen/email-login-validate.tsx
@@ -11,6 +11,7 @@ import { useCallback, useState } from "react"
import { ActivityIndicator, View } from "react-native"
import { Screen } from "../../components/screen"
import analytics from "@react-native-firebase/analytics"
+import { testProps } from "@app/utils/testProps"
const useStyles = makeStyles(({ colors }) => ({
screenStyle: {
@@ -50,17 +51,19 @@ const useStyles = makeStyles(({ colors }) => ({
},
}))
-type EmailLoginValidationScreenProps = {
- route: RouteProp
+type EmailLoginValidateScreenProps = {
+ route: RouteProp
}
-export const EmailLoginValidationScreen: React.FC = ({
+const placeholder = "000000"
+
+export const EmailLoginValidateScreen: React.FC = ({
route,
}) => {
const styles = useStyles()
const { colors } = useTheme()
const navigation =
- useNavigation>()
+ useNavigation>()
const [errorMessage, setErrorMessage] = React.useState("")
@@ -147,11 +150,12 @@ export const EmailLoginValidationScreen: React.FC
- {LL.EmailLoginValidationScreen.header({ email })}
+ {LL.EmailLoginValidateScreen.header({ email })}
{
const navigation =
@@ -76,7 +77,7 @@ export const GetStartedScreen: React.FC = () => {
createDeviceAccountEnabled: Boolean(appCheckToken),
})
- navigation.navigate("emailLoginInput")
+ navigation.navigate("emailLoginInitiate")
}
return (
@@ -110,14 +111,18 @@ export const GetStartedScreen: React.FC = () => {
/>
)}
- {LL.GetStartedScreen.loginBackInWith()}
+ {LL.GetStartedScreen.logBackInWith()}
{LL.common.phone()}
{LL.common.or()}
-
+
{LL.common.email()}
diff --git a/e2e/02-login-flow.e2e.spec.ts b/e2e/02-login-flow.e2e.spec.ts
index a88268b293..05b9a24a51 100644
--- a/e2e/02-login-flow.e2e.spec.ts
+++ b/e2e/02-login-flow.e2e.spec.ts
@@ -1,10 +1,10 @@
+import { sleep } from "../app/utils/sleep"
import { i18nObject } from "../app/i18n/i18n-util"
import { loadLocale } from "../app/i18n/i18n-util.sync"
import {
clickBackButton,
clickIcon,
clickOnSetting,
- waitTillOnHomeScreen,
waitTillSettingDisplayed,
userToken,
selector,
@@ -15,6 +15,7 @@ import {
waitTillButtonDisplayed,
getInbox,
getFirstEmail,
+ getSecondEmail,
} from "./utils"
describe("Login Flow", () => {
@@ -124,19 +125,56 @@ describe("Login Flow", () => {
await codeInput.waitForDisplayed({ timeout })
await codeInput.click()
await codeInput.setValue(code)
+
+ const okButton = await $(selector(LL.common.ok(), "Button"))
+ await okButton.waitForDisplayed({ timeout })
+ await okButton.click()
})
- it("clicks OK in alert dialog", async () => {
+ it("log out", async () => {
+ await clickOnSetting(LL.AccountScreen.logOutAndDeleteLocalData())
+
+ await sleep(1000)
+
+ const iUnderstandButton = await $(selector(LL.AccountScreen.IUnderstand(), "Button"))
+ await iUnderstandButton.waitForDisplayed({ timeout })
+ await iUnderstandButton.click()
+
+ await sleep(1000)
+
const okButton = await $(selector(LL.common.ok(), "Button"))
await okButton.waitForDisplayed({ timeout })
await okButton.click()
})
- it("navigates back to move home screen", async () => {
- await clickBackButton()
- await waitTillSettingDisplayed(LL.common.account())
+ it("log back in", async () => {
+ const emailLink = await $(selector("email-button", "Other"))
+ await emailLink.waitForDisplayed({ timeout })
+ await emailLink.click()
- await clickBackButton()
- await waitTillOnHomeScreen()
+ const emailInput = await $(
+ selector(LL.EmailRegistrationInitiateScreen.placeholder(), "Other", "[1]"),
+ )
+ await emailInput.waitForDisplayed({ timeout })
+ await emailInput.click()
+ await emailInput.setValue(email)
+ await clickButton(LL.EmailRegistrationInitiateScreen.send())
+ // i9TEikJakmv4@mailslurp.com
+ const emailRes = await getSecondEmail(inboxId)
+ if (!emailRes) throw new Error("No email response")
+
+ const { subject, body } = emailRes
+ expect(subject).toEqual("your code")
+
+ const regex = /\b\d{6}\b/
+ const match = body.match(regex)
+ if (!match) throw new Error("No code found in email body")
+ const code = match[0]
+
+ const placeholder = "000000"
+ const codeInput = await $(selector(placeholder, "Other", "[1]"))
+ await codeInput.waitForDisplayed({ timeout })
+ await codeInput.click()
+ await codeInput.setValue(code)
})
})
diff --git a/e2e/config/wdio.conf.js b/e2e/config/wdio.conf.js
index a327a46eb8..8bbfa22325 100644
--- a/e2e/config/wdio.conf.js
+++ b/e2e/config/wdio.conf.js
@@ -1,10 +1,12 @@
+/* eslint-disable */
+
const androidValueForAppiumInspector = {
"platformName": "Android",
"appium:deviceName": "generic_x86",
"appium:app": "./android/app/build/outputs/apk/debug/app-universal-debug.apk",
"appium:automationName": "UiAutomator2",
"appium:snapshotMaxDepth": 500,
- "appium:autoGrantPermissions": true,
+ "appium:autoGrantPermissions": false
}
const iOSValueForAppiumInspector = {
@@ -13,7 +15,7 @@ const iOSValueForAppiumInspector = {
"appium:bundleId": "io.galoy.bitcoinbeach",
"appium:automationName": "XCUITest",
"appium:snapshotMaxDepth": 500,
- "appium:autoAcceptAlerts": true,
+ "appium:autoAcceptAlerts": false
}
// value to copy to appium inspector
@@ -29,7 +31,7 @@ let capabilities = {
"./android/app/build/outputs/apk/debug/app-universal-debug.apk",
"appium:automationName": "UiAutomator2",
"appium:snapshotMaxDepth": 500,
- "appium:autoGrantPermissions": true,
+ "appium:autoGrantPermissions": false,
}
if (process.env.E2E_DEVICE === "ios") {
@@ -40,7 +42,7 @@ if (process.env.E2E_DEVICE === "ios") {
"appium:bundleId": "io.galoy.bitcoinbeach",
"appium:automationName": "XCUITest",
"appium:snapshotMaxDepth": 500,
- "appium:autoAcceptAlerts": true,
+ "appium:autoAcceptAlerts": false,
}
}
diff --git a/e2e/utils/email.sh b/e2e/utils/email.sh
new file mode 100644
index 0000000000..07f90ff3f9
--- /dev/null
+++ b/e2e/utils/email.sh
@@ -0,0 +1,6 @@
+```
+curl -s -X 'GET' \
+ "https://api.mailslurp.com/inboxes/$inboxId/emails" \
+ -H 'accept: */*' \
+ -H "x-api-key: $MAILSLURP_API_KEY"
+```
diff --git a/e2e/utils/email.ts b/e2e/utils/email.ts
index f0135b108f..0bdeac7161 100644
--- a/e2e/utils/email.ts
+++ b/e2e/utils/email.ts
@@ -16,14 +16,14 @@ const headers = {
export const getInbox = async () => {
const optionsCreateInbox = {
method: "POST",
- url: `https://api.mailslurp.com/inboxes?expiresIn=60000&useShortAddress=true`,
+ url: `https://api.mailslurp.com/inboxes?expiresIn=3600000&useShortAddress=true`,
headers,
}
try {
const { data } = await axios.request(optionsCreateInbox)
const { id, emailAddress } = data
- console.log({ id, emailAddress })
+ console.log({ inboxId: id, emailAddress })
return { id, emailAddress }
} catch (error) {
console.error(error)