Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/implement owasp zap baseline scan GitHub actions #6

Open
wants to merge 42 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
505bb26
Cloned feature/alerts-and-frames into feature/alerts-and-frames-with-…
aasimsyed Apr 13, 2024
4dd5baf
installed the 'cypress-iframe' plugin to do Lesson 4.2 tests
aasimsyed Apr 13, 2024
1294ff5
revised the frames test to utilized the 'cypress-iframe' plugin
aasimsyed Apr 13, 2024
95cff28
added 'chromeWebSecurity: false' for Sauce Demo page workaround
aasimsyed Apr 14, 2024
4d57305
added Sauce Demo credentials and AdBlock URLs in fixtures
aasimsyed Apr 14, 2024
38d4d21
refactored 'visitWithAdBlocker' to use fixture file
aasimsyed Apr 14, 2024
d3b50d3
added Sauce Demo spec
aasimsyed Apr 14, 2024
295ff6b
added error handling to commands.js
aasimsyed Apr 14, 2024
9bb6caa
using the https URL
aasimsyed Apr 14, 2024
20dfee0
removed placeholder comments
aasimsyed Apr 14, 2024
ae159bc
suppressing logs for the blocked external scripts
aasimsyed Apr 14, 2024
d5b43e0
removed a comment
aasimsyed Apr 14, 2024
16666cd
optimized
aasimsyed Apr 14, 2024
d7d2d24
optimized the alerts/frames specs
aasimsyed Apr 14, 2024
61ded08
separated e2e and api tests into respective directories and updated c…
aasimsyed Apr 16, 2024
082c7af
removed example.json; added apiRequest() and createBooking() commands
aasimsyed Apr 16, 2024
63acdb9
updated no cache visit commmand
aasimsyed Apr 16, 2024
3f27701
added fixture for booking; created getToken function; added specs for…
aasimsyed Apr 16, 2024
9e889a8
added ajv for schema validation
aasimsyed Apr 16, 2024
00f5591
added schema validation library
aasimsyed Apr 17, 2024
c574b7b
added schema files based on API docs
aasimsyed Apr 17, 2024
75f2fc7
added fixture for udpate methods
aasimsyed Apr 17, 2024
28ba3d5
added schema compile/validate function
aasimsyed Apr 17, 2024
29a0068
updated auth token in apiRequest, added deleteBooking
aasimsyed Apr 17, 2024
abba6d8
updated getNewToken to use baseUrl
aasimsyed Apr 17, 2024
16fe7b4
package files
aasimsyed Apr 17, 2024
3dfce7b
implemented all the api test spec files
aasimsyed Apr 17, 2024
2e655cc
added README.md
aasimsyed Apr 17, 2024
1902ef5
added PR link to README
aasimsyed Apr 17, 2024
fcfc285
fixed typo
aasimsyed Apr 17, 2024
7c08778
added yml blank file
aasimsyed Apr 20, 2024
dc8cfe1
inital Github Actions file
aasimsyed Apr 20, 2024
b63b42b
remove --record
aasimsyed Apr 20, 2024
de12029
removed group, parallel flags
aasimsyed Apr 20, 2024
8f945d2
separated api and e2e tests to run on separate containers
aasimsyed Apr 20, 2024
ce99509
use Cypress binary from cache if found, else install cypress
aasimsyed Apr 20, 2024
cbecae4
Attempt to fix Cypress caching check
aasimsyed Apr 20, 2024
0e7c0a8
install Cypress
aasimsyed Apr 20, 2024
a476abb
Updated README for Lesson 7: Topic 5 assignment
aasimsyed Apr 20, 2024
161197d
added OWASP ZAP Scan for Juice Shop on Push
aasimsyed Apr 30, 2024
680e9c0
added report to scan action
aasimsyed Apr 30, 2024
8aa06b2
fixing permissions
aasimsyed Apr 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
22 changes: 22 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: CI

on:
push:
branches:
- feature/implement-owasp-zap-baseline-scan-github-actions

