Skip to content

Commit

Permalink
Adding nightly testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Bradley committed Jan 7, 2025
1 parent bff44e3 commit ac6f335
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 60 deletions.
8 changes: 7 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ updates:
directory: "/"
# Check for updates once a week
schedule:
interval: "weekly"
interval: "daily"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "daily"
14 changes: 4 additions & 10 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- cron: '0 3 * * *' # Runs nightly at 3 AM UTC

jobs:
build-and-test:
run-tests:
runs-on: ubuntu-latest

steps:
Expand All @@ -18,7 +18,6 @@ jobs:
with:
node-version: 22

# 1) Install Chrome so Selenium can run
- name: Install Chrome
run: |
sudo apt-get update
Expand All @@ -27,11 +26,9 @@ jobs:
- name: Install dependencies
run: npm install

# 2) Spin up DynamoDB local on port 8000
- name: Start DynamoDB Local
run: docker run -d -p 8000:8000 amazon/dynamodb-local

# 3) Set environment vars so the AWS SDK points to local DynamoDB
- name: Set up env vars
run: |
echo "AWS_ACCESS_KEY_ID=FAKE_KEY" >> $GITHUB_ENV
Expand All @@ -40,21 +37,18 @@ jobs:
echo "DYNAMODB_ENDPOINT=http://127.0.0.1:8000" >> $GITHUB_ENV
echo "DYNAMODB_TABLE_NAME=RoomsTest" >> $GITHUB_ENV
# IMPORTANT: Make sure this matches the port your Express app uses
# If your app listens on 8081, set this to http://localhost:8081
echo "BASE_URL=http://localhost:3000" >> $GITHUB_ENV
echo "BASE_URL=http://localhost:8081" >> $GITHUB_ENV
echo "CI=true" >> $GITHUB_ENV
# 4) Start your Express app in the background
# By default your "npm start" runs on port 3000 or 8081—adjust sleep time as necessary
- name: Start server
run: |
npm start &
# Give the server a few seconds to spin up before running tests
sleep 5
# 5) Run your Jest-based unit tests
- name: Run unit tests
run: npm run unit-test

# 6) Run your Selenium + Cucumber integration tests
- name: Run integration tests
run: npm run integration-tests
125 changes: 76 additions & 49 deletions test/integration-tests/features/step_definitions/hotel_steps.js
Original file line number Diff line number Diff line change
@@ -1,115 +1,142 @@
const { setDefaultTimeout, Given, When, Then, After } = require('@cucumber/cucumber');
const { Builder, By, until } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome'); // <-- Add this import
const { openHomepage, verifyHomepageElements } = require('./helpers/homepageHelper');
const { openAddRoomPage, fillAddRoomForm, verifyAddRoomSuccess, verifyAddRoomFormFields, verifySubmitButton } = require('./helpers/addRoomHelper');
const { openRoomsPage, verifyRoomList, verifyRoomDetails, verifyTableColumns, verifyRoomsStoredAlert } = require('./helpers/roomsHelper');
const {
openAddRoomPage,
fillAddRoomForm,
verifyAddRoomSuccess,
verifyAddRoomFormFields,
verifySubmitButton
} = require('./helpers/addRoomHelper');
const {
openRoomsPage,
verifyRoomList,
verifyRoomDetails,
verifyTableColumns,
verifyRoomsStoredAlert
} = require('./helpers/roomsHelper');

let driver;

setDefaultTimeout(120 * 1000); // needed for the time it takes to spin up the remote web driver if used

