npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@feminashajahan/nextest

v1.0.1

Published

Cross Platform Mobile Test Framework (Android + iOS) | Appium + Playwright + Cucumber + TypeScript

Downloads

153

Readme

WTHR Mobile Automation Framework

Cross-platform mobile test automation for the WTHR app (Android + iOS), built with:

  • Appium 2 — native mobile automation (UiAutomator2 / XCUITest)
  • Playwright — web / WebView automation (Safari, Chromium, WebKit)
  • Cucumber.js — BDD with Gherkin feature files
  • TypeScript — fully typed framework
  • WebdriverIO — Appium client

Project Structure

UnifiedUIAutomation/
├── cucumber.js                        # Cucumber runner config (parallel, tags, paths)
├── package.json                       # Dependencies & npm scripts
├── tsconfig.json                      # TypeScript compiler config
├── .env.example                       # All supported environment variables
│
├── src/
│   ├── config/
│   │   ├── appiumCapabilities.ts      # All Appium capability sets + smart selector
│   │   └── playwrightConfig.ts        # Playwright browser launch options
│   │
│   ├── core/                          # Reusable action + assertion libraries
│   │   ├── AppiumActions.ts           # tap, swipe, scroll, gestures, wait…
│   │   ├── PlaywrightActions.ts       # navigate, click, fill, scroll, screenshot…
│   │   └── Assertions.ts             # Unified assertions (Appium + Playwright + generic)
│   │
│   ├── drivers/
│   │   └── DriverManager.ts           # Singleton manager for Appium + Playwright sessions
│   │
│   ├── utils/
│   │   ├── PlatformManager.ts         # isAndroid() / isIOS() helpers
│   │   ├── ReportManager.ts           # Console logging + screenshot + JSON run log
│   │   └── ScreenRecordingUtil.ts     # Start/stop MP4 recording per scenario
│   │
│   └── test/                          # All test-specific code
│       ├── features/
│       │   └── wthr/
│       │       └── Wthr13.feature     # Gherkin scenarios
│       ├── hooks/
│       │   └── hooks.ts               # Before / After lifecycle hooks
│       ├── pages/
│       │   ├── BasePage.ts            # Base page with appium + pw + assert
│       │   └── wthr/
│       │       └── InitialPage.ts     # WTHR app page object
│       ├── steps/
│       │   └── wthr/
│       │       └── Wthr13Steps.ts     # Cucumber step definitions
│       └── world/
│           └── CustomWorld.ts         # Cucumber World (driver + playwrightPage)
│
└── scripts/
    └── generate-report.ts             # Merges worker JSONs → HTML report

Prerequisites

| Tool | Version | Purpose | |---|---|---| | Node.js | ≥ 18 | Runtime | | Appium | 2.x | Mobile automation server | | Appium UiAutomator2 driver | latest | Android | | Appium XCUITest driver | latest | iOS | | Android SDK / ADB | latest | Emulator / device management | | Xcode | ≥ 15 | iOS Simulator / real device | | Java | ≥ 11 | Appium dependency |

Install Appium and drivers

npm install -g appium
appium driver install uiautomator2
appium driver install xcuitest

Setup

1. Install dependencies

npm install

2. Install Playwright browsers

npm run install:browsers

3. Configure environment

cp .env.example .env
# Edit .env with your device details, BrowserStack credentials, etc.

4. Start Appium server

appium --port 4723

Environment Variables