jobs:
zap_scan:
permissions: write-all
runs-on: ubuntu-latest
name: OWASP ZAP Baseline Scan of OWASP Juice Shop
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Run OWASP ZAP Baseline Scan
uses: zaproxy/[email protected]
with:
target: "https://juice-shop.herokuapp.com/#"
artifact_name: "zap_report.html"

10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# coding-temple-cypress-playground
# Integrating GitHub Actions into an Existing GitHub Repo

## Overview

The objective of this project is to integrate GitHub Actions into your existing GitHub project.

## GitHub Actions Run

- [GitHub Actions Run](https://github.com/aasimsyed/coding-temple-cypress-playground/actions/runs/8761555437)
13 changes: 11 additions & 2 deletions cypress.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@ const { defineConfig } = require("cypress");

module.exports = defineConfig({
e2e: {
env: {
restfulBookerUrl: 'https://restful-booker.herokuapp.com'
},
chromeWebSecurity: false,
supportFile: 'cypress/support/commands.js',
specPattern: [
'cypress/integration/e2e/**/*.spec.js',
'cypress/integration/api/**/*.spec.js'
],
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
}
}
});
12 changes: 12 additions & 0 deletions cypress/fixtures/adBlockerUrls.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"blockAds": "https://pagead2.googlesyndication.com/**",
"blockGpt": "https://www.googletagservices.com/tag/js/gpt.js",
"blockGtm": "https://www.googletagmanager.com/gtm.js?id=GTM-MX8DD4S",
"blockAdPlus": "https://cdn.ad.plus/player/adplus.js",
"blockBacktrace": "https://events.backtrace.io/**",
"blockGif": "**/*.gif",
"blockUserMatch": "**/usermatch.gif**",
"blockMerge": "**/merge**",
"blockScripts": "**/*.js"
}

11 changes: 11 additions & 0 deletions cypress/fixtures/bookingDetails.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"firstname": "Jim",
"lastname": "Brown",
"totalprice": 111,
"depositpaid": true,
"bookingdates": {
"checkin": "2021-01-01",
"checkout": "2021-01-02"
},
"additionalneeds": "Breakfast"
}
36 changes: 36 additions & 0 deletions cypress/fixtures/credentials.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"users": {
"standardUser": {
"username": "standard_user",
"password": "secret_sauce"
},
"lockedOutUser": {
"username": "locked_out_user",
"password": "secret_sauce"
},
"problemUser": {
"username": "problem_user",
"password": "secret_sauce"
},
"performanceGlitchUser": {
"username": "performance_glitch_user",
"password": "secret_sauce"
},
"invalidUser": {
"username": "invalid_user",
"password": "secret_sauce"
},
"noPassword": {
"username": "standard_user",
"password": ""
},
"invalidPassword": {
"username": "standard_user",
"password": "invalid_password"
},
"noUsername": {
"username": "",
"password": "secret_sauce"
}
}
}
5 changes: 0 additions & 5 deletions cypress/fixtures/example.json

This file was deleted.

11 changes: 11 additions & 0 deletions cypress/fixtures/updateBookingDetails.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"firstname": "UpdatedFirstName",
"lastname": "UpdatedLastName",
"totalprice": 200,
"depositpaid": false,
"bookingdates": {
"checkin": "2023-01-10",
"checkout": "2023-01-15"
},
"additionalneeds": "Late checkout"
}
61 changes: 61 additions & 0 deletions cypress/integration/api/createBooking.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { getNewToken } from '../../support/utils';
import { compileSchema } from '../../support/ajv-utils';

