-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
1,976 additions
and
138 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
name: E2E Test | ||
on: | ||
push: | ||
branches: | ||
- cypress-experiment | ||
- develop | ||
- main | ||
- master | ||
|
||
jobs: | ||
e2e-tests: | ||
runs-on: [ubuntu-latest] | ||
concurrency: | ||
group: ${{ github.workflow }}-ci-${{ github.ref }} | ||
cancel-in-progress: true | ||
permissions: | ||
contents: read | ||
deployments: write | ||
name: Run E2E Tests | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: '16' | ||
cache: 'npm' | ||
- run: npm ci | ||
- name: Cypress run | ||
uses: cypress-io/github-action@v5 | ||
env: | ||
CYPRESS_TEST_USERNAME: ${{ secrets.CYPRESS_TEST_USERNAME}} | ||
CYPRESS_TEST_PASSWORD: ${{ secrets.CYPRESS_TEST_PASSWORD }} | ||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_TEST_RECORD_ID}} | ||
CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_TEST_PROJECT_ID }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
start: npm run startprod | ||
install: false | ||
config: pageLoadTimeout=100000 | ||
wait-on: 'http://localhost:4200' | ||
record: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
<ImgLogo></ImgLogo> | ||
<ImgLogo id='login-logo-img' /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { defineConfig } from 'cypress'; | ||
|
||
export default defineConfig({ | ||
e2e: { | ||
projectId: 'fkj9f2', | ||
baseUrl: 'http://localhost:4200/', | ||
specPattern: ['cypress/e2e/**/*.spec.{js,ts}'], | ||
viewportHeight: 1070, | ||
viewportWidth: 1480, | ||
env: { | ||
hideCredentials: true, | ||
TEST_USERNAME: '***', | ||
TEST_PASSWORD: '***', | ||
}, | ||
setupNodeEvents(on, config) {}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Add Cypress types | ||
declare namespace Cypress { | ||
/** | ||
* ================================== | ||
* IRENE SPECIFIC INTERFACES | ||
* ================================== | ||
*/ | ||
|
||
export interface FrontendConfig { | ||
name: string; | ||
hide_poweredby_logo: boolean; | ||
url: string; | ||
registration_enabled: boolean; | ||
registration_link: string; | ||
integrations: Integrations; | ||
images: Images; | ||
theme: Theme; | ||
} | ||
|
||
export interface Images { | ||
logo_on_darkbg: string; | ||
logo_on_lightbg: string; | ||
favicon: string; | ||
} | ||
|
||
export interface Integrations { | ||
crisp_key: string; | ||
hotjar_key: string; | ||
pendo_key: string; | ||
csb_key: string; | ||
rollbar_key: string; | ||
freshdesk_configuration: FreshdeskConfiguration; | ||
} | ||
|
||
export interface FreshdeskConfiguration { | ||
widget_id: string; | ||
} | ||
|
||
export interface Theme { | ||
scheme: string; | ||
primary_color: string; | ||
primary_alt_color: string; | ||
secondary_color: string; | ||
secondary_alt_color: string; | ||
} | ||
|
||
interface ServerConfig { | ||
websocket: string; | ||
enterprise: boolean; | ||
url_upload_allowed: boolean; | ||
} | ||
|
||
/** | ||
* ================================== | ||
* CUSTOM CYPRESS COMMANDS | ||
* ================================== | ||
*/ | ||
type modelFactoriesName = 'vulnerabilities' | 'projects'; | ||
|
||
interface Chainable { | ||
loginByCredentials(username: string, password: string): Chainable; | ||
|
||
generateModelFixture: ( | ||
name: modelFactoriesName, | ||
size?: number | ||
) => Chainable; | ||
|
||
loadAppConfig(data?: { | ||
frontendConfig?: FrontendConfig; | ||
serverConfig?: ServerConfig; | ||
}): Chainable; | ||
|
||
loadMockAppConfig(): Chainable; | ||
loadMockHudsonProjects(): Chainable; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import APP_TRANSLATIONS from '../support/translations'; | ||
import { mirageServer } from '../support/Mirage'; | ||
|
||
import LoginActions from '../support/Actions/auth/LoginActions'; | ||
import NetworkActions from '../support/Actions/common/NetworkActions'; | ||
import NotificationRepository from '../support/Repositories/NotificationRepository'; | ||
|
||
import LOGIN_PAGE_LOCATORS from '../locators/pages/LoginPage'; | ||
import NAVBAR_LOCATORS from '../locators/common/Navbar'; | ||
|
||
import { API_ROUTES } from '../support/api.routes'; | ||
import { APPLICATION_ROUTES } from '../support/application.routes'; | ||
|
||
// Grouped test Actions | ||
const loginActions = new LoginActions(); | ||
const networkActions = new NetworkActions(); | ||
|
||
// Common application repositories | ||
const notifications = new NotificationRepository(); | ||
|
||
// User credentials | ||
const username = Cypress.env('TEST_USERNAME'); | ||
const password = Cypress.env('TEST_PASSWORD'); | ||
|
||
describe('User Login', () => { | ||
beforeEach(() => { | ||
networkActions.hideNetworkLogsFor({ ...API_ROUTES.websockets }); | ||
}); | ||
|
||
it('should redirect unauthenticated user to login page', function () { | ||
cy.visit(APPLICATION_ROUTES.projects); | ||
|
||
cy.url().should('contain', APPLICATION_ROUTES.login); | ||
cy.get(LOGIN_PAGE_LOCATORS.loginTitle).should( | ||
'contain.text', | ||
APP_TRANSLATIONS.login | ||
); | ||
|
||
cy.get(LOGIN_PAGE_LOCATORS.orgImageLogo).should('be.visible'); | ||
cy.get(LOGIN_PAGE_LOCATORS.loginTitle) | ||
.should('be.visible') | ||
.contains(APP_TRANSLATIONS.login); | ||
|
||
cy.get(LOGIN_PAGE_LOCATORS.usernameField).should('be.visible'); | ||
cy.get(LOGIN_PAGE_LOCATORS.userCheckIconBtn).should('be.visible'); | ||
// cy.get(LOGIN_PAGE_LOCATORS.regLink).should('be.visible'); | ||
}); | ||
|
||
it('should throw an error if user credentials are invalid', () => { | ||
const errorMessage = 'Unable to log in with provided credentials.'; | ||
|
||
// Mock Login request to fail | ||
networkActions.mockNetworkReq({ | ||
method: 'POST', | ||
route: API_ROUTES.login.route, | ||
alias: 'failedLoginAttempt', | ||
dataOverride: { | ||
statusCode: 401, | ||
body: { | ||
message: errorMessage, | ||
attempt_left: '4', | ||
failure_limit: '5', | ||
}, | ||
}, | ||
}); | ||
|
||
// Logs user to dashboard via UI | ||
// CASE: Invalid Password | ||
loginActions.doLoginWithUI({ username, password: 'password' }); | ||
notifications.assertErrorMessage(errorMessage); | ||
|
||
// CASE: Invalid Username | ||
loginActions.doLoginWithUI({ username: 'username', password }); | ||
notifications.assertErrorMessage(errorMessage); | ||
}); | ||
|
||
it('should redirect authenticated user to dashboard after logging in', () => { | ||
// Intercept vulnerabilities route | ||
networkActions.mockNetworkReq({ | ||
...API_ROUTES.vulnerabilityList, | ||
dataOverride: { | ||
data: mirageServer.createRecordList('vulnerability', 1).map((_) => ({ | ||
id: _['id'], | ||
type: 'vulnerabilities', | ||
attributes: _, | ||
relationships: {}, | ||
})), | ||
}, | ||
}); | ||
|
||
// Intercept unknown analysis request | ||
const unknownAnalysisStatus = mirageServer.createRecord( | ||
'unknown-analysis-status' | ||
); | ||
const file = mirageServer.createRecord('file'); | ||
|
||
networkActions.mockNetworkReq({ | ||
...API_ROUTES.unknownAnalysisStatus, | ||
dataOverride: unknownAnalysisStatus, | ||
}); | ||
|
||
// Intercept file request | ||
networkActions.mockNetworkReq({ | ||
...API_ROUTES.file, | ||
dataOverride: file, | ||
}); | ||
|
||
// Intercept projects route | ||
networkActions.mockPaginatedNetworkReq({ | ||
...API_ROUTES.projectList, | ||
resDataOverride: { | ||
results: mirageServer | ||
.createRecordList('project', 1) | ||
.map((_) => ({ ..._, file: file['id'] })), | ||
}, | ||
}); | ||
|
||
// Return empty submissions data | ||
networkActions.mockPaginatedNetworkReq({ | ||
...API_ROUTES.submissionList, | ||
resDataOverride: { | ||
results: [], | ||
}, | ||
}); | ||
|
||
networkActions.loadAppConfigWithMockData(); | ||
|
||
cy.visit('/'); | ||
|
||
// Logs user to dashboard via API | ||
loginActions.doLoginWithUI({ username, password }); | ||
|
||
// Navigates to project listing route | ||
cy.url({ timeout: 15000 }).should('include', APPLICATION_ROUTES.projects); | ||
|
||
// Assertion for different dashboard elements | ||
cy.get(NAVBAR_LOCATORS.container); | ||
|
||
cy.get(NAVBAR_LOCATORS.startScanBtn).contains( | ||
APP_TRANSLATIONS.startNewScan | ||
); | ||
|
||
cy.get(NAVBAR_LOCATORS.profileBtn).contains(username); | ||
}); | ||
}); |
Oops, something went wrong.