mirror of https://github.com/harness/drone.git
feat: [code-1755]: add signup integration test (#1207)
parent
622cc58b21
commit
a314709402
|
@ -14,6 +14,7 @@ release
|
|||
.vscode/settings.json
|
||||
coverage.out
|
||||
gitness.session.sql
|
||||
web/cypress/node_modules
|
||||
|
||||
# ignore any executables we build
|
||||
/gitness
|
|
@ -0,0 +1,19 @@
|
|||
import { defineConfig } from 'cypress'
|
||||
|
||||
export default defineConfig({
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:3020',
|
||||
specPattern: 'integration/**/*.spec.{ts,tsx}',
|
||||
supportFile: 'support/e2e.ts',
|
||||
fixturesFolder: 'fixtures',
|
||||
videoUploadOnPasses: false
|
||||
},
|
||||
projectId: 'mcssf4',
|
||||
viewportWidth: 1500,
|
||||
viewportHeight: 1000,
|
||||
retries: {
|
||||
runMode: 2,
|
||||
openMode: 0
|
||||
},
|
||||
fixturesFolder: 'fixtures'
|
||||
})
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import {
|
||||
CreateUserResponse,
|
||||
GetUserResponse,
|
||||
membershipGetCall,
|
||||
membershipQueryGetCall,
|
||||
signupPostCall,
|
||||
userGetCall
|
||||
} from './constants'
|
||||
|
||||
describe('Signup', () => {
|
||||
beforeEach(() => {
|
||||
cy.on('uncaught:exception', () => false)
|
||||
cy.intercept('POST', signupPostCall, CreateUserResponse).as('signupPostCall')
|
||||
cy.intercept('GET', userGetCall, GetUserResponse).as('userGetCall')
|
||||
cy.intercept('GET', membershipGetCall, []).as('membershipGetCall')
|
||||
cy.intercept('GET', membershipQueryGetCall, []).as('membershipQueryGetCall')
|
||||
})
|
||||
it('should signup a new user', () => {
|
||||
cy.visit('/register')
|
||||
cy.contains('div p', 'Sign Up').should('be.visible')
|
||||
cy.contains('span', 'User ID').should('be.visible')
|
||||
cy.contains('span', 'Email').should('be.visible')
|
||||
cy.contains('span', 'Password').should('be.visible')
|
||||
cy.contains('span', 'Confirm Password').should('be.visible')
|
||||
|
||||
// Fill fields
|
||||
cy.get('input[name="username"]').type('testuser')
|
||||
cy.get('input[name="email"]').type('test@harness.io')
|
||||
cy.get('input[name="password"]').type('password')
|
||||
cy.get('input[name="confirmPassword"]').type('password')
|
||||
|
||||
//click signup
|
||||
cy.contains('button span', 'Sign Up').click()
|
||||
cy.wait('@signupPostCall')
|
||||
cy.wait('@userGetCall')
|
||||
cy.get('@signupPostCall').its('request.body').should('deep.equal', {
|
||||
display_name: 'testuser',
|
||||
email: 'test@harness.io',
|
||||
uid: 'testuser',
|
||||
password: 'password'
|
||||
})
|
||||
cy.wait('@membershipGetCall')
|
||||
cy.wait('@membershipQueryGetCall')
|
||||
})
|
||||
})
|
|
@ -0,0 +1,27 @@
|
|||
export const CreateUserResponse = {
|
||||
access_token: 'token',
|
||||
token: {
|
||||
principal_id: 1,
|
||||
type: 'session',
|
||||
identifier: 'register',
|
||||
expires_at: 1715463431214,
|
||||
issued_at: 1712871431214,
|
||||
created_by: 15,
|
||||
uid: 'register'
|
||||
}
|
||||
}
|
||||
|
||||
export const GetUserResponse = {
|
||||
uid: 'testuser',
|
||||
email: 'test@harness.io',
|
||||
display_name: 'testuser',
|
||||
admin: false,
|
||||
blocked: false,
|
||||
created: 1712871431212,
|
||||
updated: 1712871431212
|
||||
}
|
||||
|
||||
export const signupPostCall = `/api/v1/register?include_cookie=true`
|
||||
export const userGetCall = `/api/v1/user`
|
||||
export const membershipGetCall = '/api/v1/user/memberships'
|
||||
export const membershipQueryGetCall = '/api/v1/user/memberships?query='
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "cypress-tests",
|
||||
"private": "true",
|
||||
"scripts": {
|
||||
"cypress:open": "cypress open",
|
||||
"server": "node server.js"
|
||||
},
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"cypress": "10.8.0",
|
||||
"wait-on": "^6.0.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2023 Harness, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const express = require('express')
|
||||
const fs = require('fs')
|
||||
const app = express()
|
||||
const path = require('path')
|
||||
const PORT = 8080
|
||||
|
||||
function checkFileExistsSync(filepath) {
|
||||
let flag = true
|
||||
try {
|
||||
fs.accessSync(filepath, fs.constants.F_OK)
|
||||
} catch (e) {
|
||||
flag = false
|
||||
}
|
||||
return flag
|
||||
}
|
||||
|
||||
function getFile(req) {
|
||||
const url = req.url.split('?')[0].replace(/^\/gateway/, '')
|
||||
|
||||
return path.resolve(__dirname, `fixtures${url}${req.method === 'POST' ? '.post' : ''}.json`)
|
||||
}
|
||||
|
||||
app.all('*', (req, res) => {
|
||||
if (req.get('Content-Type') === 'text/plain') {
|
||||
res.setHeader('Content-Type', 'text/plain')
|
||||
} else {
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
}
|
||||
const file = getFile(req)
|
||||
if (['POST', 'GET', 'PUT'].indexOf(req.method) > -1 && checkFileExistsSync(file)) {
|
||||
res.end(fs.readFileSync(file))
|
||||
} else {
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
correlationId: '',
|
||||
data: {},
|
||||
status: 'SUCCESS'
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`⚡️[server]: Server is running at http://localhost:${PORT}`)
|
||||
})
|
|
@ -0,0 +1,84 @@
|
|||
// @ts-check
|
||||
///<reference path="../../src/global.d.ts" />
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
|
||||
declare namespace Cypress {
|
||||
interface Chainable {
|
||||
clickSubmit(): void
|
||||
visitPageAssertion(className?: string): void
|
||||
getAccountIdentifier(): any
|
||||
apiRequest(
|
||||
method: string,
|
||||
endpoint: string,
|
||||
body?: any,
|
||||
queryParams?: { [key: string]: string },
|
||||
headerOptions?: HeadersInit
|
||||
): void
|
||||
getSecret(scope: string): any
|
||||
fillName(name: string): void
|
||||
fillField(fieldName: string, value: string): void
|
||||
login(username?: string, password?: string): void
|
||||
}
|
||||
}
|
||||
|
||||
export const activeTabClassName = '.TabNavigation--active'
|
||||
|
||||
Cypress.Commands.add('visitPageAssertion', (className = activeTabClassName) => {
|
||||
cy.get(className, {
|
||||
timeout: 30000
|
||||
}).should('be.visible')
|
||||
cy.wait(1000)
|
||||
})
|
||||
Cypress.Commands.add('clickSubmit', () => {
|
||||
cy.get('input[type="submit"]').click()
|
||||
})
|
||||
|
||||
Cypress.Commands.add('getAccountIdentifier', () => {
|
||||
cy.location('hash').then(hash => {
|
||||
return cy.wrap(hash.split('/')[2])
|
||||
})
|
||||
})
|
||||
|
||||
Cypress.Commands.add(
|
||||
'apiRequest',
|
||||
(
|
||||
method: string,
|
||||
endpoint: string,
|
||||
body?: unknown,
|
||||
queryParams?: { [key: string]: string },
|
||||
headerOptions?: HeadersInit
|
||||
) => {
|
||||
cy.request(generateRequestObject(method, endpoint, body, queryParams, headerOptions))
|
||||
}
|
||||
)
|
||||
|
||||
Cypress.Commands.add('fillField', (fieldName: string, value: string) => {
|
||||
cy.get(`[name="${fieldName}"]`).clear().type(value)
|
||||
})
|
||||
Cypress.Commands.add('fillName', (value: string) => {
|
||||
cy.fillField('name', value)
|
||||
})
|
|
@ -0,0 +1,20 @@
|
|||
// ***********************************************************
|
||||
// This example support/e2e.ts is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
File diff suppressed because it is too large
Load Diff
|
@ -31,7 +31,8 @@
|
|||
"services": "restful-react import --config restful-react.config.js",
|
||||
"postservices": "prettier --write src/services/**/*.tsx",
|
||||
"strings": "npm-run-all strings:*",
|
||||
"strings:genTypes": "node scripts/strings/generateTypesCli.mjs"
|
||||
"strings:genTypes": "node scripts/strings/generateTypesCli.mjs",
|
||||
"dev:cypress": "NODE_ENV=development TARGET_LOCALHOST=false CYPRESS=true PROJECT_ID=CYPRESS_PROJECT_ID ORG_ID=CYPRESS_ORG_ID ACCOUNT_ID=CYPRESS_ACCOUNT_ID BASE_URL=http://localhost:8080 NODE_OPTIONS=\"--max-old-space-size=6144\" webpack serve --progress --config config/webpack.dev.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@blueprintjs/core": "3.26.1",
|
||||
|
|
Loading…
Reference in New Issue