describe('CreateBooking API Test', () => {
before(() => {
// Load and compile schemas
cy.readFile('cypress/schemas/createBookingRequest.json')
.then(compileSchema).as('validateRequest');
cy.readFile('cypress/schemas/createBookingResponse.json')
.then(compileSchema).as('validateResponse');
cy.log('Schemas compiled successfully.');

// Load booking details
cy.fixture('bookingDetails.json').as('bookingData');

// Retrieve a new token and store as alias
getNewToken().then(cy.wrap).as('token');
});

after(() => {
// Clean up: delete the booking created in the before hook
cy.get('@token').then(token => {
cy.get('@bookingId').then(bookingId => {
if (bookingId && token) {
cy.log('Cleaning up: deleting the booking created in the before hook');
cy.deleteBooking(bookingId, token).then(response => {
expect(response.status).to.eq(201);
cy.log(`Booking with ID: ${bookingId} deleted successfully.`);
});
} else {
cy.log('No booking ID or token available for cleanup.');
}
});
});
});

it('should create a new booking and validate the response matches the request', function () {
// Use aliases to ensure data is loaded before executing the test
cy.get('@token').then(token => {
cy.get('@bookingData').then(bookingData => {
cy.log('Creating a new booking with the provided details');
cy.createBooking(bookingData, token).then(response => {
expect(response.status).to.eq(200);
cy.log('Booking created with status:', response.status);

// Validate response schema
cy.get('@validateResponse').then(validateResponse => {
if (!validateResponse(response.body)) {
const errors = validateResponse.errors.map(err => `${err.instancePath} ${err.message}`).join(', ');
throw new Error(`Response validation failed: ${errors}`);
}
cy.log('Response schema validation passed.');

// Store the bookingId for cleanup
cy.wrap(response.body.bookingid).as('bookingId');
});
});
});
});
});
});
31 changes: 31 additions & 0 deletions cypress/integration/api/createToken.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { compileSchema } from '../../support/ajv-utils';

describe('CreateToken API Test', () => {
before(() => {
// Load and compile the schema, then store it as an alias for use in the tests
cy.readFile('cypress/schemas/createTokenResponse.json')
.then(compileSchema)
.as('validateTokenSchema'); // Storing the compiled schema as an alias
cy.log('Token schema compiled and stored as an alias.');
});

it('should create a new auth token', () => {
cy.apiRequest('POST', '/auth', null, {
username: 'admin',
password: 'password123',
}).then((response) => {
expect(response.status).to.eq(200);
cy.log('Auth token created, validating response...');

// Use the alias for the schema to validate the response
cy.get('@validateTokenSchema').then((validate) => {
const validationResult = validate(response.body);
if (!validationResult) {
const errors = validate.errors.map(err => `${err.instancePath} ${err.message}`).join(', ');
throw new Error(`Validation error: ${errors}`);
}
cy.log('Response validated successfully against the schema.');
});
});
});
});
47 changes: 47 additions & 0 deletions cypress/integration/api/deleteBooking.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { getNewToken } from '../../support/utils';
import { compileSchema } from '../../support/ajv-utils';

describe('Delete Booking by ID API Tests', () => {
let validateResponse, bookingId, token;

before(() => {
// Compile the response schema
cy.readFile('cypress/schemas/deleteBookingResponse.json')
.then(compileSchema)
.then((compiledSchema) => {
validateResponse = compiledSchema;
cy.log('Response schema compiled successfully.');
});

// Retrieve authentication token
getNewToken().then((receivedToken) => {
cy.wrap(receivedToken).as('token');
cy.log('Authentication token retrieved:', token);

// Load booking details from a fixture and create a booking
cy.fixture('bookingDetails.json').then((bookingDetails) => {
cy.createBooking(bookingDetails, token).then((response) => {
expect(response.status).to.eq(200);
bookingId = response.body.bookingid;
cy.wrap(bookingId).as('bookingId');
cy.log(`New booking created with ID: ${bookingId}`);
});
});
});
});

it('should delete a booking by ID', () => {
cy.get('@token').then((token) => {
cy.get('@bookingId').then((bookingId) => {
if (bookingId && token) {
cy.deleteBooking(bookingId, token).then(response => {
expect(response.status).to.eq(201);
cy.log(`Booking with ID: ${bookingId} deleted successfully.`);
});
} else {
cy.log('No booking ID or token available for cleanup.');
}
});
});
});
});
65 changes: 65 additions & 0 deletions cypress/integration/api/getBooking.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { getNewToken } from '../../support/utils';
import { compileSchema } from '../../support/ajv-utils';

