
Security News
/Research
Fake Corepack Site Distributes Infostealer and Proxyware to Developers
A fake corepack.org site is impersonating the Node.js tool and delivers an infostealer and proxyware to developers who download it.
@deepracticex/testing-utils
Advanced tools
Testing utility functions for Deepractice Node.js projects
Unified testing utilities for Deepractice Node.js projects with BDD support.
This package wraps
@deepracticex/vitest-cucumberand@deepracticex/vitest-cucumber-pluginto provide a single dependency for users.
# Single dependency - includes vitest-cucumber runtime and plugin
pnpm add -D @deepracticex/testing-utils
Use the pre-configured vitest config from @deepracticex/config-preset:
// vitest.config.ts
import path from "node:path";
import { defineConfig, mergeConfig } from "vitest/config";
import { vitest } from "@deepracticex/config-preset/vitest";
export default mergeConfig(
vitest.withCucumber({
steps: "tests/e2e/steps",
verbose: true,
}),
defineConfig({
resolve: {
alias: {
"~": path.resolve(__dirname, "./src"),
},
},
}),
);
Create .feature files using Gherkin syntax:
# features/calculator.feature
Feature: Calculator
Scenario: Add two numbers
Given I have entered 50 into the calculator
And I have entered 70 into the calculator
When I press add
Then the result should be 120
Create step definitions in tests/e2e/steps/:
// tests/e2e/steps/calculator.steps.ts
import { Given, When, Then } from "@deepracticex/testing-utils";
import { expect } from "vitest";
Given("I have entered {int} into the calculator", function (num: number) {
this.numbers = this.numbers || [];
this.numbers.push(num);
});
When("I press add", function () {
this.result = this.numbers.reduce((a, b) => a + b, 0);
});
Then("the result should be {int}", function (expected: number) {
expect(this.result).toBe(expected);
});
Create hooks in tests/e2e/support/hooks.ts:
// tests/e2e/support/hooks.ts
import {
Before,
After,
BeforeAll,
AfterAll,
setWorldConstructor,
} from "@deepracticex/testing-utils";
import { createWorld } from "./world.js";
// Register World factory
setWorldConstructor(createWorld);
BeforeAll(async function () {
console.log("🥒 Starting tests");
});
Before(async function () {
// Fresh context for each scenario
if (this.clear) {
this.clear();
}
});
After(async function () {
// Cleanup
});
AfterAll(async function () {
console.log("✅ Tests completed");
});
Create custom world context in tests/e2e/support/world.ts:
// tests/e2e/support/world.ts
export interface MyWorld {
numbers: number[];
result: number;
context: Record<string, any>;
set(key: string, value: any): void;
get(key: string): any;
clear(): void;
}
export function createWorld(): MyWorld {
const context: Record<string, any> = {};
return {
numbers: [],
result: 0,
context,
set(key: string, value: any) {
this.context[key] = value;
},
get(key: string) {
return this.context[key];
},
clear() {
this.context = {};
this.numbers = [];
this.result = 0;
},
};
}
pnpm test
import { Given, When, Then } from "@deepracticex/testing-utils";
// Parameter types: {int}, {float}, {string}, {word}
Given("I have {int} items", function (count: number) {
this.count = count;
});
When("I add {int} more", function (more: number) {
this.count += more;
});
Then("I should have {int} items", function (expected: number) {
expect(this.count).toBe(expected);
});
import {
Before,
After,
BeforeAll,
AfterAll,
} from "@deepracticex/testing-utils";
BeforeAll(async function () {
// Runs once before all scenarios in the feature
});
Before(async function () {
// Runs before each scenario
});
After(async function () {
// Runs after each scenario
});
AfterAll(async function () {
// Runs once after all scenarios in the feature
});
import { setWorldConstructor } from "@deepracticex/testing-utils";
// Define your world interface
interface MyWorld {
calculator: Calculator;
result: number;
}
// Create world factory function
function createWorld(): MyWorld {
return {
calculator: new Calculator(),
result: 0,
};
}
// Register the world factory
setWorldConstructor(createWorld);
// Use in steps with proper typing
Given("...", function (this: MyWorld) {
this.calculator.add(5);
});
Handle tabular data in your steps:
Scenario: Multiple users
Given the following users:
| name | email | role |
| Alice | alice@test.com | admin |
| Bob | bob@test.com | user |
import { Given, DataTable } from "@deepracticex/testing-utils";
Given("the following users:", function (table: DataTable) {
// Get as array of objects (recommended)
const users = table.hashes();
// users = [
// { name: "Alice", email: "alice@test.com", role: "admin" },
// { name: "Bob", email: "bob@test.com", role: "user" }
// ]
users.forEach((user) => {
console.log(user.name, user.email, user.role);
});
// Or get as raw 2D array
const rows = table.raw();
// rows = [
// ["name", "email", "role"],
// ["Alice", "alice@test.com", "admin"],
// ["Bob", "bob@test.com", "user"]
// ]
});
Handle multi-line text data:
Scenario: Process JSON
Given I have the following JSON:
"""json
{
"name": "Test",
"value": 42
}
"""
Given("I have the following JSON:", function (docString: string) {
this.data = JSON.parse(docString);
});
Step Definition Functions:
Given(pattern, implementation) - Define preconditionsWhen(pattern, implementation) - Define actionsThen(pattern, implementation) - Define assertionsLifecycle Hooks:
BeforeAll(hook) - Run once before all scenariosBefore(hook) - Run before each scenarioAfter(hook) - Run after each scenarioAfterAll(hook) - Run once after all scenariosConfiguration:
setWorldConstructor(factory) - Register world factory functionData Structures:
DataTable - Handle table data with .hashes() and .raw() methodsRuntime APIs (for advanced usage):
StepExecutor - Internal step execution engineContextManager - Manage test contextHookRegistry - Hook registration and executionThis package serves as a wrapper that combines:
@deepracticex/vitest-cucumber - Runtime API (Given/When/Then, hooks, DataTable)@deepracticex/vitest-cucumber-plugin - Vitest plugin for transforming .feature filesUsers only need to install @deepracticex/testing-utils as a single dependency. The vitest-cucumber plugin is configured via @deepracticex/config-preset/vitest to use this package as the runtime module, ensuring all imports resolve correctly.
tests/
├── e2e/
│ ├── steps/
│ │ ├── auth.steps.ts # Authentication steps
│ │ ├── user.steps.ts # User management steps
│ │ └── common.steps.ts # Common/shared steps
│ └── support/
│ ├── world.ts # World interface and factory
│ └── hooks.ts # Global hooks
└── features/
├── auth.feature
└── user.feature
Always type your world context:
interface MyWorld {
user?: User;
token?: string;
}
Given("a user with email {string}", function (this: MyWorld, email: string) {
// TypeScript provides autocomplete and type checking
this.user = { email };
});
Write generic steps that can be used across multiple scenarios:
// ✅ Good: Reusable and flexible
Given("I am logged in as {string}", function (role: string) {
this.token = loginAs(role);
});
// ❌ Avoid: Too specific
Given("I am logged in as an admin user with full permissions", function () {
this.token = loginAs("admin");
});
Feature: User Management
Background:
Given I have the error factory imported
Scenario: Create user
When I create a user
Then the user should be created
For multiple similar test cases, use Scenario Outlines with Examples:
Scenario Outline: Validate HTTP errors
When I create a "<errorType>" error
Then the error status code should be <statusCode>
Examples:
| errorType | statusCode |
| notFound | 404 |
| unauthorized | 401 |
| forbidden | 403 |
Always use a factory function, not a class:
// ✅ Correct
export function createWorld(): MyWorld {
return {
count: 0,
items: [],
};
}
// ❌ Wrong - don't use classes
class MyWorld {
count = 0;
items = [];
}
MIT © Deepractice
FAQs
Testing utility functions for Deepractice Node.js projects
We found that @deepracticex/testing-utils demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
/Research
A fake corepack.org site is impersonating the Node.js tool and delivers an infostealer and proxyware to developers who download it.

Research
/Security News
A large-scale campaign abused GitHub Actions in compromised repositories to exploit CVE-2026-41940 in cPanel and WHM and steal server credentials.

Security News
Five frontier LLMs generated the same nonexistent package names, leaving 53 available for potential slopsquatting across PyPI and npm.