diff --git a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/project.pbxproj b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/project.pbxproj index baf78f85ac..aef62a414a 100644 --- a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/project.pbxproj +++ b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/project.pbxproj @@ -7,6 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + 2163D6352BEAB577009689B1 /* SignInScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B978CD291C9C35005B465D /* SignInScreen.swift */; }; + 2163D6362BEAB577009689B1 /* UITestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B978CB291C9C07005B465D /* UITestCase.swift */; }; + 2163D6372BEAB577009689B1 /* HostedUISignInTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B41080F7291AD4D600297354 /* HostedUISignInTests.swift */; }; + 2163D6382BEAB577009689B1 /* SignUpScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B978CF291CA085005B465D /* SignUpScreen.swift */; }; + 2163D6392BEAB577009689B1 /* AuthenticatedScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B978D3291DB1D1005B465D /* AuthenticatedScreen.swift */; }; B41080ED291AD02500297354 /* Amplify in Frameworks */ = {isa = PBXBuildFile; productRef = B41080EC291AD02500297354 /* Amplify */; }; B41080EF291AD02500297354 /* AWSCognitoAuthPlugin in Frameworks */ = {isa = PBXBuildFile; productRef = B41080EE291AD02500297354 /* AWSCognitoAuthPlugin */; }; B41080F5291AD10700297354 /* ConfigurationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B41080F4291AD10700297354 /* ConfigurationHelper.swift */; }; @@ -26,6 +31,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 2163D6332BEAB577009689B1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B4EB96A0291ACF4400B73755 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B4EB96A7291ACF4400B73755; + remoteInfo = AuthHostedUIApp; + }; B41080E4291ACF7E00297354 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B4EB96A0291ACF4400B73755 /* Project object */; @@ -36,6 +48,9 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 2163D62F2BEAADD0009689B1 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 2163D63F2BEAB577009689B1 /* AuthHostedUIAppGen2UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AuthHostedUIAppGen2UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 2163D6402BEAB5B4009689B1 /* AuthHostedUIAppGen2UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = AuthHostedUIAppGen2UITests.xctestplan; sourceTree = ""; }; 21D41D1A2BC728190019D811 /* AuthHostedUIGen2App.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = AuthHostedUIGen2App.xctestplan; sourceTree = ""; }; B41080DE291ACF7E00297354 /* AuthHostedUIAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AuthHostedUIAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; B41080EA291ACFDB00297354 /* amplify-swift */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "amplify-swift"; path = ../../../..; sourceTree = ""; }; @@ -58,6 +73,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 2163D63A2BEAB577009689B1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; B41080DB291ACF7E00297354 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -80,6 +102,7 @@ B41080DF291ACF7E00297354 /* AuthHostedUIAppUITests */ = { isa = PBXGroup; children = ( + 2163D6402BEAB5B4009689B1 /* AuthHostedUIAppGen2UITests.xctestplan */, B4B978CB291C9C07005B465D /* UITestCase.swift */, B4B978CA291C9BE5005B465D /* Screen */, B41080F6291AD4C200297354 /* AuthenticationTest */, @@ -155,6 +178,7 @@ children = ( B4EB96A8291ACF4400B73755 /* AuthHostedUIApp.app */, B41080DE291ACF7E00297354 /* AuthHostedUIAppUITests.xctest */, + 2163D63F2BEAB577009689B1 /* AuthHostedUIAppGen2UITests.xctest */, ); name = Products; sourceTree = ""; @@ -170,6 +194,7 @@ B4EB96AD291ACF4400B73755 /* ContentView.swift */, B4EB96AF291ACF4600B73755 /* Assets.xcassets */, B4EB96B1291ACF4600B73755 /* Preview Content */, + 2163D62F2BEAADD0009689B1 /* README.md */, ); path = AuthHostedUIApp; sourceTree = ""; @@ -185,6 +210,24 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 2163D6312BEAB577009689B1 /* AuthHostedUIAppGen2UITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2163D63C2BEAB577009689B1 /* Build configuration list for PBXNativeTarget "AuthHostedUIAppGen2UITests" */; + buildPhases = ( + 2163D6342BEAB577009689B1 /* Sources */, + 2163D63A2BEAB577009689B1 /* Frameworks */, + 2163D63B2BEAB577009689B1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2163D6322BEAB577009689B1 /* PBXTargetDependency */, + ); + name = AuthHostedUIAppGen2UITests; + productName = AuthHostedUIAppUITests; + productReference = 2163D63F2BEAB577009689B1 /* AuthHostedUIAppGen2UITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; B41080DD291ACF7E00297354 /* AuthHostedUIAppUITests */ = { isa = PBXNativeTarget; buildConfigurationList = B41080E8291ACF7E00297354 /* Build configuration list for PBXNativeTarget "AuthHostedUIAppUITests" */; @@ -259,11 +302,19 @@ targets = ( B4EB96A7291ACF4400B73755 /* AuthHostedUIApp */, B41080DD291ACF7E00297354 /* AuthHostedUIAppUITests */, + 2163D6312BEAB577009689B1 /* AuthHostedUIAppGen2UITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 2163D63B2BEAB577009689B1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; B41080DC291ACF7E00297354 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -304,6 +355,18 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 2163D6342BEAB577009689B1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2163D6352BEAB577009689B1 /* SignInScreen.swift in Sources */, + 2163D6362BEAB577009689B1 /* UITestCase.swift in Sources */, + 2163D6372BEAB577009689B1 /* HostedUISignInTests.swift in Sources */, + 2163D6382BEAB577009689B1 /* SignUpScreen.swift in Sources */, + 2163D6392BEAB577009689B1 /* AuthenticatedScreen.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; B41080DA291ACF7E00297354 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -333,6 +396,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 2163D6322BEAB577009689B1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B4EB96A7291ACF4400B73755 /* AuthHostedUIApp */; + targetProxy = 2163D6332BEAB577009689B1 /* PBXContainerItemProxy */; + }; B41080E5291ACF7E00297354 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B4EB96A7291ACF4400B73755 /* AuthHostedUIApp */; @@ -341,6 +409,38 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 2163D63D2BEAB577009689B1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.amazon.AuthHostedUIAppUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = AuthHostedUIApp; + }; + name = Debug; + }; + 2163D63E2BEAB577009689B1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.amazon.AuthHostedUIAppUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = AuthHostedUIApp; + }; + name = Release; + }; B41080E6291ACF7E00297354 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -548,6 +648,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 2163D63C2BEAB577009689B1 /* Build configuration list for PBXNativeTarget "AuthHostedUIAppGen2UITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2163D63D2BEAB577009689B1 /* Debug */, + 2163D63E2BEAB577009689B1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; B41080E8291ACF7E00297354 /* Build configuration list for PBXNativeTarget "AuthHostedUIAppUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/xcshareddata/xcschemes/AuthHostedUIAppGen2UITests.xcscheme b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/xcshareddata/xcschemes/AuthHostedUIAppGen2UITests.xcscheme new file mode 100644 index 0000000000..43d4a971dd --- /dev/null +++ b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/xcshareddata/xcschemes/AuthHostedUIAppGen2UITests.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/xcshareddata/xcschemes/AuthHostedUIAppUITests.xcscheme b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/xcshareddata/xcschemes/AuthHostedUIAppUITests.xcscheme new file mode 100644 index 0000000000..b981a0f4db --- /dev/null +++ b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp.xcodeproj/xcshareddata/xcschemes/AuthHostedUIAppUITests.xcscheme @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp/README.md b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp/README.md new file mode 100644 index 0000000000..41be62504e --- /dev/null +++ b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIApp/README.md @@ -0,0 +1,170 @@ +# Auth + +## Schema: AuthHostedUIApp + +The following steps demonstrate how to setup the integration tests for auth plugin using Amplify CLI (Gen1). The steps were ran with version 12.10.3. + +1. Run `amplify init` and then `amplify add auth` + +- enable HostedUI +- add sign in redirect URLs for "myapp://" +- add pre-sign up lambda to auto confirm the user + +``` +What do you want to do? `Walkthrough all the auth configurations` + Select the authentication/authorization services that you want to use: `User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage features for images or other content, Analytics, and more)` + Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) `No` + Do you want to enable 3rd party authentication providers in your identity pool? `N`o + Do you want to add User Pool Groups? `No` + Do you want to add an admin queries API? `No` + Multifactor authentication (MFA) user login options: `OFF` + Email based user registration/forgot password: `Enabled (Requires per-user email entry at registration)` + Specify an email verification subject: `Your verification code` + Specify an email verification message: `Your verification code is {####}` + Do you want to override the default password policy for this User Pool? `No` + Specify the app's refresh token expiration period (in days): `30` + Do you want to specify the user attributes this app can read and write? `No` + Do you want to enable any of the following capabilities? + Do you want to use an OAuth flow? `Yes` + What domain name prefix do you want to use? `authintegbf03a97b-xxxx` + Enter your redirect signin URI: `myapp://` +? Do you want to add another redirect signin URI `No` + Enter your redirect signout URI: `myapp://` +? Do you want to add another redirect signout URI `No` + Select the OAuth scopes enabled for this project. `Phone, Email, OpenID, Profile, aws.cognito.signin.user.admin` + Select the identity providers you want to configure for your user pool: +? Do you want to configure Lambda Triggers for Cognito? `Yes` +? Which triggers do you want to enable for Cognito `Pre Sign-up` +? What functionality do you want to use for Pre Sign-up `Create your own module` +``` + +Pre Sign-up code +``` +exports.handler = async (event, context) => { + + event.response.autoConfirmUser = true; + return event; +}; +``` + +3. `amplify push` to provision the backend + +4. Copy the `amplifyconfiguration.json` file over to the test directory as `AWSCognitoAuthPluginHostedUIIntegrationTests-amplifyconfiguration.json`. The tests will automatically pick this file up. Create the directories in this path first if it currently doesn't exist. + +``` +cp amplifyconfiguration.json ~/.aws-amplify/amplify-ios/testconfiguration/AWSCognitoAuthPluginHostedUIIntegrationTests-amplifyconfiguration.json +``` + +## Schema: AuthHostedUIAppGen2 + +The following steps demonstrate how to setup the integration tests for auth plugin using Amplify CLI (Gen2). + +### Set-up + +At the time this was written, it follows the steps from here https://docs.amplify.aws/gen2/deploy-and-host/fullstack-branching/mono-and-multi-repos/ + +1. From a new folder, run `npm create amplify@beta`. This uses the following versions of the Amplify CLI, see `package.json` file below. + +```json +{ + ... + "devDependencies": { + "@aws-amplify/backend": "^0.15.0", + "@aws-amplify/backend-cli": "^0.15.0", + "aws-cdk": "^2.139.0", + "aws-cdk-lib": "^2.139.0", + "constructs": "^10.3.0", + "esbuild": "^0.20.2", + "tsx": "^4.7.3", + "typescript": "^5.4.5" + }, + "dependencies": { + "aws-amplify": "^6.2.0" + }, +} +``` + +2. Update `amplify/auth/resource.ts`. The resulting file should look like this + +```ts +import { defineAuth, defineFunction } from '@aws-amplify/backend'; + +/** + * Define and configure your auth resource + * @see https://docs.amplify.aws/gen2/build-a-backend/auth + */ +export const auth = defineAuth({ + loginWith: { + email: true, + externalProviders: { + callbackUrls: ["myapp://"], + logoutUrls: ["myapp://"], + } + }, + triggers: { + // configure a trigger to point to a function definition + preSignUp: defineFunction({ + entry: './pre-sign-up-handler.ts' + }) + } +}); +``` + +Add `amplify/auth/pre-sign-up-handler.ts` with the following: + +```ts +import type { PreSignUpTriggerHandler } from 'aws-lambda'; + +export const handler: PreSignUpTriggerHandler = async (event) => { + // your code here + event.response.autoConfirmUser = true + return event; +}; +``` + +3. Update `backend.ts` + +```ts +import { defineBackend } from '@aws-amplify/backend'; +import { auth } from './auth/resource'; + +const backend = defineBackend({ + auth +}); +``` + +4. Deploy the backend with npx amplify sandbox + +For example, this deploys to a sandbox env and generates the amplify_outputs.json file. + +``` +npx amplify sandbox --config-out-dir ./config --profile [PROFILE] +``` + +5. Copy the `amplify_outputs.json` file over to the test directory as `AWSCognitoAuthPluginHostedUIIntegrationTests-amplify_outputs.json`. The tests will automatically pick this file up. Create the directories in this path first if it currently doesn't exist. + +``` +cp amplify_outputs.json ~/.aws-amplify/amplify-ios/testconfiguration/AWSCognitoAuthPluginHostedUIIntegrationTests-amplify_outputs.json +``` + +### Deploying from a branch (Optional) + +If you want to be able utilize Git commits for deployments + +1. Commit and push the files to a git repository. + +2. Navigate to the AWS Amplify console (https://us-east-1.console.aws.amazon.com/amplify/home?region=us-east-1#/) + +3. Click on "Try Amplify Gen 2" button. + +4. Choose "Option 2: Start with an existing app", and choose Github, and press Next. + +5. Find the repository and branch, and click Next + +6. Click "Save and deploy" and wait for deployment to finish. + +7. Generate the `amplify_outputs.json` configuration file + +``` +npx amplify generate outputs --branch main --app-id [APP_ID] --profile [AWS_PROFILE] +``` diff --git a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/AuthHostedUIAppGen2UITests.xctestplan b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/AuthHostedUIAppGen2UITests.xctestplan new file mode 100644 index 0000000000..d8bfefa969 --- /dev/null +++ b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/AuthHostedUIAppGen2UITests.xctestplan @@ -0,0 +1,28 @@ +{ + "configurations" : [ + { + "id" : "E36588F7-6C54-4EB4-BDF6-DFE09B98BAF6", + "name" : "Test Scheme Action", + "options" : { + + } + } + ], + "defaultOptions" : { + "commandLineArgumentEntries" : [ + { + "argument" : "GEN2" + } + ] + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:AuthHostedUIApp.xcodeproj", + "identifier" : "2163D6312BEAB577009689B1", + "name" : "AuthHostedUIAppGen2UITests" + } + } + ], + "version" : 1 +} diff --git a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/AuthenticationTest/HostedUISignInTests.swift b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/AuthenticationTest/HostedUISignInTests.swift index 3c9004a220..8bfc88e1e0 100644 --- a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/AuthenticationTest/HostedUISignInTests.swift +++ b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/AuthenticationTest/HostedUISignInTests.swift @@ -12,7 +12,7 @@ class HostedUISignInTests: UITestCase { func testSignInSuccess() throws { let username = "hostedUI-\(UUID().uuidString)@amazon.com" - let password = "P123@\(UUID().uuidString)" + let password = "Pp123@\(UUID().uuidString)" let signInScreen = SignInScreen(app: app) let signUpScreen = signInScreen.gotoSignUpView() _ = signUpScreen @@ -31,7 +31,7 @@ class HostedUISignInTests: UITestCase { func testSignInWithoutPresentationAnchorSuccess() throws { let username = "hostedUI-\(UUID().uuidString)@amazon.com" - let password = "P123@\(UUID().uuidString)" + let password = "Pp123@\(UUID().uuidString)" let signInScreen = SignInScreen(app: app) let signUpScreen = signInScreen.gotoSignUpView() _ = signUpScreen diff --git a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/Screen/SignInScreen.swift b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/Screen/SignInScreen.swift index 0b9224bf40..16d8a61205 100644 --- a/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/Screen/SignInScreen.swift +++ b/AmplifyPlugins/Auth/Tests/AuthHostedUIApp/AuthHostedUIAppUITests/Screen/SignInScreen.swift @@ -46,9 +46,9 @@ struct SignInScreen: Screen { } func signIn(username: String, password: String) -> Self { - _ = app.webViews.textFields["Username"].waitForExistence(timeout: 60) - app.webViews.textFields["Username"].tap() - app.webViews.textFields["Username"].typeText(username) + _ = app.webViews.textFields["Email Email"].waitForExistence(timeout: 60) + app.webViews.textFields["Email Email"].tap() + app.webViews.textFields["Email Email"].typeText(username) app.webViews.secureTextFields["Password"].tap() app.webViews.secureTextFields["Password"].typeText(password)