diff --git a/cypress/components/app-card.ts b/cypress/components/app-card.ts
new file mode 100644
index 0000000000..ec4406c194
--- /dev/null
+++ b/cypress/components/app-card.ts
@@ -0,0 +1,10 @@
+export default {
+ actions: {
+ clickAppCardWithName(name: string) {
+ return cy.get(`div[data-test-app-name="${name}"]`).click()
+ },
+ clickAppCardSettingWithId(id: string) {
+ return cy.get(`div[data-test="app-settings_${id}"]`).click()
+ }
+ }
+}
diff --git a/cypress/components/app-detail-modal.ts b/cypress/components/app-detail-modal.ts
new file mode 100644
index 0000000000..d085eec519
--- /dev/null
+++ b/cypress/components/app-detail-modal.ts
@@ -0,0 +1,13 @@
+export default {
+ selectors: {
+ buttonInstallApp: 'button[data-test="detail-modal-install-button"]',
+ buttonUninstallApp: 'button[data-test="detail-modal-uninstall-button"]',
+ buttonEditDetail: 'button[data-test="detail-modal-edit-button"]',
+ buttonAgree: 'button[data-test="agree-btn"]',
+ buttonDisagree: 'button[data-test="disagree-btn"]',
+ buttonSuccess: 'button[data-test="installations-success-button"]',
+
+ divInstalled: 'div[data-test="detail-modal-installed"]',
+ divSuccessMessage: 'div[data-test="installations-success-message"]'
+ }
+}
diff --git a/cypress/components/client-welcome-modal.ts b/cypress/components/client-welcome-modal.ts
new file mode 100644
index 0000000000..7ce35e4bf8
--- /dev/null
+++ b/cypress/components/client-welcome-modal.ts
@@ -0,0 +1,5 @@
+export default {
+ selectors: {
+ buttonAceptWelcome: 'button[data-test="button-accept-welcome-message-modal"]'
+ }
+}
diff --git a/cypress/fixtures/routes.ts b/cypress/fixtures/routes.ts
index 58577ac748..d47cd53413 100644
--- a/cypress/fixtures/routes.ts
+++ b/cypress/fixtures/routes.ts
@@ -5,8 +5,14 @@ export default {
scopes: `${apiEndPoint}/scopes`,
appsOfDeveloper: `${apiEndPoint}/apps?developerId=**&PageNumber=**&PageSize=**`,
apps: `${apiEndPoint}/apps`,
+ approvals: `${apiEndPoint}/approvals`,
+ appDetail: `${apiEndPoint}/apps/**?clientId=**`,
+ installedApps: `${apiEndPoint}/apps?clientId=**&OnlyInstalled=**&PageNumber=**&PageSize=**&IsDirectApi=**`,
+ manageApps: `${apiEndPoint}/apps?clientId=**&OnlyInstalled=**&PageNumber=**&PageSize=**`,
developers: `${apiEndPoint}/developers`,
approveApp: `${apiEndPoint}/apps/**/revisions/**/approve`,
revision: `${apiEndPoint}/apps/**/revisions`,
- changePassword: `${Cypress.env('COGNITO_API_BASE_URL')}/password/change`
+ changePassword: `${apiEndPoint}/password/change`,
+ installations: `${apiEndPoint}/installations`,
+ terminateApp: `${apiEndPoint}/installations/**/terminate`
}
diff --git a/cypress/integration/flow-install-app-happy-path.test.ts b/cypress/integration/flow-install-app-happy-path.test.ts
new file mode 100644
index 0000000000..3bcaec3ee1
--- /dev/null
+++ b/cypress/integration/flow-install-app-happy-path.test.ts
@@ -0,0 +1,118 @@
+import loginPage from '../pages/login-page'
+import apiRoutes from '../fixtures/routes'
+import appRequest from '../requests/app'
+import developerAppsPage from '../pages/developer-apps-page'
+import adminApprovalsPage from '../pages/admin-approvals-page'
+import installedAppsPage from '../pages/installed-apps-page'
+import manageAppsPage from '../pages/manage-apps-page'
+
+import clientWelcomeModal from '../components/client-welcome-modal'
+import appDetailModal from '../components/app-detail-modal'
+import appCard from '../components/app-card'
+import nanoid from 'nanoid'
+
+const {
+ actions: { loginUsingClientAccount, loginUsingDeveloperAccount, loginUsingAdminAccount }
+} = loginPage
+
+const {
+ selectors: { buttonAceptWelcome }
+} = clientWelcomeModal
+
+const {
+ actions: { listedAppWithName }
+} = developerAppsPage
+
+const {
+ actions: { approveAppWithId }
+} = adminApprovalsPage
+
+const { url: installedAppsPageUrl } = installedAppsPage
+
+const { url: manageAppsPageUrl } = manageAppsPage
+
+const {
+ selectors: { buttonAgree, buttonInstallApp, buttonUninstallApp, buttonSuccess, divSuccessMessage }
+} = appDetailModal
+
+const {
+ actions: { clickAppCardSettingWithId }
+} = appCard
+
+const appName = `E2E Test App - ${nanoid()}`
+let appId = ''
+
+describe('Install app happy path', () => {
+ before(() => {
+ cy.server()
+ appRequest.createApp(appName)
+ })
+
+ after(() => {
+ cy.server()
+ appRequest.deleteApp(appId)
+ })
+
+ it('Log into developer and listed app successfully', () => {
+ cy.server()
+ loginUsingDeveloperAccount()
+ listedAppWithName(appName, res => {
+ appId = res
+ })
+ })
+
+ it('Log into admin and approve app successfully', () => {
+ cy.server()
+ loginUsingAdminAccount()
+ approveAppWithId(appId)
+ })
+
+ it('Log into client and install and uninstall app successfully', () => {
+ cy.server()
+ cy.clearCookies()
+
+ cy.route('GET', apiRoutes.manageApps).as('getManageApps')
+ cy.route('GET', apiRoutes.installedApps).as('getInstalledApps')
+ cy.route('POST', apiRoutes.installations).as('installApp')
+ cy.route('POST', apiRoutes.terminateApp).as('uninstallApp')
+
+ loginUsingClientAccount()
+
+ cy.get(buttonAceptWelcome).click()
+
+ cy.get(`div[data-test-app-name="${appName}"]`).click()
+
+ cy.get(buttonInstallApp).should('have.length', 1)
+ cy.get(buttonInstallApp).click()
+ cy.get(buttonAgree).click()
+
+ cy.wait('@installApp')
+
+ cy.route('GET', apiRoutes.appDetail).as('getAppDetail')
+
+ cy.get(divSuccessMessage).should('have.length', 1)
+ cy.get(buttonSuccess).click()
+
+ cy.wait('@getAppDetail')
+
+ cy.visit(installedAppsPageUrl)
+
+ cy.wait('@getInstalledApps')
+
+ cy.visit(manageAppsPageUrl)
+
+ cy.wait('@getManageApps')
+
+ clickAppCardSettingWithId(appId)
+
+ cy.get(buttonUninstallApp).click()
+ cy.get(buttonAgree).click()
+
+ cy.wait('@uninstallApp')
+
+ cy.get(divSuccessMessage).should('have.length', 1)
+ cy.get(buttonSuccess).click()
+
+ cy.wait('@getManageApps')
+ })
+})
diff --git a/cypress/pages/admin-approvals-page.ts b/cypress/pages/admin-approvals-page.ts
index 49f4d44d7d..c804e8a45d 100644
--- a/cypress/pages/admin-approvals-page.ts
+++ b/cypress/pages/admin-approvals-page.ts
@@ -1,4 +1,5 @@
import routes from '@/constants/routes'
+import apiRoutes from '../fixtures/routes'
const adminApprovalsPageMetaData = {
url: routes.ADMIN_APPROVALS,
@@ -16,6 +17,17 @@ const adminApprovalsPage = {
actions: {
clickViewDetailsButtonWithAppId(id: string) {
cy.get(`button[data-test="view-details-button_${id}"]`).click()
+ },
+ approveAppWithId(id: string) {
+ const { buttonApprove, btnConfirmApproval, divApproveAppSuccessfully } = adminApprovalsPageMetaData.selectors
+ cy.get(`button[data-test="view-details-button_${id}"]`).click()
+ cy.get(buttonApprove).click()
+
+ cy.route('POST', apiRoutes.approveApp).as('requestApproveApp')
+ cy.get(btnConfirmApproval).click()
+ cy.wait('@requestApproveApp')
+
+ cy.get(divApproveAppSuccessfully).should('have.length', 1)
}
}
}
diff --git a/cypress/pages/developer-apps-page.ts b/cypress/pages/developer-apps-page.ts
index dcd9e75bd8..8f599c7b23 100644
--- a/cypress/pages/developer-apps-page.ts
+++ b/cypress/pages/developer-apps-page.ts
@@ -1,6 +1,7 @@
import webRoutes from '@/constants/routes'
import appRequests from '../requests/app'
import apiRoutes from '../fixtures/routes'
+import developerSubmitAppPage from '../pages/developer-submit-app-page'
const developerAppsPageMetadata = {
url: webRoutes.DEVELOPER_MY_APPS,
@@ -11,6 +12,10 @@ const developerAppsPageMetadata = {
}
}
+const {
+ selectors: { checkBoxIsListed, buttonSubmit, checkboxAgreeTheTermsAndConditions }
+} = developerSubmitAppPage
+
const developerAppsPageActions = {
clickAppCardWithName(name: string) {
return cy.get(`div[data-test-app-name="${name}"]`).click()
@@ -26,6 +31,38 @@ const developerAppsPageActions = {
.then(appId => {
appRequests.deleteApp(appId as any)
})
+ },
+
+ listedAppWithName(name: string, callback: (appId: string) => void) {
+ const { buttonEditDetails } = developerAppsPageMetadata.selectors
+ cy.visit(developerAppsPage.url)
+ cy.route(apiRoutes.appsOfDeveloper).as('getAppsOfDeveloper')
+ cy.wait('@getAppsOfDeveloper')
+ cy.get(`div[data-test-app-name='${name}']`)
+ .click()
+ .invoke('attr', 'data-test-app-id')
+ .then(appId => {
+ callback(appId as any)
+ })
+
+ cy.route(apiRoutes.categories).as('requestGetCategories')
+ cy.route(apiRoutes.scopes).as('requestGetScopes')
+
+ cy.get(buttonEditDetails).click()
+
+ cy.wait('@requestGetCategories')
+ cy.wait('@requestGetScopes')
+
+ cy.get(checkBoxIsListed).click({ force: true })
+ cy.get(checkboxAgreeTheTermsAndConditions).click({ force: true })
+
+ cy.route('POST', apiRoutes.revision).as('requestSubmitRevision')
+ cy.get(buttonSubmit).click()
+ cy.wait('@requestSubmitRevision')
+
+ cy.get(buttonEditDetails)
+ .should('have.text', 'Pending Revision')
+ .should('be.disabled')
}
}
diff --git a/cypress/pages/installed-apps-page.ts b/cypress/pages/installed-apps-page.ts
new file mode 100644
index 0000000000..55697e889f
--- /dev/null
+++ b/cypress/pages/installed-apps-page.ts
@@ -0,0 +1,5 @@
+import routes from '@/constants/routes'
+
+export default {
+ url: routes.INSTALLED_APPS
+}
diff --git a/cypress/pages/manage-apps-page.ts b/cypress/pages/manage-apps-page.ts
new file mode 100644
index 0000000000..764ab9453e
--- /dev/null
+++ b/cypress/pages/manage-apps-page.ts
@@ -0,0 +1,5 @@
+import routes from '@/constants/routes'
+
+export default {
+ url: routes.MY_APPS
+}
diff --git a/src/components/ui/__tests__/__snapshots__/installed-app-card.tsx.snap b/src/components/ui/__tests__/__snapshots__/installed-app-card.tsx.snap
index 854a16892c..ee9b933aab 100644
--- a/src/components/ui/__tests__/__snapshots__/installed-app-card.tsx.snap
+++ b/src/components/ui/__tests__/__snapshots__/installed-app-card.tsx.snap
@@ -1,20 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`InstalledAppCard should match a snapshot 1`] = `
-
- nXXT2zaK807ysWgy8F0WEhIYRP3TgosAtfuiLtQCImoSx0kynxbIF0nkGHU36Oz13kM3DG0Bcsicr8L6eWFKLBg4axlmiOEWcvwHAbBP9LRvoFkCl58k1wjhOExnpaZItEyOT1AXVKv8PE44aMGtVz -
- ++ nXXT2zaK807ysWgy8F0WEhIYRP3TgosAtfuiLtQCImoSx0kynxbIF0nkGHU36Oz13kM3DG0Bcsicr8L6eWFKLBg4axlmiOEWcvwHAbBP9LRvoFkCl58k1wjhOExnpaZItEyOT1AXVKv8PE44aMGtVz +
+ +