| Variable | Default | Description | |---|---|---| | PLATFORM | android | android or ios. Optional when using npm scripts — already set inside each script. | | EXECUTION_TARGET | emulator (Android) / simulator (iOS) | emulator, simulator, local-device, browserstack | | TAGS | @mobileApp | Cucumber tag filter | | PARALLEL_WORKERS | 1 | Number of concurrent workers | | UDID | emulator-5554 | Single device UDID (overrides auto-assign) | | DEVICE_POOL | (auto) | Comma-separated UDIDs for parallel runs | | APPIUM_HOST | 127.0.0.1 | Appium server host | | APPIUM_PORT | 4723 | Appium server port | | IOS_DEVICE_NAME | iPhone 17 Pro | iOS simulator / device name | | IOS_VERSION | (auto) | iOS platform version — omit to let Appium auto-select | | DEVICE_NAME | Android Device | Display name for physical Android device | | XCODE_ORG_ID | (required for real device) | Apple Team ID for code signing | | WDA_BUNDLE_ID | (optional) | Custom WDA bundle ID | | BROWSERSTACK_USERNAME | — | BrowserStack credentials | | BROWSERSTACK_ACCESS_KEY | — | BrowserStack credentials | | BS_APP_URL | — | bs:// app URL after uploading to BrowserStack | | BS_ANDROID_DEVICE | Samsung Galaxy S23 | BS Android device name | | BS_ANDROID_VERSION | 13.0 | BS Android OS version | | BS_IOS_DEVICE | iPhone 15 Pro | BS iOS device name | | BS_IOS_VERSION | 17 | BS iOS version | | BS_PROJECT | WTHR Mobile Automation | BrowserStack project name | | BS_BUILD | (auto-generated) | BrowserStack build name |

Note: PLATFORM is baked into every npm run test:android* / npm run test:ios* script. You only need to set it manually when running cucumber-js directly or overriding the default (android).


Running Tests

Android Emulator

# All scenarios
npm run test:android

# Filter by tag
TAGS=@mobileApp  npm run test:android    # video playback full flow
TAGS=@mobileApp2 npm run test:android    # video icon + menu + suggest
TAGS=@mobileApp3 npm run test:android    # scroll to page end

# With HTML report generated after the run
TAGS=@mobileApp2 npm run test:android:report

iOS Simulator

# All scenarios
npm run test:ios

# Filter by tag
TAGS=@mobileApp  npm run test:ios        # video playback full flow
TAGS=@mobileApp2 npm run test:ios        # video icon + menu + suggest
TAGS=@mobileApp3 npm run test:ios        # scroll to page end (Safari via Playwright)

# With HTML report
TAGS=@mobileApp3 npm run test:ios:report

Physical Device

# Android physical device
EXECUTION_TARGET=local-device UDID=<device-udid> npm run test:android

# iOS physical device
EXECUTION_TARGET=local-device UDID=<device-udid> npm run test:ios

With HTML report

npm run test:android:report
npm run test:ios:report

Parallel Execution

Cucumber.js spawns each worker as a separate Node.js process. Each worker gets its own Appium session, device, and report log.

Android Emulators in parallel

Start the required number of AVDs before running. UDIDs are auto-assigned: worker 0 → emulator-5554, worker 1 → emulator-5556, …

# Start 3 emulators (in separate terminals or via emulator CLI)
emulator -avd Pixel_7_API_34 -port 5554 &
emulator -avd Pixel_7_API_34 -port 5556 &
emulator -avd Pixel_7_API_34 -port 5558 &

# Run with 3 workers
npm run test:android:parallel
# equivalent: PLATFORM=android PARALLEL_WORKERS=3 cucumber-js

iOS Simulators in parallel

Boot simulators first, then supply their UDIDs via DEVICE_POOL.

xcrun simctl list devices | grep "iPhone 17 Pro"

EXECUTION_TARGET=simulator \
DEVICE_POOL=<udid1>,<udid2>,<udid3> \
PARALLEL_WORKERS=3 \
npm run test:ios:parallel

Physical devices in parallel

EXECUTION_TARGET=local-device \
DEVICE_POOL=R3CN30XXXXX,R5CT10XXXXX \
PARALLEL_WORKERS=2 \
npm run test:android:parallel

BrowserStack — cloud parallel

No device management needed. BrowserStack handles concurrency.

# Android — 5 parallel cloud sessions
npm run test:browserstack:android

# iOS — 5 parallel cloud sessions
npm run test:browserstack:ios

# Custom device + OS version
EXECUTION_TARGET=browserstack \
BS_ANDROID_DEVICE="Google Pixel 8" \
BS_ANDROID_VERSION="14.0" \
PARALLEL_WORKERS=3 \
npm run test:android:parallel

Execution Targets Summary

