Tech Plan: Refactor Automation Framework

Tech Plan: Refactor Automation Framework

Tech Plan: Refactor Automation Framework for Maintainability & Multi-Environment Support

 

Date: 14-Aug-2025

Status: In Progress

Jira Ticket: https://readyedu.atlassian.net/browse/CG-7872

Framework: CodeceptJS with JavaScript

CI Tool: GitHub Actions

 

🎯 Objective

Refactor the existing CodeceptJS framework to improve maintainability, clarity, and enable running tests across multiple environments (acceptance, test01, prod). This includes cleaning up smoke tests, centralizing reusable steps, organizing locators better, supporting multi-environment configs, and managing user data efficiently.

 

1. 🧪 Smoke Testing Tags

✅ Why this is needed

  • Current smoke tests have duplicate scenarios.

  • Tagging is inconsistent, causing unreliable smoke runs.

  • A focused smoke suite ensures quick validation of critical flows.

🔧 Action Items

  • Review existing smoke test .feature files.

  • Remove tests already covered by other feature files. If not covered, move the tests to the correct feature folder

  • Add @smoke tags only to essential test cases

  • Update the CodeceptJS config and CI scripts to run tests filtered by @smoke.

 

⚙️ How we’ll do it

  • Audit smoke tests for duplication or irrelevance.

  • Tag essential scenarios with @smoke.

  • Use CodeceptJS’s --grep @smoke flag to run smoke suite selectively.

📦 Deliverables

  • Cleaned and updated smoke tests in their respective feature files

  • Consistent use of @smoke tags

  • CI pipeline configured to run smoke tests efficiently

📈 What it improves

  • Faster CI feedback for critical tests

  • Reduced noise from redundant tests

  • Clearer test ownership and focus

 


 

2. ♻️ Reusable Step Definitions

✅ Why this is needed

  • Step definitions are duplicated across feature files.

  • Maintenance becomes error-prone and slow with repeated steps.

🔧 Action Items

  • Identify commonly used steps (e.g., login, navigation).

  • Move these into a shared step definition file common_steps.js.

  • Refactor feature-specific step files to import and reuse these shared steps.

⚙️ How we’ll do it

  • Extract reusable steps into common_steps.js.

  • Replace duplicates with imports from this shared file.

  • Maintain consistent step phrasing for readability.

📦 Deliverables

  • common_steps.js file with common steps

  • Refactored feature step files

  • Updated project documentation if needed

📈 What it improves

  • Easier to maintain step definitions

  • Consistent test behavior across features

  • Reduced duplication and cleaner codebase

 


 

3. 📍 Centralized Locators (CodeceptJS)

✅ Why this is needed

  • Locators are scattered and sometimes duplicated.

  • UI changes require updates in multiple places.

  • Centralized locators improve maintainability and clarity.

🔧 Action Items

  • Create a locators/ folder in the project.

  • Organize locator files by feature/module:

    • commonLocators.js for shared UI elements

    • eventsLocators.js for Events feature

    • gradesLocators.js for Grades feature

    • groupsLocators.js for Groups feature

  • Export locators using module.exports = {}.

  • Refactor page objects and steps to require() locators from these files.

⚙️ How we’ll do it

Folder Structure:

locators/

├── commonLocators.js

├── eventsLocators.js

├── gradesLocators.js

└── groupsLocators.js

 

Example: eventsLocators.js

Module.exports = {

  createEventButton: locate('button').withText('Create Event'),

  eventTitleInput: '#event-title',

  datePicker: '.datepicker',

};

 

Example: commonLocators.js

module.exports = {

  header: '.main-header',

  footer: '.main-footer',

  toastMessage: '.toast-message',

  modalCloseButton: '.modal-close',

  loader: '.spinner',

};

 

Using locators in a page object or step file:

const { I } = inject();

const eventsLocators = require('../locators/eventsLocators');

const commonLocators = require('../locators/commonLocators');

 

module.exports = {

  createNewEvent() {

    I.click(eventsLocators.createEventButton);

    I.fillField(eventsLocators.eventTitleInput, 'Test Event');

    I.click(commonLocators.modalCloseButton);

  }

};

 

