Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions docusaurus.config.js

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comments from all fines related to internal task ticket numbers.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in b56c813 — stripped Task 35, LIVE-12, LIVE-13, and LIVE-20 ticket references from comments across docusaurus.config.js, src/theme/DocBreadcrumbs/index.js, and src/theme/DocItem/index.js. Kept the explanatory comments that describe why each piece of logic exists, just without the internal ticket numbers.

Original file line number Diff line number Diff line change
Expand Up @@ -449,20 +449,58 @@ module.exports = {
changefreq: "weekly",
priority: 0.5,
filename: "sitemap.xml",
// Task 35: differentiate docs sitemap priorities by content type
// so search engines spend crawl budget proportional to how
// canonical each page is. Priority buckets:
// 1.0 → /docs/ root (highest — primary entry point)
// 0.9 → /docs/quickstart/* (highest-intent user flow)
// 0.8 → /docs/running-keploy/* (primary product docs)
// 0.7 → /docs/concepts/*, /docs/keploy-explained/*
// 0.6 → /docs/keploy-cloud/*, /docs/ci-cd/*
// 0.6 → /docs/faq, /docs/troubleshooting (reference-style)
// 0.5 → /docs/concepts/reference/glossary/* (long-tail
// glossary; noindexed legacy versions excluded via
// netlify headers + robots.txt)
createSitemapItems: async (params) => {
const {defaultCreateSitemapItems, ...rest} = params;
const items = await defaultCreateSitemapItems(rest);
return items.map((item) => {
if (item.url.includes("/quickstart/")) {
const url = item.url;
// The /docs/ home page is the highest-priority entry point
// for the whole docs subtree.
if (url.endsWith("/docs/") || url.endsWith("/docs")) {
return {...item, priority: 1.0, changefreq: "weekly"};
}
if (url.includes("/quickstart/")) {
return {...item, priority: 0.9, changefreq: "weekly"};
}
if (url.includes("/running-keploy/")) {
return {...item, priority: 0.8, changefreq: "weekly"};
}
if (
item.url.includes("/concepts/") ||
item.url.includes("/keploy-explained/")
url.includes("/concepts/reference/glossary/")
) {
// Glossary entries are numerous, long-tail, and often
// off-topic for core product queries. Keep them in the
// sitemap but mark them low priority.
return {...item, priority: 0.5, changefreq: "monthly"};
}
if (
url.includes("/concepts/") ||
url.includes("/keploy-explained/")
) {
return {...item, priority: 0.7, changefreq: "weekly"};
}
if (item.url.includes("/keploy-cloud/")) {
if (
url.includes("/keploy-cloud/") ||
url.includes("/ci-cd/")
) {
return {...item, priority: 0.6, changefreq: "monthly"};
}
if (
url.includes("/faq") ||
url.includes("/troubleshooting")
) {
return {...item, priority: 0.6, changefreq: "monthly"};
}
Comment on lines +505 to 513

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sitemap priority bucket for “/docs/faq” and “/docs/troubleshooting” won’t apply to the current v4 docs routes. The FAQ docs are at URLs like /docs/keploy-explained/integration-testing-faq/ (and api-testing-faq, unit-testing-faq), which don’t contain the substring /faq, and the “Troubleshooting Guide” is /docs/keploy-explained/common-errors/, which doesn’t contain /troubleshooting. As a result, these pages will fall into the /keploy-explained/ bucket (0.7) instead of the intended 0.6. Update the matching logic to reflect actual routes (e.g., match faq anywhere in the slug and common-errors, or base this on doc ids/tags), or update the comment/bucket list so it matches the implemented behavior.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0af8f3c. Changed the match patterns to the actual v4 URL fragments (-faq/, -faq, /common-errors) and moved the FAQ/troubleshooting check ABOVE the /keploy-explained/ check so it takes precedence. Now /docs/keploy-explained/integration-testing-faq/, api-testing-faq, unit-testing-faq, and common-errors all correctly land in the 0.6 reference-style bucket instead of the 0.7 concepts bucket. Header comment updated to name the actual pages covered.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0af8f3c: the FAQ + troubleshooting bucket now matches the actual v4 routes. The createSitemapItems handler matches url.includes("-faq/") || url.includes("-faq") || url.includes("/common-errors") before the broader /keploy-explained/ 0.7 bucket, so the three FAQ pages (integration-testing-faq, api-testing-faq, unit-testing-faq) and the Troubleshooting Guide at /docs/keploy-explained/common-errors/ correctly land in the 0.6 bucket. The match-first ordering is documented inline so future edits don't accidentally swap the rules and bury these matches under the keploy-explained fallback.

return item;
Expand Down
75 changes: 41 additions & 34 deletions src/theme/DocBreadcrumbs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,14 @@ export default function DocBreadcrumbs() {
const {siteConfig} = useDocusaurusContext();
const {pathname} = useLocation();

if (!breadcrumbs) {
return null;
}
// LIVE-20 fix. Previously this component early-returned when
// useSidebarBreadcrumbs() returned null/undefined, which caused
// glossary and reference pages not in the sidebar config to ship
// with zero BreadcrumbList schema (audited 2026-04-14 on
// /docs/concepts/reference/glossary/idempotency/).
// Now we treat null/undefined as "no sidebar trail, emit Home + Docs
// schema anyway" so AI crawlers always get a hierarchy signal.
const sidebarTrail = Array.isArray(breadcrumbs) ? breadcrumbs : [];

const toAbsoluteUrl = (baseUrl, url) => {
if (!url) {
Expand Down Expand Up @@ -89,9 +94,9 @@ export default function DocBreadcrumbs() {
}
}

if (breadcrumbs.length > 0) {
breadcrumbs.forEach((crumb, index) => {
const isLast = index === breadcrumbs.length - 1;
if (sidebarTrail.length > 0) {
sidebarTrail.forEach((crumb, index) => {
const isLast = index === sidebarTrail.length - 1;
const href =
crumb.type === "category" && crumb.linkUnlisted
? undefined
Expand Down Expand Up @@ -130,35 +135,37 @@ export default function DocBreadcrumbs() {
</script>
</Head>
)}
<nav
className={clsx(
ThemeClassNames.docs.docBreadcrumbs,
styles.breadcrumbsContainer
)}
aria-label={translate({
id: "theme.docs.breadcrumbs.navAriaLabel",
message: "Breadcrumbs",
description: "The ARIA label for the breadcrumbs",
})}
>
<ul className="breadcrumbs">
{homePageRoute && <HomeBreadcrumbItem />}
{breadcrumbs.map((item, idx) => {
const isLast = idx === breadcrumbs.length - 1;
const href =
item.type === "category" && item.linkUnlisted
? undefined
: item.href;
return (
<BreadcrumbsItem key={idx} active={isLast}>
<BreadcrumbsItemLink href={href} isLast={isLast}>
{item.label}
</BreadcrumbsItemLink>
</BreadcrumbsItem>
);
{sidebarTrail.length > 0 && (
<nav
className={clsx(
ThemeClassNames.docs.docBreadcrumbs,
styles.breadcrumbsContainer
)}
aria-label={translate({
id: "theme.docs.breadcrumbs.navAriaLabel",
message: "Breadcrumbs",
description: "The ARIA label for the breadcrumbs",
})}
</ul>
</nav>
>
<ul className="breadcrumbs">
{homePageRoute && <HomeBreadcrumbItem />}
{sidebarTrail.map((item, idx) => {
const isLast = idx === sidebarTrail.length - 1;
const href =
item.type === "category" && item.linkUnlisted
? undefined
: item.href;
return (
<BreadcrumbsItem key={idx} active={isLast}>
<BreadcrumbsItemLink href={href} isLast={isLast}>
{item.label}
</BreadcrumbsItemLink>
</BreadcrumbsItem>
);
})}
</ul>
</nav>
)}
</>
);
}
32 changes: 31 additions & 1 deletion src/theme/DocItem/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,24 @@ export default function DocItem(props) {
const normalizedMetaKeywords = Array.isArray(metaKeywords)
? metaKeywords.join(", ")
: metaKeywords;
// LIVE-13: suppress Article / BlogPosting / APIReference schema on the

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we suppressing, how does this help?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explaining rather than removing, since it's a functional fix — happy to revert if you still want it out.

What it does: On /docs/ and any /category/... index page, we skip emitting Article / BlogPosting / APIReference JSON-LD and emit only the BreadcrumbList schema.

Why: Article schema requires a single headline, single author, and single datePublished. A hub page (the docs landing, or a category index) is an index of many articles — it has no single author or publication date. Emitting Article JSON-LD on these pages is a structured-data type mismatch.

What breaks without it:

  1. Google Rich Results Test flags /docs/ as invalid Article structured data (missing or conflicting fields). Invalid schema can cause Google to stop trusting all the schema on the domain, including the valid Article entries on leaf pages.
  2. AI crawlers (Perplexity, ChatGPT Search) that cite "articles" prefer pages where the type matches — a hub incorrectly marked as Article gets cited with the wrong title/author combo in answer engines.

Scope: It only affects the docs root and category index pages. Every normal content page (/docs/running-keploy/cli-commands, /docs/keploy-explained/how-keploy-works, etc.) still emits full Article schema exactly as before — those pages have real authors, dates, and headlines.

If you want it removed anyway: say the word and I'll strip it. The cost is that /docs/ will fail Google's structured-data validation and /docs/category/* pages will emit Article schema with blank author/date fields. Up to you.

// /docs/ root and any category index pages. Article schema on a hub
// page is a type mismatch because a hub does not have a single author,
// single publication date, or single headline — it is an index of
// content. Hub pages emit only the normal DocBreadcrumbs JSON-LD.
const permalink = metadata?.permalink || "";
const isDocsRoot =
permalink === "/docs/" ||
permalink === "/docs" ||
permalink.endsWith("/docs/index") ||
permalink.endsWith("/docs/");
const isCategoryIndex =
frontMatter?.slug === "index" ||
/\/category\/|\/index\/?$/.test(permalink);
const suppressArticleSchema = isDocsRoot || isCategoryIndex;

const articleSchema =
pageUrl && title
pageUrl && title && !suppressArticleSchema
? {
"@context": "https://schema.org",
"@type": schemaType,
Expand Down Expand Up @@ -187,6 +203,20 @@ export default function DocItem(props) {
{normalizedMetaKeywords && (
<meta name="keywords" content={normalizedMetaKeywords} />
)}
{/* LIVE-12: per-page og:title and og:description override the
docusaurus.config.js site-level defaults, which previously
emitted "Keploy Documentation" as og:title on every docs
page regardless of content. Social card previews now reflect
the actual page title (e.g. "What is Idempotency in REST
APIs? Complete Guide"). */}
<meta property="og:title" content={title} />
{description && (
<meta property="og:description" content={description} />
)}
<meta name="twitter:title" content={title} />
{description && (
<meta name="twitter:description" content={description} />
)}
{socialImage && <meta property="og:image" content={socialImage} />}
{socialImage && <meta name="twitter:image" content={socialImage} />}
{socialImage && (
Expand Down
90 changes: 88 additions & 2 deletions static/robots.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,98 @@
# Block specific bot
# Keploy docs robots.txt
# Policy: allow AI search/answer engines, block training-only crawlers,
# block Bytespider. Search bots drive visibility in ChatGPT, Claude,
# Perplexity, Copilot, Gemini answers. Training bots feed future model
# weights and provide nothing back.
# Reference: Speedscale / Katalon / Testsigma split policy (2026 competitor audit)
Comment on lines +1 to +6

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description mentions adding a new “Keploy vs Alternatives” doc page and updating the v4 sidebar, but those artifacts don’t appear to be present in this change set (no keploy-vs-alternatives doc found and no sidebar entry references it). Either the description needs updating to reflect the actual changes in this PR, or the missing doc/sidebar changes need to be included so the PR matches its stated scope.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by updating the PR title and body via REST API. The title is now 'audit: BreadcrumbList, robots policy, og:title, sitemap priorities' and the Task 33 section describing the Keploy vs Alternatives page has been removed from the body. Added a trailing Note that explains the file and sidebar entry were created earlier in the branch and then removed in commit b56c813 per @nehagup's review feedback — product comparison framing belongs on the landing site, not the docs subtree. The current PR scope is BreadcrumbList + robots.txt + og:title + sitemap priorities only.


# =============================================================================
# ALLOW — AI search / answer engines
# Legacy-version disallows are repeated inside this group because a bot that
# matches a named User-agent group only reads rules from THAT group; it does
# not fall through to `User-agent: *`. Without these lines, Perplexity/
# Applebot/OAI-SearchBot/etc. would still crawl /docs/{1,2,3}.0.0/ despite
# the global block further below.
# =============================================================================

User-agent: OAI-SearchBot
User-agent: ChatGPT-User
User-agent: Claude-SearchBot
User-agent: Claude-User
User-agent: PerplexityBot
User-agent: Perplexity-User
User-agent: Gemini-Deep-Research
User-agent: GoogleOther
User-agent: Applebot
User-agent: DuckAssistBot
User-agent: Amazonbot
Allow: /

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The explicit AI-search User-agent group won’t inherit rules from User-agent: *, so those bots will ignore Crawl-delay: 5 and Disallow: /cgi-bin/. If the intent is to keep the same crawl-rate limit and global disallows for all allowed crawlers, duplicate those rules inside this named allow group as well (alongside the legacy-version disallows).

Suggested change
Allow: /
Allow: /
Crawl-delay: 5
Disallow: /cgi-bin/

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 56cae9e. Added Crawl-delay: 5 and Disallow: /cgi-bin/ inside the named AI-search User-agent group so the allowed bots (OAI-SearchBot, ChatGPT-User, Claude-SearchBot, Claude-User, PerplexityBot, Perplexity-User, Gemini-Deep-Research, GoogleOther, Applebot, DuckAssistBot, Amazonbot) get the same rate-limit and global disallow as User-agent: *. The legacy-version disallows (/docs/1.0.0/, /docs/2.0.0/, /docs/3.0.0/) were already duplicated in this group for the same inheritance reason — this extends that pattern to the two global rules you flagged.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 56cae9e: Crawl-delay: 5 and Disallow: /cgi-bin/ are now mirrored inside the AI-search allow group alongside the legacy-version disallows, so the group is a proper superset of the User-agent: * defaults. Named AI search bots (Perplexity/Applebot/OAI-SearchBot/etc.) now see the same crawl-rate limit and /cgi-bin/ block as fall-through bots.

Crawl-delay: 5
Disallow: /cgi-bin/
Disallow: /docs/1.0.0/
Disallow: /docs/2.0.0/
Disallow: /docs/3.0.0/

# =============================================================================
# DISALLOW — Training-only crawlers
# =============================================================================

User-agent: GPTBot
Disallow: /

User-agent: ClaudeBot
Disallow: /

User-agent: anthropic-ai
Disallow: /

User-agent: CCBot
Disallow: /

User-agent: Google-Extended
Disallow: /

User-agent: Applebot-Extended
Disallow: /

User-agent: Meta-ExternalAgent
Disallow: /

User-agent: FacebookBot
Disallow: /

User-agent: cohere-ai
Disallow: /

User-agent: Diffbot
Disallow: /

User-agent: Omgilibot
Disallow: /

User-agent: ImagesiftBot
Disallow: /

# Always-block scraper
User-agent: Bytespider
Disallow: /

# Default rules — apply to all crawlers including AI bots
# =============================================================================
# DEFAULT — Googlebot, Bingbot, and all other crawlers
# =============================================================================

User-agent: *
Allow: /
Crawl-delay: 5
Disallow: /cgi-bin/

# Block unmaintained legacy doc versions (already set via noindex + canonical,
# belt-and-braces for crawlers that ignore those signals).
Disallow: /docs/1.0.0/
Disallow: /docs/2.0.0/
Disallow: /docs/3.0.0/
Comment on lines +88 to +92

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The legacy-version Disallow: /docs/1.0.0/ (and 2.0.0/3.0.0) rules are only under User-agent: *, so they will not apply to crawlers that match one of the explicit allow groups above (e.g., PerplexityBot, Applebot, OAI-SearchBot). If the intent is to block those legacy versions for all crawlers, either move the legacy disallows into each explicit allow group (and keep Allow: /), or remove the explicit allow groups entirely and let those bots fall through to User-agent: * (while keeping explicit disallow groups for training bots).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 758cff5. Went with option (a) but consolidated: the 11 AI-search-bot allow groups are now a single block that uses multiple User-agent: headers sharing one rule set, with the three legacy-version Disallow lines (/docs/1.0.0/, /docs/2.0.0/, /docs/3.0.0/) applied directly inside it. Same intent ("allow these AI search bots everywhere except legacy versions") but now actually enforced, and only 8 lines of net change instead of 33.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 758cff5 (the earlier commit that moved the legacy disallows inside the named allow group). The /docs/1.0.0/, /docs/2.0.0/, /docs/3.0.0/ lines now sit directly under the User-agent: OAI-SearchBot / ChatGPT-User / Claude-SearchBot / ... / Amazonbot block so every allowed AI bot gets the legacy-version block, not just crawlers that fall through to User-agent: *. 56cae9e just now extended the same pattern to Crawl-delay: 5 and Disallow: /cgi-bin/ per your other comment — both global rules are now duplicated inside the named group as well.


# =============================================================================
# Sitemap
# =============================================================================

Sitemap: https://keploy.io/docs/sitemap.xml

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete this versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in b56c813 — deleted the file.

Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
id: keploy-vs-alternatives
title: "Keploy vs Alternatives"
sidebar_label: Keploy vs Alternatives
description: "Side-by-side comparison of Keploy with Postman, Katalon, WireMock, Testcontainers, and other API testing tools. Feature matrix, approach, strengths, and when to pick each."
keywords:
- keploy vs postman
- keploy alternatives
- api testing tool comparison
- keploy vs katalon
- keploy vs wiremock
- keploy vs testcontainers
---

# Keploy vs Alternatives

Keploy occupies a different point in the API testing design space than most competitors. This page is a reference comparison so you can decide which tool fits your workflow before adopting anything.

The shared axis across every tool: **how do tests get created and how expensive is it to maintain them**.

## Feature comparison matrix

| Capability | Keploy | Postman | Katalon | WireMock | Testcontainers |

Check failure on line 23 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L23

[Vale.Spelling] Did you really mean 'Katalon'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Katalon'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 23, "column": 35}}}, "severity": "ERROR"}

Check failure on line 23 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L23

[Vale.Spelling] Did you really mean 'Testcontainers'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Testcontainers'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 23, "column": 56}}}, "severity": "ERROR"}
|---|---|---|---|---|---|
| Test generation model | Auto from real traffic (eBPF capture) | Manual scripts | Manual + low-code | Manual + record/playback | Manual + real containers |
| SDK / code changes required | None (kernel-level eBPF) | Newman CLI integration | Groovy scripts or record | Java SDK or standalone proxy | Java / Go / Node / Python SDK |

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Markdown table uses a double leading pipe (||) on the header and separator rows, which will render as an empty first column (and can break consistent styling). Use a single leading pipe (|) for standard GitHub/Docusaurus table syntax so columns align as intended.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False positive — the file has single leading pipes on every row. Verified with grep -n '||' versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md (no matches) and by inspecting the diff hunk Copilot attached to this comment: every table row starts with | followed by a space, not ||. The first column ("Capability") renders correctly in GitHub preview. No change required.

| Mock generation | Automatic, per-dependency | Manual per endpoint | Built-in mock server | Central mock definitions | Real container instances |
| Non-determinism handling | Built-in (timestamps, UUIDs, tokens) | Manual regex matchers | Test data profiles | Request matcher rules | Not applicable |

Check failure on line 28 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L28

[Vale.Spelling] Did you really mean 'matchers'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'matchers'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 28, "column": 82}}}, "severity": "ERROR"}
| Secret masking at capture | Automatic (Bearer, Stripe, AWS, JWT, PCI) | Manual | Manual | Manual | Not applicable |
| CI/CD integration | GitHub Actions, GitLab, Jenkins, CircleCI | Newman in any CI | Built-in | Any JVM CI | Any CI with Docker |
| License | Apache 2.0 (OSS) | Freemium (commercial) | Commercial | Apache 2.0 | Apache 2.0 |

Check failure on line 31 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L31

[Vale.Spelling] Did you really mean 'Freemium'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Freemium'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 31, "column": 32}}}, "severity": "ERROR"}
| Kernel version requirement | Linux 5.5+ (CO-RE) | N/A | N/A | N/A | N/A |

## Approach differences

**Keploy** captures real traffic flowing through a running service using eBPF at the Linux kernel level, then replays that traffic as deterministic tests. You point it at a staging or local instance, run the real API calls you want covered (or let real users use the app), and Keploy writes YAML test fixtures. No SDK, no proxy, no code instrumentation.

**Postman** is a manual API client. Every request and every assertion has to be written by a human. It is excellent for exploratory testing and building up a contract, but it scales linearly with the number of endpoints — more endpoints means more tests to write and maintain.

Check failure on line 38 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L38

[Google.EmDash] Don't put a space before or after a dash.
Raw output
{"message": "[Google.EmDash] Don't put a space before or after a dash.", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 38, "column": 220}}}, "severity": "ERROR"}

**Katalon** is a low-code test automation platform with a record-and-playback GUI. It reduces the amount of scripting needed compared to pure Postman, but test maintenance still tracks endpoint count.

Check failure on line 40 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L40

[Vale.Spelling] Did you really mean 'Katalon'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Katalon'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 40, "column": 3}}}, "severity": "ERROR"}

**WireMock** is a record/playback HTTP mock server. You can capture real responses and replay them, but WireMock stops at the mock boundary — it does not generate the test cases that call into the system under test. It is the "mock side" of what Keploy does on both capture and replay.

Check failure on line 42 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L42

[Google.EmDash] Don't put a space before or after a dash.
Raw output
{"message": "[Google.EmDash] Don't put a space before or after a dash.", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 42, "column": 140}}}, "severity": "ERROR"}

**Testcontainers** spins up real instances of databases, queues, and services inside Docker for integration tests. It is the "real dependency" approach: instead of mocking Postgres, you run a real Postgres container for every test. High fidelity, high cost per test run.

Check failure on line 44 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L44

[Vale.Spelling] Did you really mean 'Testcontainers'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Testcontainers'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 44, "column": 3}}}, "severity": "ERROR"}

## When to pick each

- **Pick Keploy** when you have an API-heavy service with 50+ endpoints and want regression coverage to grow automatically with usage instead of proportional to engineering time spent writing tests.
- **Pick Postman** when you are actively developing a new API and need interactive exploration of request/response shapes during design.
- **Pick Katalon** when you are a QA-led organization with a preference for low-code tools and want GUI record/playback as the primary workflow.

Check failure on line 50 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L50

[Vale.Spelling] Did you really mean 'Katalon'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Katalon'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 50, "column": 10}}}, "severity": "ERROR"}
- **Pick WireMock** when you need a lightweight standalone mock server for a small set of HTTP dependencies and you are already writing tests in Java.
- **Pick Testcontainers** when your tests need genuine database or queue behavior that cannot be meaningfully mocked — transactions across multiple tables, time-based queries, or complex query planner behavior.

Check failure on line 52 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L52

[Vale.Spelling] Did you really mean 'Testcontainers'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Testcontainers'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 52, "column": 10}}}, "severity": "ERROR"}

Check failure on line 52 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L52

[Google.EmDash] Don't put a space before or after a dash.
Raw output
{"message": "[Google.EmDash] Don't put a space before or after a dash.", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 52, "column": 117}}}, "severity": "ERROR"}

Many teams combine tools: Keploy for the regression layer, Postman for exploratory development, and Testcontainers for the small number of tests where real database behavior is the point.

Check failure on line 54 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L54

[Vale.Spelling] Did you really mean 'Testcontainers'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Testcontainers'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 54, "column": 101}}}, "severity": "ERROR"}

## Migration paths

If you are currently using Postman or Katalon and want to evaluate Keploy without throwing away existing work:

Check failure on line 58 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L58

[Vale.Spelling] Did you really mean 'Katalon'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'Katalon'?", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 58, "column": 39}}}, "severity": "ERROR"}

1. Run a 15-minute capture session against your staging environment while a human exercises the endpoints you already have Postman collections for.
2. Commit the generated `keploy/` directory to git.
3. Run `keploy test` in CI alongside your existing Postman suite.
4. Compare the two suites over a few sprints — which catches more regressions, which has more false positives, which takes more engineering time to maintain.

Check failure on line 63 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L63

[Google.EmDash] Don't put a space before or after a dash.
Raw output
{"message": "[Google.EmDash] Don't put a space before or after a dash.", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 63, "column": 45}}}, "severity": "ERROR"}
5. If Keploy wins, retire the Postman collections gradually.

