Simplify Your Cypress Intercept Assertions: cypress-intercept-search
When writing end-to-end tests with Cypress, you must often validate that your application sends or receives the correct data. Cypress’s cy.intercept() gives you robust control over network requests. However, digging through nested bodies, headers, and query parameters to find the exact key/value you care about can become repetitive and error-prone. That’s why I created cypress-intercept-search, a small plugin that lets you recursively search through every part of one or more intercepted requests or responses for a given key and (optionally) a matching value. Then, wrap the results in a chainable Cypress command for easy assertions. ## Why Built cypress-intercept-search When you’re writing end-to-end tests in Cypress, it’s all too easy to end up with the same boilerplate over and over: cy.wait('@savePlay').then((i) => { const { players } = i.request.body; expect(players).to.exist; Object.entries(players).forEach(([role, p]) => { expect(p.id).to.not.equal('00000000-0000-0000-0000-000000000000'); }); }); Consider a scenario where your JSON structure contains multiple nested levels or headers, query parameters, request bodies, and response bodies that must be examined simultaneously. Copying and pasting recursive helpers across specifications can rapidly become a significant maintenance challenge. ## Key Advantages Zero Boilerplate, Maximum Clarity Drop in a single call: cy.wait('@savePlay') .search('playerID', '00000000-0000-0000-0000-000000000000') .should('have.length', 1); No more manual tree-walking. Tests read like plain English: “wait, search for this key/value, assert I found one.” Chainable & Composable Because .search() wraps its results in a Cypress chainable, you can combine it with any built-in assertion: cy.wait('@echo') .search('foo') // just look for key presence .should('not.be.empty') // assert at least one hit .then((matches) => { // inspect where you found it expect(matches[0].path.join('.')).to.equal('nested.level1.level2.foo'); }); Deep & Wide Coverage Under the hood, it scans: request.query request.headers request.body response.headers response.body Your tests no longer need five separate helpers — one command does it all. Rich Cypress-Log Integration Every .search() call produces a custom entry in the Cypress Command Log, complete with: the key/value you searched number of matches which part of the HTTP cycle they came from exact property paths That means you get full visibility without extra cy.log() calls. Repository & Links npm package: cypress-intercept-search GitHub source: lasithdilshan20/cypress-intercept-search ## Contributing & Roadmap I welcome issues and PRs! Here are a few ideas on the horizon: Sugar methods like .shouldExist() / .shouldNotExist() Value‐range matching (e.g. regex or partial matches) Performance tuning for very large payloads Type‐safe search with generic key/value types Feel free to open an issue or submit a pull request on GitHub.

When writing end-to-end tests with Cypress, you must often validate that your application sends or receives the correct data. Cypress’s cy.intercept()
gives you robust control over network requests. However, digging through nested bodies, headers, and query parameters to find the exact key/value you care about can become repetitive and error-prone.
That’s why I created cypress-intercept-search, a small plugin that lets you recursively search through every part of one or more intercepted requests or responses for a given key and (optionally) a matching value. Then, wrap the results in a chainable Cypress command for easy assertions.
## Why Built cypress-intercept-search
When you’re writing end-to-end tests in Cypress, it’s all too easy to end up with the same boilerplate over and over:
cy.wait('@savePlay').then((i) => {
const { players } = i.request.body;
expect(players).to.exist;
Object.entries(players).forEach(([role, p]) => {
expect(p.id).to.not.equal('00000000-0000-0000-0000-000000000000');
});
});
Consider a scenario where your JSON structure contains multiple nested levels or headers, query parameters, request bodies, and response bodies that must be examined simultaneously. Copying and pasting recursive helpers across specifications can rapidly become a significant maintenance challenge.
## Key Advantages
- Zero Boilerplate, Maximum Clarity Drop in a single call:
cy.wait('@savePlay')
.search('playerID', '00000000-0000-0000-0000-000000000000')
.should('have.length', 1);
No more manual tree-walking. Tests read like plain English: “wait, search for this key/value, assert I found one.”
- Chainable & Composable
Because
.search()
wraps its results in a Cypress chainable, you can combine it with any built-in assertion:
cy.wait('@echo')
.search('foo') // just look for key presence
.should('not.be.empty') // assert at least one hit
.then((matches) => {
// inspect where you found it
expect(matches[0].path.join('.')).to.equal('nested.level1.level2.foo');
});
- Deep & Wide Coverage Under the hood, it scans:
request.query
request.headers
request.body
response.headers
response.body
Your tests no longer need five separate helpers — one command does it all.
- Rich Cypress-Log Integration
Every
.search()
call produces a custom entry in the Cypress Command Log, complete with:
- the key/value you searched
- number of matches
- which part of the HTTP cycle they came from
- exact property paths
- That means you get full visibility without extra cy.log() calls.
Repository & Links
npm package: cypress-intercept-search
GitHub source: lasithdilshan20/cypress-intercept-search
## Contributing & Roadmap
I welcome issues and PRs! Here are a few ideas on the horizon:
- Sugar methods like
.shouldExist() / .shouldNotExist()
- Value‐range matching (e.g. regex or partial matches)
- Performance tuning for very large payloads
- Type‐safe search with generic key/value types
Feel free to open an issue or submit a pull request on GitHub.