📦 Deliverables

  • Organized locators/ folder with feature-based locator files

  • Refactored page objects and step files using these locators

📈 What it improves

  • Simplifies updates when UI changes

  • Reduces duplication of selectors

  • Improves clarity and maintainability of tests

 


 

4. 🌐 Multi-Environment Setup (using .env files)

✅ Why this is needed

  • Each environment (acceptance, test01, prod) requires different URLs, credentials, and config.

  • Managing these settings in separate .env files keeps them clean and easy to switch.

🔧 Action Items

  • Create .env files named exactly per environment:

    • acceptance.env

    • test01.env

    • prod.env

  • Use the dotenv package to load the correct file dynamically based on the ENV variable.

  • Update framework config and CI to respect the chosen environment.

⚙️ How we’ll do it

  • Sample code to load the environment:
    const dotenv = require('dotenv');
    const env = process.env.ENV || 'acceptance';  // default environment
    dotenv.config({ path: `${env}.env` });

  • Access config values via process.env in tests and config files.

  • Make sure CI sets the ENV variable correctly before running tests.

📦 Deliverables

  • .env files named as acceptance.env, test01.env, prod.env with environment-specific settings

  • Dynamic .env loading in test setup

  • Updated codecept.conf.js to use process.env variables

📈 What it improves

  • Clear separation of environment configs

  • Easy switching of environments with just one env var change

  • Avoids hardcoding sensitive info in code

 


 

5. 👤 User Data Configuration (via .env files)

✅ Why this is needed

  • User credentials and test data vary per environment.

  • Keeping user data in environment-specific .env files aligns test data with environment config.

  • Avoids hardcoding sensitive info in the codebase.

🔧 Action Items

  • Store user credentials and other environment-specific test data in the same .env files, e.g.:

    • acceptance.env

    • test01.env

    • prod.env

  • Refactor user data helper module to read from process.env.

  • Update step definitions and tests to use this centralized user data source.

⚙️ How we’ll do it

  • Sample variables in acceptance.env:

TEST_ENV=acceptance

BASE_URL=https://qa.campusgroups.com

HEADLESS=true

ADMIN_EMAIL=admin_email

ADMIN_PASSWORD=acceptPass123

TEST_USER_EMAIL=testuser_email

TEST_USER_PASSWORD=testPass123

 

 

Example userData.js helper module:

module.exports = {

  admin: {

    username: process.env.ADMIN_EMAIL,

    password: process.env.ADMIN_PASSWORD,

  },

  user: {

    username: process.env.TEST_USER_EMAIL,

    password: process.env.TEST_USER_PASSWORD,

  }

};

In tests or step files, require userData.js and use the properties for login and other operations.

📦 Deliverables

  • User credentials and test data in environment-specific .env files (acceptance.env, etc.)

  • userData.js module reading from process.env

  • Tests refactored to consume centralized user data

📈 What it improves

  • Environment-specific test data management

  • Enhanced security by not hardcoding sensitive data

  • Easier updates and consistency across environments

 


 

📁 Final Proposed Folder Structure

.

├── locators/

│   ├── commonLocators.js

│   ├── eventsLocators.js

│   ├── gradesLocators.js

│   └── groupsLocators.js

├── steps/

│   ├── common_steps.js

│   └── [feature]_steps.js

├── env/

│   ├── env.acceptance.js

│   ├── env.test01.js

│   └── env.prod.js

├── data/

│   └── userData.js

├── pages/

│   └── [pageObjects].js

├── features/

│ └──smokeTests/

│ └── smoke.feature

└── codecept.conf.js

 


 

✅ Testing Strategy

  • Run full regression locally after each refactor step.

  • Validate smoke tests run correctly with --grep @smoke.

  • Test all environments by switching ENV variables and confirming tests run successfully.

  • Review logs and reports for consistent test behavior.

 


 

📌 Final Notes

  • Align smoke tests with product feature areas and corresponding feature folders. Create or reorganize feature folders as needed for better coverage and clarity. 
    Reference: https://readyedu.atlassian.net/wiki/spaces/PROD/pages/505249797

  • All changes will be pushed in small, reviewable PRs.

  • Backward compatibility will be maintained.

  • README and Confluence will be updated with new folder and config structures.