describe('Get Booking by ID API Tests', () => {
let validateResponse, bookingId, token;

before(() => {
// Compile the response schema
cy.readFile('cypress/schemas/getBookingByIdResponse.json')
.then(compileSchema)
.then((compiledSchema) => {
validateResponse = compiledSchema;
cy.log('Response schema compiled successfully.');
});

// Retrieve authentication token
getNewToken().then((receivedToken) => {
cy.wrap(receivedToken).as('token');
cy.log('Authentication token retrieved:', token);

// Load booking details from a fixture and create a booking
cy.fixture('bookingDetails.json').then((bookingDetails) => {
cy.createBooking(bookingDetails, token).then((response) => {
expect(response.status).to.eq(200);
bookingId = response.body.bookingid;
cy.wrap(bookingId).as('bookingId');
cy.log(`New booking created with ID: ${bookingId}`);
});
});
});
});

after(() => {
// Retrieve 'token' and 'bookingId' from aliases
cy.get('@token').then((token) => {
cy.get('@bookingId').then((bookingId) => {
if (bookingId && token) {
cy.log('Cleaning up: deleting the booking created in the before hook');
// Clean up: delete the booking created in the before hook
cy.deleteBooking(bookingId, token).then(response => {
expect(response.status).to.eq(201);
cy.log(`Booking with ID: ${bookingId} deleted successfully.`);
});
} else {
cy.log('No booking ID or token available for cleanup.');
}
});
});
});

it('should retrieve a booking by ID', () => {
cy.apiRequest('GET', `/booking/${bookingId}`, token).then((response) => {
expect(response.status).to.eq(200);
cy.log(`Booking retrieved for ID ${bookingId}:`, JSON.stringify(response.body));

// Validate the response against the compiled schema
const validationResult = validateResponse(response.body);
if (!validationResult) {
const errors = validateResponse.errors.map(err => `${err.instancePath} ${err.message}`).join(', ');
throw new Error(`Response validation failed: ${errors}`);
}
cy.log('Response schema validation passed.');
});
});
});
38 changes: 38 additions & 0 deletions cypress/integration/api/getBookingIds.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { compileSchema } from '../../support/ajv-utils';

describe('Get Booking IDs API Tests', () => {
let validateResponse;

before(() => {
// Load and compile the schema for response validation
cy.readFile('cypress/schemas/getBookingIdsResponse.json')
.then(compileSchema)
.then((compiledSchema) => {
validateResponse = compiledSchema;
cy.log('Response schema compiled successfully.');
});

cy.log('Starting tests for the GetBookingIds endpoint');
});

// Helper function to perform API request and validate the response
const testBookingRetrieval = (description, queryParams = {}) => {
it(`should retrieve bookings ${description}`, () => {
cy.apiRequest('GET', '/booking', null, null, queryParams).then((response) => {
expect(response.status).to.eq(200);
if (!validateResponse(response.body)) {
const errors = validateResponse.errors.map(err => `${err.instancePath} ${err.message}`).join(', ');
throw new Error(`Response validation failed: ${errors}`);
}
cy.log(`Bookings ${description}:`, JSON.stringify(response.body));
});
});
};

// Test cases using the helper function
testBookingRetrieval('for all booking IDs');
testBookingRetrieval('by first name', { firstname: 'Jim' });
testBookingRetrieval('by last name', { lastname: 'Brown' });
testBookingRetrieval('by check-in date', { checkin: '2021-01-01' });
testBookingRetrieval('by check-out date', { checkout: '2021-01-02' });
});
8 changes: 8 additions & 0 deletions cypress/integration/api/healthCheck.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
describe('Health Check API Test', () => {
it('Ping the API for a health check', () => {
cy.apiRequest('GET', '/ping').then((response) => {
expect(response.status).to.eq(201); // Expecting a 201 status as per your API docs
cy.log('API health check response status:', response.status);
});
});
});
Loading
Loading