| EXECUTION_TARGET | Platform | Server | UDID required | |---|---|---|---| | emulator | Android | Local Appium | Auto-assigned | | simulator | iOS | Local Appium | Optional (via DEVICE_POOL) | | local-device | Android / iOS | Local Appium | Required (UDID or DEVICE_POOL) | | browserstack | Android / iOS | BS Hub | Not needed |


Scenarios

@mobileApp — Video Playback Full Flow

Launches WTHR app → dismisses sign-up popup → verifies Top Stories → opens "Center Grove" story → plays video in fullscreen → toggles mute/captions → changes speed to 2x → exits fullscreen.

@mobileApp2 — Video Icon + Menu + Suggest

Launches WTHR app → navigates to video via bottom nav → opens Menu → changes playback speed to 2x → closes sheet → uses Suggest / Suggest More.

@mobileApp3 — Scroll to Page End

Launches WTHR app → opens "AES Indiana" story → scrolls page until end or 10 attempts maximum.

On iOS this scenario uses Playwright (WebKit) for Safari/WebView scrolling.


Scroll Behaviour

scrollUntilEndOrAttempts() automatically picks the right strategy based on the active driver and context:

| Context | Platform | Driver | Strategy | |---|---|---|---| | Native app | Android | Appium | mobile: scrollGesture — returns false at bottom edge for reliable end detection | | Native app | iOS | Appium | W3C touch swipe up × maxScrolls | | WebView (Appium context) | Android / iOS | Appium | JS window.scrollTo using Math.max(body.scrollHeight, documentElement.scrollHeight) — handles iOS Safari's non-body scroll root | | Browser / WebView (Playwright) | Android / iOS | Playwright | Same JS strategy via page.evaluate |

No manual context switching or platform checks needed in test code — the framework detects the active context at runtime via driver.getContext().


Generating Reports

# HTML report from last run
npm run report

# Allure report (requires allure CLI)
npm run report:allure

Reports are written to:

reports/
├── cucumber-report.html         # Cucumber HTML report
├── cucumber-report.json         # Cucumber JSON (used by generate-report.ts)
├── run-log-worker-0.json        # Per-worker run log (merged into HTML report)
├── run-log-worker-1.json        # (one file per parallel worker)
├── screenshots/
│   └── screenshot_w0_<ts>.png   # Failure screenshots (w<workerId>_<timestamp>)
└── screen-recordings/
    └── <scenario-name>.mp4      # Screen recordings per scenario

Framework Architecture

Feature File (.feature)
        │
        ▼
  Step Definitions  ──►  Page Object (InitialPage)
  (Wthr13Steps.ts)              │
        │               ┌───────┴────────┐
        │               ▼                ▼
  CustomWorld      AppiumActions   PlaywrightActions
  (driver +        (native + WebView) (browser / WebView
  playwrightPage)   via Appium)        via Playwright)
        │
        ▼
  DriverManager  ──►  Appium Session  (emulator / simulator / device / BS)
                  ──►  Playwright Page (WebKit / Chromium / Firefox)

Core layer (src/core/)

| Class | Responsibility | |---|---| | AppiumActions | All reusable native mobile interactions: tap, swipe, scroll (native + WebView auto-detection), type, wait, gestures, device actions | | PlaywrightActions | All reusable web interactions: navigate, click, fill, scroll (cross-browser scrollHeight fix), wait, screenshot | | Assertions | Unified assertion library for both Appium elements and Playwright locators |

Page objects extend BasePage and use only this.appium.*, this.pw.*, and this.assert.* — no raw driver calls in page objects.


Tech Stack

| Package | Version | Role | |---|---|---| | @cucumber/cucumber | ^10.8.0 | BDD test runner | | webdriverio | ^8.39.0 | Appium WebDriver client | | @playwright/test | ^1.45.0 | Web / WebView automation | | typescript | ^5.5.0 | Language | | ts-node | ^10.9.2 | TypeScript execution | | multiple-cucumber-html-reporter | ^3.7.0 | HTML report generation | | allure-cucumberjs | ^2.15.1 | Allure report integration | | winston | ^3.13.0 | Structured logging |