// Function to build and return a WebDriver instance
const buildDriver = async () => {
const gridUrl = process.env.GRID_URL || null;

if (gridUrl) {
console.log(`Using Selenium Grid at: ${gridUrl}`);
driver = await new Builder()
.usingServer(gridUrl) // Use the Selenium Grid URL here
.forBrowser('chrome')
.build();
} else {
// If no GRID_URL is set, run the browser locally
driver = await new Builder().forBrowser('chrome').build();
const gridUrl = process.env.GRID_URL || null;

if (gridUrl) {
console.log(`Using Selenium Grid at: ${gridUrl}`);
driver = await new Builder()
.usingServer(gridUrl) // Use the Selenium Grid URL here
.forBrowser('chrome')
.build();
} else {
// If no GRID_URL is set, run the browser locally
let options = new chrome.Options();

if (process.env.CI) {
// Running in CI: add headless flags
options = options
.headless()
.addArguments('--disable-gpu')
.addArguments('--no-sandbox')
.addArguments('--disable-dev-shm-usage');
}

// Common settings for the driver
await driver.manage().setTimeouts({ implicit: 10000 });
await driver.manage().window().setRect({ width: 1920, height: 1080 }); // Full HD resolution
driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
}

// Common settings for the driver
await driver.manage().setTimeouts({ implicit: 10000 });
await driver.manage().window().setRect({ width: 1920, height: 1080 }); // Full HD resolution
};

// Step Definitions
Given('I am on the homepage', async function () {
await buildDriver(); // Create WebDriver instance
const baseUrl = process.env.BASE_URL || 'http://localhost:3000';
await openHomepage(driver, baseUrl); // Use helper function to open the homepage
await buildDriver(); // Create WebDriver instance
const baseUrl = process.env.BASE_URL || 'http://localhost:3000';
await openHomepage(driver, baseUrl); // Use helper function to open the homepage
});

Then('I should see the page title {string}', async function (title) {
await verifyHomepageElements(driver, 'title', title); // Use helper function to verify the title
await verifyHomepageElements(driver, 'title', title); // Use helper function to verify the title
});

Then('I should see a navbar with {string}, {string}, and {string} options', async function (home, rooms, add) {
await verifyHomepageElements(driver, 'navbar'); // Use helper function to verify the navbar with the given options
await verifyHomepageElements(driver, 'navbar'); // Use helper function to verify the navbar
});

Then('I should see the heading {string}', async function (headingText) {
await verifyHomepageElements(driver, 'heading', headingText); // Use helper function to verify the heading
await verifyHomepageElements(driver, 'heading', headingText); // Use helper function to verify the heading
});

When('I click on {string} in the navbar', async function (linkText) {
if (linkText === "Rooms") {
await openRoomsPage(driver); // Use helper to open the Rooms page
} else if (linkText === "Add") {
await openAddRoomPage(driver); // Use helper to open the Add Room page
} else {
throw new Error(`Link text ${linkText} is not supported.`);
}
if (linkText === "Rooms") {
await openRoomsPage(driver); // Use helper to open the Rooms page
} else if (linkText === "Add") {
await openAddRoomPage(driver); // Use helper to open the Add Room page
} else {
throw new Error(`Link text ${linkText} is not supported.`);
}
});

Then('I should be on the {string} page', async function (pageTitle) {
await verifyRoomList(driver, 'title', pageTitle); // Use helper function to verify the page title
await verifyRoomList(driver, 'title', pageTitle); // Use helper function to verify the page title
});

Then('I should see a table with the list of rooms', async function () {
await verifyRoomList(driver, 'room_table'); // Use helper function to verify room table is present
await verifyRoomList(driver, 'room_table'); // Use helper function to verify room table is present
});

Then('the table should contain columns for {string}, {string}, and {string}', async function (column1, column2, column3) {
await verifyTableColumns(driver); // Use helper function to verify table columns
await verifyTableColumns(driver); // Use helper function to verify table columns
});

When('I enter {string} in the {string} field', async function (value, fieldName) {
if (fieldName === "Room number") {
await fillAddRoomForm(driver, "room_number", value);
} else if (fieldName === "Floor number") {
await fillAddRoomForm(driver, "floor_number", value);
} else {
throw new Error(`Unsupported field name: ${fieldName}`);
}
if (fieldName === "Room number") {
await fillAddRoomForm(driver, "room_number", value);
} else if (fieldName === "Floor number") {
await fillAddRoomForm(driver, "floor_number", value);
} else {
throw new Error(`Unsupported field name: ${fieldName}`);
}
});

When('I select {string} from the "Good View" dropdown', async function (value) {
await fillAddRoomForm(driver, "good_view", value);
await fillAddRoomForm(driver, "good_view", value);
});

When('I click the "Add room" button', async function () {
await fillAddRoomForm(driver, "submit");
await fillAddRoomForm(driver, "submit");
});

Then('the new room should be added successfully', async function () {
await verifyAddRoomSuccess(driver);
await verifyAddRoomSuccess(driver);
});

Then('I should see a room with the room number {string}, on floor {string}, with {string} under Good View', async function (roomNumber, floorNumber, viewStatus) {
await verifyRoomDetails(driver, roomNumber, floorNumber, viewStatus);
await verifyRoomDetails(driver, roomNumber, floorNumber, viewStatus);
});

Then('I should see an alert displaying the number of rooms stored in the database', async function () {
await verifyRoomsStoredAlert(driver);
await verifyRoomsStoredAlert(driver);
});

Then('I should see a form with fields for {string}, {string}, and {string}', { timeout: 20000 }, async function (field1, field2, field3) {
await verifyAddRoomFormFields(driver);
await verifyAddRoomFormFields(driver);
});

Then('I should see a submit button labeled {string}', { timeout: 20000 }, async function (buttonLabel) {
await verifySubmitButton(driver, buttonLabel);
await verifySubmitButton(driver, buttonLabel);
});

// Tear Down
After(async function () {
if (driver) {
await driver.quit();
}
if (driver) {
await driver.quit();
}
});

0 comments on commit ac6f335

Please sign in to comment.