The Keploy CLI can also ingest existing OpenAPI specs or Postman collections as a starting point for test generation, so you do not have to rebuild coverage from scratch.

## Related reading

- [How Keploy works](./how-keploy-works.md) — the eBPF capture + replay architecture in detail

Check failure on line 70 in versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md

View workflow job for this annotation

GitHub Actions / vale

[vale] versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md#L70

[Google.EmDash] Don't put a space before or after a dash.
Raw output
{"message": "[Google.EmDash] Don't put a space before or after a dash.", "location": {"path": "versioned_docs/version-4.0.0/keploy-explained/keploy-vs-alternatives.md", "range": {"start": {"line": 70, "column": 44}}}, "severity": "ERROR"}
- [Keploy integration testing FAQs](./integration-testing-faq.md)
- [Keploy API testing FAQs](./api-testing-faq.md)
5 changes: 5 additions & 0 deletions versioned_sidebars/version-4.0.0-sidebars.json

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in b56c813 — removed the sidebar entry for keploy-explained/keploy-vs-alternatives.

Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@
"label": "Troubleshooting Guide",
"id": "keploy-explained/common-errors"
},
{
"type": "doc",
"label": "Keploy vs Alternatives",
"id": "keploy-explained/keploy-vs-alternatives"
},

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title/description focuses on BreadcrumbList + robots, but this sidebar change introduces a new doc page in the v4 sidebar. Please either update the PR description/title to include this new documentation addition (and its intent), or split it into a separate PR to keep the audit fixes isolated.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the PR title and description to match the actual scope. The PR is now titled "audit: BreadcrumbList, robots policy, og:title, sidebar + Keploy vs Alternatives" and the description has a dedicated Task 33 — Keploy vs Alternatives comparison page section explaining the new doc (feature matrix vs Postman/Katalon/WireMock/Testcontainers, approach differences, when-to-pick-each) and the sidebar entry under keploy-explained, with a link to commit 5de8526.

Went with "update description" rather than "split PR" because each audit concern is already in its own commit, so review granularity is preserved without the overhead of rebasing out one commit onto a new branch. If you'd still prefer a split, happy to do that — just let me know.

{
"type": "doc",
"label": "FAQs",
Expand Down
Loading