Skip to content

Commit

Permalink
Feature/cld 636 implement submit app test case (#231)
Browse files Browse the repository at this point in the history
[CLD-636]implement submit app happy path test case
  • Loading branch information
NghiaPham authored Dec 31, 2019
1 parent b5a0f54 commit 7ad0a26
Show file tree
Hide file tree
Showing 22 changed files with 339 additions and 82 deletions.
6 changes: 6 additions & 0 deletions cypress/fixtures/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
categories: 'https://dev.platformmarketplace.reapit.net/categories',
scopes: 'https://dev.platformmarketplace.reapit.net/scopes',
appsOfDeveloper: 'https://dev.platformmarketplace.reapit.net/apps?developerId=**&PageNumber=**&PageSize=**',
apps: 'https://dev.platformmarketplace.reapit.net/apps'
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import loginPage from '../pages/loginPage'
import clientAppsPage from '../pages/clientAppsPage'
import developerAppsPage from '../pages/developerAppsPage'
import adminApprovalsPage from '../pages/adminApprovalsPage'
import loginPage from '../pages/login-page'
import clientAppsPage from '../pages/client-apps-page'
import developerPage from '../pages/developer-page'
import adminApprovalsPage from '../pages/admin-approvals-page'

describe('Login flow', () => {
describe('works when testing the happycase flow', () => {
describe('Login happy path', () => {
describe('Should be able to login as client, developer and admin and navigate to correct landing pages', () => {
const {
selectors: { inputEmail, inputPassword, buttonLogin },
loginAsAdminUrl,
Expand All @@ -20,7 +20,7 @@ describe('Login flow', () => {
const {
url: developerPageUrl,
selectors: { container: developerPageContainer }
} = developerAppsPage
} = developerPage

const {
url: adminPageUrl,
Expand All @@ -29,23 +29,23 @@ describe('Login flow', () => {

const testCases = [
{
testCaseName: 'login successfully using DEVELOPER account',
testCaseName: 'Login successfully using DEVELOPER account',
email: Cypress.env('DEVELOPER_ACCOUNT_EMAIL'),
password: Cypress.env('DEVELOPER_ACCOUNT_PASSWORD'),
container: developerPageContainer,
url: developerPageUrl,
loginUrl: loginAsDeveloperUrl
},
{
testCaseName: 'login successfully using CLIENT account',
testCaseName: 'Login successfully using CLIENT account',
email: Cypress.env('CLIENT_ACCOUNT_EMAIL'),
password: Cypress.env('CLIENT_ACCOUNT_PASSWORD'),
container: clientAppsPageContainer,
url: pageClientAppsUrl,
loginUrl: loginAsClientUrl
},
{
testCaseName: 'login successfully using ADMIN account',
testCaseName: 'Login successfully using ADMIN account',
email: Cypress.env('ADMIN_ACCOUNT_EMAIL'),
password: Cypress.env('ADMIN_ACCOUNT_PASSWORD'),
container: adminPageContainer,
Expand Down
94 changes: 94 additions & 0 deletions cypress/integration/flow-submit-app-happy-path.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import loginPage from '../pages/login-page'
import developerSubmitAppPage from '../pages/developer-submit-app-page'
import developerAppsPage from '../pages/developer-apps-page'
import appRequests from '../requests/app'
import routes from '../fixtures/routes'
import nanoid from 'nanoid'

const appName = `E2E Test App -${nanoid()}`

const {
actions: { loginUsingDeveloperAccount }
} = loginPage

const { selectors: developerSubmitAppPageSelectors } = developerSubmitAppPage
const { checkBoxUserSession, buttonSubmit, selectCategory, submitSuccessSection } = developerSubmitAppPageSelectors

describe('Submit app happy path', () => {
it('Log into dev and Submit an app successfully', () => {
loginUsingDeveloperAccount()

cy.visit(developerSubmitAppPage.url)
cy.server()

cy.route(routes.appsOfDeveloper).as('getAppsOfDeveloper')
cy.route(routes.categories).as('getCategories')
cy.route(routes.scopes).as('getScopes')
cy.route('POST', routes.apps).as('postSubmitApp')

cy.wait('@getCategories')
cy.wait('@getScopes')
/**
* Both Object.keys and for in loop element is string
* string is not a key of developerSubmitAppPageSelectors or testData
* -> Have to cast to any
*/
const inputTestData: any = {
textBoxName: appName,
textBoxSupportEmail: '[email protected]',
textBoxTelephone: '01234567890',
textBoxHomePage: 'https://google.com',
textBoxLaunchUrl: 'https://google.com',
textAreaDescription:
'Lorem ipsum dolor amet organic fashion axe man bun cray kitsch hashtag post-ironic normcore copper mug keytar fam actually street art air plant. Copper mug put a bird on it kombucha pop-up. Man bun kickstarter fam pour-over plaid, franzen blog. Activated charcoal letterpress mlkshk kickstarter master cleanse. Paleo austin actually blue bottle mixtape mustache bicycle rights gochujang humblebrag. Direct trade affogato cliche, asymmetrical sartorial pinterest chambray coloring book.',
textAreaSummary:
'Lorem ipsum dolor amet messenger bag pinterest af umami. Master cleanse photo booth cardigan, jean shorts dreamcatcher butcher ethical YOLO.'
}
for (let inputTestDataSelector in inputTestData) {
const data = inputTestData[inputTestDataSelector]
const selector = (developerSubmitAppPageSelectors as any)[inputTestDataSelector]
cy.get(selector).type(data)
}
const fileUploadTestData: any = {
inputFileSubmitAppIcon:
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==',
fileUploadScreenshot1:
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8Xw8AAoMBgDTD2qgAAAAASUVORK5CYII=',
fileUploadScreenshot2:
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
fileUploadScreenshot3:
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk4PpfDwACpQGKFCvGMAAAAABJRU5ErkJggg==',
fileUploadScreenshot4:
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOMK86uBwAEMAG9Q194bwAAAABJRU5ErkJggg=='
}
for (let fileUploadTestDataSelector in fileUploadTestData) {
const data = fileUploadTestData[fileUploadTestDataSelector]
const selector = (developerSubmitAppPageSelectors as any)[fileUploadTestDataSelector]
cy.get(selector).upload(
{
fileContent: data,
fileName: selector,
mimeType: 'image/jpeg',
encoding: 'binary'
},
{ subjectType: 'input' }
)
}
cy.get(selectCategory).select('Game')
cy.get(checkBoxUserSession).click({ force: true })
cy.get(buttonSubmit).click()
cy.wait(100)
cy.wait('@postSubmitApp')
cy.get(submitSuccessSection).should('have.length', 1)

// Cleanup
cy.visit(developerAppsPage.url)
cy.wait('@getAppsOfDeveloper')
cy.get(`div[data-test-app-name='${appName}']`)
.should('have.length', 1)
.invoke('attr', 'data-test-app-id')
.then(appId => {
appRequests.deleteApp(appId as any)
})
})
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import routes from '@/constants/routes'

export default {
url: '/admin/approvals',
url: routes.ADMIN_APPROVALS,
selectors: {
container: '#page-admin-approvals-container'
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import routes from '@/constants/routes'

export default {
url: '/client/apps',
url: routes.CLIENT,
selectors: {
container: '#page-client-apps-container'
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import routes from '@/constants/routes'

export default {
url: '/developer/apps',
url: routes.DEVELOPER_MY_APPS,
selectors: {
container: '#page-developer-apps-container'
}
Expand Down
8 changes: 8 additions & 0 deletions cypress/pages/developer-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import routes from '@/constants/routes'

export default {
url: routes.DEVELOPER,
selectors: {
container: '#page-developer-home-container'
}
}
24 changes: 24 additions & 0 deletions cypress/pages/developer-submit-app-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import routes from '@/constants/routes'

export default {
url: routes.SUBMIT_APP,
selectors: {
buttonSubmit: 'button[type="submit"]',
selectCategory: 'select[name="categoryId"]',
checkBoxUserSession: 'input[id="USER SESSION"]',
checkBoxClientSecret: 'input["CLIENT SECRET"]',
textBoxName: 'input[name="name"]',
inputFileSubmitAppIcon: 'input#iconImage',
textBoxSupportEmail: 'input[name="supportEmail"]',
textBoxTelephone: 'input[name="telephone"]',
textBoxHomePage: 'input[name="homePage"]',
textBoxLaunchUrl: 'input[name="launchUri"]',
textAreaSummary: 'textarea[name="summary"]',
textAreaDescription: 'textarea[name="description"]',
fileUploadScreenshot1: 'input#screenshot1',
fileUploadScreenshot2: 'input#screenshot2',
fileUploadScreenshot3: 'input#screenshot3',
fileUploadScreenshot4: 'input#screenshot4',
submitSuccessSection: 'div[data-test="submit-success-section"]'
}
}
41 changes: 41 additions & 0 deletions cypress/pages/login-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import routes from '@/constants/routes'
import developerAppsPage from './developer-page'

const loginPageMetadata = {
loginAsClientUrl: routes.CLIENT_LOGIN,
loginAsDeveloperUrl: routes.DEVELOPER_LOGIN,
loginAsAdminUrl: routes.ADMIN_LOGIN,
selectors: {
inputEmail: 'input#userName',
inputPassword: 'input#password',
buttonLogin: "button[type='submit']"
},
account: {
DEVELOPER: {
email: Cypress.env('DEVELOPER_ACCOUNT_EMAIL'),
password: Cypress.env('DEVELOPER_ACCOUNT_PASSWORD')
}
}
}

const loginPageActions = {
loginUsingDeveloperAccount() {
const {
loginAsDeveloperUrl,
selectors: { buttonLogin, inputPassword, inputEmail }
} = loginPageMetadata

cy.visit(loginAsDeveloperUrl)
cy.get(inputEmail).type(Cypress.env('DEVELOPER_ACCOUNT_EMAIL'))
cy.get(inputPassword).type(Cypress.env('DEVELOPER_ACCOUNT_PASSWORD'))
cy.get(buttonLogin).click()
cy.get(developerAppsPage.selectors.container).should('have.length', 1)
}
}

const loginPage = {
...loginPageMetadata,
actions: loginPageActions
}

export default loginPage
10 changes: 0 additions & 10 deletions cypress/pages/loginPage.ts

This file was deleted.

26 changes: 23 additions & 3 deletions cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const path = require('path')
const wp = require('@cypress/webpack-preprocessor')
const ResolveTSPathsToWebpackAlias = require('ts-paths-to-webpack-alias')
const reapitConfig = require('../../reapit-config.json')

module.exports = (on, config) => {
// https://basarat.gitbooks.io/typescript/docs/testing/cypress.html
Expand All @@ -22,17 +24,35 @@ module.exports = (on, config) => {
options: { transpileOnly: true }
}
]
}
},
plugins: [
/**
* This plugin mapped all data in the field named "paths" of tsconfig.json to webpack alias
*/
new ResolveTSPathsToWebpackAlias({
tsconfig: path.resolve(__dirname, '../tsconfig.json')
}),
]
}
}
on('file:preprocessor', wp(options))


// Retries plugin
require('cypress-plugin-retries/lib/plugin')(on)

// Config ENV
require('dotenv').config({ path: path.resolve(__dirname, '../../src/constants/.env') })

// Load ENV from config manager
let mergedEnv = process.env
const reapitEnv = process.env.REAPIT_ENV || 'LOCAL'
const reapitConfigMatchedEnv = reapitConfig[reapitEnv]

if (config && typeof config === 'object') {
mergedEnv = {...mergedEnv, ...reapitConfigMatchedEnv}
}

const baseUrl = process.env.APPLICATION_URL
return { ...config, baseUrl, env: { ...process.env } }
return { ...config, baseUrl, env: {...mergedEnv} }
}
16 changes: 16 additions & 0 deletions cypress/requests/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import routes from '../fixtures/routes'

export default {
deleteApp: (appId: string) => {
cy.server()
cy.route(`${routes.apps}/${appId}`, 'DELETE')

cy.request({
url: `${routes.apps}/${appId}`,
method: 'DELETE',
headers: {
'x-api-key': Cypress.env('MARKETPLACE_API_KEY')
}
})
}
}
11 changes: 11 additions & 0 deletions cypress/support/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
import 'cypress-plugin-retries'
import 'cypress-file-upload'

/**
* See https://github.com/cypress-io/cypress/issues/95
* Cypress doesn't support waiting for Fetch API atm
* Solution: delete window.fetch while developing -> whatwg-fetch will kick in
* whatwg-fetch is based on XMLHttpRequest and supported by Cypress
*/
Cypress.on('window:before:load', win => {
delete win.fetch
})
11 changes: 8 additions & 3 deletions cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
{
"compilerOptions": {
"esModuleInterop": true,
"strict": true,
"baseUrl": "../node_modules",
"baseUrl": "../",
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress"]
"lib": ["es5", "dom", "ES2015"],
"typeRoots": ["./node_modules/@types"],
"types": ["cypress"],
"paths": {
"@/*": ["./src/*"]
}
},
"include": [
"**/*.ts"
Expand Down
Loading

0 comments on commit 7ad0a26

Please sign in to comment.