mirror of
https://github.com/hoppscotch/hoppscotch.git
synced 2026-04-26 01:06:00 +03:00
[PR #5417] [MERGED] feat(scripting-revamp): chai powered assertions and postman compatibility layer #5200
Labels
No labels
CodeDay
a11y
browser limited
bug
bug fix
cli
core
critical
design
desktop
discussion
docker
documentation
duplicate
enterprise
feature
feature
fosshack
future
good first issue
hacktoberfest
help wanted
i18n
invalid
major
minor
need information
need testing
not applicable to hoppscotch
not reproducible
pull-request
question
refactor
resolved
sandbox
self-host
spam
stale
testmu
wip
wont fix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/hoppscotch#5200
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/hoppscotch/hoppscotch/pull/5417
Author: @jamesgeorge007
Created: 9/30/2025
Status: ✅ Merged
Merged: 10/27/2025
Merged by: @jamesgeorge007
Base:
next← Head:feat/updated-scripting-system📝 Commits (5)
9ea85b4feat: chai powered assertions and postman compatibility layer2a6496echore: import modal checkbox UI updateac6f8a1chore: inform users about postman script import in legacy sandbox40fb7fdchore: cleanup4f365bcchore: cleanup📊 Changes
90 files changed (+30774 additions, -1397 deletions)
View changed files
📝
packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/scripting-revamp-coll.json(+548 -4)📝
packages/hoppscotch-cli/src/utils/pre-request.ts(+19 -6)📝
packages/hoppscotch-common/locales/en.json(+6 -0)📝
packages/hoppscotch-common/src/components/collections/ImportExport.vue(+74 -5)📝
packages/hoppscotch-common/src/components/importExport/Base.vue(+2 -0)📝
packages/hoppscotch-common/src/components/importExport/ImportExportSteps/FileImport.vue(+49 -2)📝
packages/hoppscotch-common/src/components/importExport/ImportExportSteps/ImportSummary.vue(+161 -69)📝
packages/hoppscotch-common/src/helpers/import-export/import/import-sources/FileSource.ts(+7 -2)📝
packages/hoppscotch-common/src/helpers/import-export/import/postman.ts(+115 -12)📝
packages/hoppscotch-common/src/types/post-request.d.ts(+701 -37)📝
packages/hoppscotch-common/src/types/pre-request.d.ts(+517 -32)📝
packages/hoppscotch-js-sandbox/package.json(+2 -0)➕
packages/hoppscotch-js-sandbox/src/__tests__/combined/async-await-support.spec.ts(+149 -0)➕
packages/hoppscotch-js-sandbox/src/__tests__/combined/core-chai-assertions.spec.ts(+607 -0)➕
packages/hoppscotch-js-sandbox/src/__tests__/combined/deep-include-keys-assertions.spec.ts(+364 -0)➕
packages/hoppscotch-js-sandbox/src/__tests__/combined/instanceof-assertions.spec.ts(+503 -0)➕
packages/hoppscotch-js-sandbox/src/__tests__/combined/keys-members-assertions.spec.ts(+443 -0)➕
packages/hoppscotch-js-sandbox/src/__tests__/combined/length-assertions.spec.ts(+604 -0)➕
packages/hoppscotch-js-sandbox/src/__tests__/combined/side-effects-assertions.spec.ts(+426 -0)➕
packages/hoppscotch-js-sandbox/src/__tests__/hopp-namespace/chai-powered-assertions/core-assertions.spec.ts(+616 -0)...and 70 more files
📄 Description
This PR extends the scripting system with Chai.js-powered assertions for both
hoppandpmnamespaces, introducing a Postman compatibility layer with script import capability (experimental feature requiring user consent) alongside Postman collection (v2.0/2.1) imports, as proposed in #5221.Related to FE-319 #2904.
What's changed
Chai.js Assertion Support
Added comprehensive Chai.js BDD assertion support through
hopp.expect()for native Hoppscotch scripts andpm.expect()for Postman compatibility, enabling advanced testing patterns with 50+ assertion methods.Usage Samples
Native Hoppscotch Scripts (
hoppnamespace)Use
hopp.expect()for assertions in native Hoppscotch test scripts:Postman Compatibility (
pmnamespace)Use
pm.expect()for importing and running Postman collections in Hoppscotch. This provides experimental Postman API compatibility. The supported version range isv2.0/2.1.Experimental sandbox importer flow
Legacy sandbox import summary nudge
Real-World Usage Examples
API Pagination Testing:
Authentication Flow Testing:
Data Transformation Pipeline:
Rate Limit Handling:
Webhook Signature Verification:
GraphQL Error Handling:
Postman Collection Migration Example:
Complete Assertion Reference
Type assertions:
.a(type)/.an(type)- Check value type.instanceof(constructor)- Check instance type.typeof(type)- Check typeof resultEquality assertions:
.equal(value)/.eq(value)- Strict equality (===).eql(value)- Deep equality.deep.equal(value)- Deep strict equalityProperty assertions:
.property(name)- Has property.own.property(name)- Has own property (not inherited).nested.property(path)- Has nested property (e.g., 'a.b.c').deep.property(path)- Deep property comparisonCollection assertions:
.include(value)/.contain(value)- Contains value.members(array)- Has members (order-independent).ordered.members(array)- Has members in order.keys(...keys)- Has keys.all.keys(...)- Has exactly these keys.any.keys(...)- Has at least one key.length(n)/.lengthOf(n)- Length equals n.lengthOf.at.least(n)- Minimum length.lengthOf.at.most(n)- Maximum lengthComparison assertions:
.above(n)/.gt(n)- Greater than.below(n)/.lt(n)- Less than.at.least(n)/.gte(n)- Greater than or equal.at.most(n)/.lte(n)- Less than or equal.within(min, max)- Within range.closeTo(expected, delta)- Approximately equalBoolean assertions:
.ok- Truthy.true- Strictly true.false- Strictly false.null- Strictly null.undefined- Strictly undefined.exist- Not null or undefined.empty- Empty (string, array, object)String assertions:
.match(regex)- Matches regular expression.string(substring)- Contains substringFunction assertions:
.throw()/.throw(ErrorType)/.throw(message)- Throws error.respondTo(method)- Has methodObject state assertions:
.extensible- Object.isExtensible().sealed- Object.isSealed().frozen- Object.isFrozen()Side-effect assertions:
.change(getter)- Changes value when executed.increase(getter)- Increases value when executed.decrease(getter)- Decreases value when executed.by(delta)- Change amount (chain with change/increase/decrease)PM-specific response assertions:
pm.response.to.have.status(code)- Status code checkpm.response.to.have.header(name)- Header existencepm.response.to.have.body()- Has response bodypm.response.to.have.jsonBody()- JSON body existspm.response.to.have.jsonBody(path)- JSON property existspm.response.to.have.jsonSchema(schema)- Validates JSON schemapm.response.to.be.ok- 2xx status codepm.response.to.be.success- Alias for okpm.response.to.be.json- JSON content typeModifiers:
.not- Negation.deep- Deep comparison.own- Own properties only.ordered- Order matters.nested- Nested property access.all- All items/keys.any- Any items/keys.to/.be/.been/.is/.that/.which/.and/.has/.have/.with/.at/.of/.same- Language chains for readabilityUnsupported Features
The following Postman features are not implemented per RFC scope:
pm.sendRequest()pm.visualizerpm.collectionVariablespm.iterationDatapm.execution.setNextRequest()responseBodyvariable,require(), etc.Implementation Details
Implementation architecture
Serialisation Boundary Handling
The scripting sandbox uses faraday-cage to isolate untrusted code. All data crossing this boundary is serialised, which loses object metadata.
Pre-check pattern:
Example:
This pattern ensures metadata-dependent assertions work correctly despite serialisation.
The
__createChaiProxyfunction appears in both pre-request.js and post-request.js (~1,300 lines each) because each runs in a separate sandbox execution context that cannot share global state.Notes to reviewers
Chai Integration Rationale
Chai.jsis not bundled in the sandbox for several reasons:The pre-check pattern trades bandwidth (by passing metadata) for correctness (by preserving object state).
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.