Skip to content

About

Sample test automation project: WebdriverIO (UI) + PactumJS (API), with API+UI integration tests

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

WebdriverIO + PactumJS Sample Project

A sample test automation project demonstrating:

  • UI validations with WebdriverIO (browser automation)
  • API validations with PactumJS (REST API testing)

Both frameworks run independently against the public demo site the-internet.herokuapp.com, so the suite works out of the box with no backend setup.

What's under test

Layer Framework Target
UI WebdriverIO https://the-internet.herokuapp.com/login
API PactumJS https://the-internet.herokuapp.com (HTTP layer)

Project structure

.
├── package.json            # scripts + dependencies
├── wdio.conf.js            # WebdriverIO config (UI runner)
├── config/
│   └── constants.js        # shared BASE_URL, timeouts, credentials
├── constants/
│   └── waits/
│       └── constant_waits.js   # named wait durations
├── data/
│   └── contact.data.js     # test-data builders (externalized fixtures)
├── locators/               # selectors only ({ selector } objects, no behaviour)
│   ├── login/login.locator.js
│   ├── secure/secure.locator.js
│   ├── admin/admin.locator.js
│   └── contact/contact.locator.js
├── utils/
│   ├── wdio.js             # wdioHelper: wraps all WebdriverIO interactions
│   ├── booking-api.js      # PactumJS client (room integration test)
│   └── contact-api.js      # PactumJS client (contact integration test)
└── test/
    ├── pageobjects/        # Page Object Model: behaviour, talks to wdioHelper
    │   ├── page.js         #   base page
    │   ├── login.page.js
    │   ├── secure.page.js
    │   ├── admin.page.js
    │   └── contact.page.js
    ├── specs/              # UI / integration specs (run by WebdriverIO)
    │   ├── login.e2e.js
    │   ├── room.integration.e2e.js      # API + UI integration (rooms)
    │   └── contact.integration.e2e.js   # API + UI integration (contacts)
    └── api/                # API-only specs (run by Mocha + PactumJS)
        ├── status-codes.spec.js
        └── auth-and-redirects.spec.js

The two layers are kept separate on purpose:

  • WebdriverIO has its own test runner (wdio) and only picks up test/specs/**.
  • PactumJS is a plain library, so its specs run under Mocha and live in test/api/**.

UI layering (house style)

The project is CommonJS and the UI side follows a layered convention:

  • locators/ — selectors only, as { selector } objects under a flat elements map per page file, grouped by section comments (elements.USERNAME).
  • utils/wdio.js — wdioHelper, a thin wrapper over WebdriverIO (setValue, clickElement, getText, waitForElementVisible, isDisplayed, createDynamicLocator). Page objects never call $() or browser directly. This is a local stand-in for the internal bstackautomation-helpers/wdio package.
  • pageobjects/ — behaviour-only classes exported as singletons (module.exports.LoginPage = new LoginPage()), driving the helper with locators.

Prerequisites

  • Node.js (v18.20+ recommended) and npm
  • Google Chrome installed (WebdriverIO auto-manages the matching driver)

Setup

npm install

Configuration

Shared settings live in config/constants.js — the base URL, default API timeout, and demo credentials. Both the WebdriverIO config and the PactumJS specs import from there, so there is a single source of truth.

Point the suite at a different environment without touching code via the BASE_URL environment variable:

BASE_URL=https://staging.example.com npm test

Running the tests

# API tests only (PactumJS via Mocha)
npm run test:api

# UI tests only (WebdriverIO) — runs headless Chrome by default
npm run test:ui

# Everything (API then UI)
npm test

To watch the browser during UI runs, comment out the --headless=new line in the goog:chromeOptions.args array in wdio.conf.js.

What the tests cover

UI (test/specs/login.e2e.js)

  • Successful login with valid credentials
  • Rejection of an invalid username
  • Rejection of an invalid password

Built with the Page Object Model — selectors and actions live in test/pageobjects/, keeping specs readable and maintainable. Each test runs in a fresh browser session (browser.reloadSession() in beforeEach) so the tests stay independent and reliable against the free demo site.

API (test/api/)

  • status-codes.spec.js — landing page, /status_codes/200|404|500, and unknown-path 404 handling
  • auth-and-redirects.spec.js — HTTP Basic Auth (401 vs 200), redirect handling without auto-follow, and form login via POST /authenticate

These showcase common PactumJS features: expectStatus, expectHeader / expectHeaderContains, expectBodyContains, withAuth, withForm, and withFollowRedirects.

API + UI integration (test/specs/room.integration.e2e.js)

A single end-to-end flow against restful-booker-platform (an app with an admin API and an admin UI over the same data):

  1. API generates test data — POST /api/auth/login for a token, then POST /api/room to create a uniquely named room. A follow-up GET /api/room finds the new room and captures its id. (API chaining: token → create → list → id.)
  2. UI validates it — log into the admin panel and assert the room appears in the room list.
  3. API cleans up — DELETE /api/room/{id} and confirm the room is gone. Cleanup runs in an after hook, so it happens even if the UI step fails.

The API calls are encapsulated in utils/booking-api.js (PactumJS), and the UI uses the admin.page.js page object. PactumJS runs happily inside the WebdriverIO/Mocha spec, which is what lets a single test span both layers.

API + UI integration #2 (test/specs/contact.integration.e2e.js)

The same pattern against the Contact List App:

  1. API generates test data — POST /users registers a throwaway user (returns a token), then POST /contacts creates a contact and returns its id. (API chaining: register → token → add contact → id.)
  2. UI validates it — log in with the new user and assert the contact appears in the contact list.
  3. API cleans up — DELETE /contacts/{id} then DELETE /users/me.

API calls live in utils/contact-api.js; the UI uses contact.page.js. Each run uses a unique email, so the test is self-contained and repeatable.

About

Sample test automation project: WebdriverIO (UI) + PactumJS (API), with API+UI integration tests

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages