-
-
Notifications
You must be signed in to change notification settings - Fork 290
audit: BreadcrumbList, robots policy, og:title, sitemap priorities #832
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
0ba5264
4b143f0
758cff5
3ffe847
56cae9e
5de8526
0af8f3c
3c8ac01
b56c813
69e5eee
3622c50
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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
|
||
| return item; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are we suppressing, how does this help?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 Why: What breaks without it:
Scope: It only affects the docs root and category index pages. Every normal content page ( If you want it removed anyway: say the word and I'll strip it. The cost is that |
||
| // /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, | ||
|
|
@@ -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 && ( | ||
|
|
||
| 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
|
||||||||||
|
|
||||||||||
| # ============================================================================= | ||||||||||
| # 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: / | ||||||||||
|
||||||||||
| Allow: / | |
| Allow: / | |
| Crawl-delay: 5 | |
| Disallow: /cgi-bin/ |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
Copilot
AI
Apr 14, 2026
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
|
||
| |---|---|---|---|---|---| | ||
| | 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 | | ||
|
||
| | 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
|
||
| | 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
|
||
| | 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
|
||
|
|
||
| **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
|
||
|
|
||
| **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
|
||
|
|
||
| **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
|
||
|
|
||
| ## 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
|
||
| - **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
|
||
|
|
||
| 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
|
||
|
|
||
| ## 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
|
||
|
|
||
| 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
|
||
| 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
|
||
| - [Keploy integration testing FAQs](./integration-testing-faq.md) | ||
| - [Keploy API testing FAQs](./api-testing-faq.md) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
|---|---|---|
|
|
@@ -166,6 +166,11 @@ | |
| "label": "Troubleshooting Guide", | ||
| "id": "keploy-explained/common-errors" | ||
| }, | ||
| { | ||
| "type": "doc", | ||
| "label": "Keploy vs Alternatives", | ||
| "id": "keploy-explained/keploy-vs-alternatives" | ||
| }, | ||
|
||
| { | ||
| "type": "doc", | ||
| "label": "FAQs", | ||
|
|
||
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.