Skip to content

Fix testenv runtime links#234

Merged
eviltester merged 6 commits into
masterfrom
233-test-env-consistency
Jun 22, 2026
Merged

Fix testenv runtime links#234
eviltester merged 6 commits into
masterfrom
233-test-env-consistency

Conversation

@eviltester

@eviltester eviltester commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • make runtime docs and blog links resolve to the nested GitHub Pages testenv site instead of leaking anywaydata.com from testenv surfaces
  • rewrite inline help and tooltip link HTML through the shared runtime site resolver
  • rewrite standalone testenv root page links and add focused regression tests for the resolver, tooltip rewriting, and testenv page rewriting

Why

Issue #233 called out that testenv pages were mixing live-site and nested-site links. That created inconsistent docs destinations for users and for AI tooling reading the environment.

Validation

  • pnpm run verify:ui
  • pnpm run verify:local

Summary by CodeRabbit

Release Notes

  • New Features

    • Added consistent, environment-aware documentation and navigation URL generation (including placeholder-based header links) for all web entry pages.
  • Refactor

    • Updated help/tooltip content to use the configured docs URLs and improved runtime rewriting for valid docs links.
    • Help tooltips now coordinate opening (hide other tooltips) and reliably update aria-expanded.
  • Bug Fixes

    • Improved domain keyword argument validation by enforcing correct min/max ordering across relevant keyword types.
  • Tests

    • Expanded and adjusted unit/integration coverage for URL generation, placeholders, tooltip behavior, and ordered-bounds validation.

Copilot AI review requested due to automatic review settings June 21, 2026 14:22
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a26669a9-76c2-4459-af45-1650d956a098

📥 Commits

Reviewing files that changed from the base of the PR and between d6afc25 and ec1b8db.

📒 Files selected for processing (24)
  • packages/core-ui/js/site/site-config-core.js
  • packages/core-ui/src/tests/grid/generation/test-data-generation-service.test.js
  • packages/core-ui/src/tests/grid/tabulator-performance.benchmark.test.js
  • packages/core-ui/src/tests/shared/schema-row-validation.test.js
  • packages/core-ui/src/tests/shared/site-config.test.js
  • packages/core/js/domain/domain-keyword-arg-validators.js
  • packages/core/js/domain/domain-keywords.js
  • packages/core/js/keywords/domain/date/between-keyword-definition.js
  • packages/core/js/keywords/domain/date/betweens-keyword-definition.js
  • packages/core/js/keywords/domain/date/birthdate-keyword-definition.js
  • packages/core/js/keywords/domain/finance/amount-keyword-definition.js
  • packages/core/js/keywords/domain/location/latitude-keyword-definition.js
  • packages/core/js/keywords/domain/location/longitude-keyword-definition.js
  • packages/core/js/keywords/domain/number/binary-keyword-definition.js
  • packages/core/js/keywords/domain/number/float-keyword-definition.js
  • packages/core/js/keywords/domain/number/hex-keyword-definition.js
  • packages/core/js/keywords/domain/number/int-keyword-definition.js
  • packages/core/js/keywords/domain/number/octal-keyword-definition.js
  • packages/core/js/keywords/domain/number/roman-numeral-keyword-definition.js
  • packages/core/src/tests/data_generation/schema-rules-adapter.test.js
  • packages/core/src/tests/data_generation/unit/domain/domain-test-data-rule-validator.test.js
  • packages/core/src/tests/data_generation/unit/domain/domainKeywords.test.js
  • scripts/create-testenv.mjs
  • tests/integration/cross-surface-amend-trim-parity.test.js
💤 Files with no reviewable changes (1)
  • packages/core-ui/src/tests/grid/tabulator-performance.benchmark.test.js
✅ Files skipped from review due to trivial changes (2)
  • packages/core/js/keywords/domain/location/latitude-keyword-definition.js
  • packages/core/src/tests/data_generation/unit/domain/domain-test-data-rule-validator.test.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/core-ui/src/tests/shared/site-config.test.js
  • packages/core-ui/js/site/site-config-core.js
  • scripts/create-testenv.mjs

📝 Walkthrough

Walkthrough

Introduces a site-config system (site-config-core.js, site-config.production.js) that centralizes docs/blog URL building via createSiteConfig/buildDocsUrl/resolveOwnedSiteUrl. All components migrate from hardcoded URLs to these helpers. The web build gains HTML placeholder injection via site-config-html.mjs and an async Vite config. The testenv script generates a per-repo site-config override before building. runtime-docs-url.js is expanded with owned-path normalization, resolveRuntimeSiteUrl, and rewriteRuntimeSiteLinksHtml. Additionally, domain keyword argument validation is implemented via createOrderedArgsValidator to enforce min/max bounds ordering across date, finance, location, and numeric keyword types, with comprehensive test coverage.

Changes

Site-Config URL System

Layer / File(s) Summary
site-config-core factory and production instance
packages/core-ui/js/site/site-config-core.js, packages/core-ui/js/site/site-config.production.js, jest.config.cjs, .storybook/main.js, packages/core-ui/src/tests/shared/site-config.test.js
Adds PRODUCTION_SITE_ORIGIN, normalization helpers, createSiteConfig, resolveOwnedSiteUrl, and serializeSiteConfigModuleSource in core; instantiates the production config; registers the @anywaydata/site-config alias in Jest and Storybook; adds a test suite validating production hrefs and override behavior.
runtime-docs-url.js: owned-path normalization and rewriting
packages/core-ui/js/gui_components/shared/test-data/help/runtime-docs-url.js
Replaces the single-function module with normaliseOwnedSitePath, resolveRuntimeSiteUrl (with GitHub Pages base-path handling), a constrained resolveRuntimeDocsUrl, and rewriteRuntimeSiteLinksHtml for DOM-based link rewriting; expands exports.
Component migration to buildDocsUrl / resolveOwnedSiteUrl
packages/core-ui/js/gui_components/shared/test-data/help/help-model-builder.js, ...ui/method-picker-modal.js, ...ui/params-editor-modal.js, ...shared/domain-command-help-metadata.js, packages/core-ui/js/gui_components/generator/..., packages/core-ui/js/gui_components/app/test-data-population-toolbar/..., packages/core-ui/js/help/inline-help-content.js
Replaces hardcoded https://anywaydata.com/docs/... and /docs/... URLs with buildDocsUrl(...) calls; removes resolveRuntimeDocsUrl from modal UI components; drops windowObj from buildSchemaHelpModel.
Help tooltips: pass documentObj/windowObj and hide other tippies
packages/core-ui/js/help/help-tooltips.js
Adds a third { documentObj, windowObj } options parameter to buildHelpTooltipContent and passes resolved objects from the tippy content callback; adds hideOtherOpenTippies helper to close other open tooltips when a tooltip is shown.
HTML placeholder injection: site-config-html.mjs, Vite config, web HTML pages
apps/web/site-config-html.mjs, apps/web/vite.config.mjs, apps/web/*.html
Adds SITE_LINK_PLACEHOLDERS, createSiteLinkPlaceholderMap, and transformStandaloneHtmlWithSiteConfig; converts vite.config.mjs to an async factory that dynamically imports the site-config (with ANYWAYDATA_SITE_CONFIG_OVERRIDE_PATH override) and injects placeholder replacement via a transformIndexHtml plugin; all five web HTML pages use %ANYWAYDATA_*_HREF% placeholders.
testenv script: site-config override generation
scripts/create-testenv.mjs
Adds createTestEnvSiteConfigInput and writeGeneratedTestEnvSiteConfigOverride; main() generates a temporary _site-config.override.mjs via serializeSiteConfigModuleSource before the Vite build, sets ANYWAYDATA_SITE_CONFIG_OVERRIDE_PATH, and cleans up afterward; live-link updated to ./site/.
Tests: site-config, HTML placeholder, and testenv override
apps/web/src/tests/jest/site-config-html.test.js, apps/web/src/tests/jest/testenv-site-config-override.test.js, packages/core-ui/src/tests/shared/site-config.test.js
Adds test suites validating production config hrefs, placeholder map generation, testenv override file generation, and config reuse/override scenarios.
Tests: help models, method-picker, and tooltips
packages/core-ui/src/tests/shared/help-model-builder.test.js, packages/core-ui/src/tests/utils/method-picker-modal.test.js, packages/core-ui/src/tests/utils/help-tooltips.test.js
Updates tests to assert authored URLs are preserved without runtime localization; adds coverage for tooltip interactions (tippy.hideAll closing other instances) and absolute link preservation in help content.

Domain Keyword Argument Validation

Layer / File(s) Summary
createOrderedArgsValidator factory and domain keyword integration
packages/core/js/domain/domain-keyword-arg-validators.js, packages/core/js/domain/domain-keywords.js
Adds createOrderedArgsValidator to build validators enforcing lower-bound <= upper-bound constraints; updates domain keyword validation to build an argsByName map and perform optional semantic validation via keyword.help.argsValidator before returning validation results.
Date keyword validators
packages/core/js/keywords/domain/date/between-keyword-definition.js, betweens-keyword-definition.js, birthdate-keyword-definition.js
Adds ordered-args validators for date.between (from/to), date.betweens (from/to), and date.birthdate (min/max), each enforcing lower/upper bound ordering.
Numeric keyword validators
packages/core/js/keywords/domain/number/{int,float,binary,hex,octal,roman-numeral}-keyword-definition.js
Adds ordered-args validators enforcing min <= max across all numeric keyword types (integer, float, binary, hex, octal, roman-numeral).
Finance and location keyword validators
packages/core/js/keywords/domain/finance/amount-keyword-definition.js, packages/core/js/keywords/domain/location/{latitude,longitude}-keyword-definition.js
Adds ordered-args validators for finance.amount (min/max), location.latitude (min/max), and location.longitude (min/max).
Tests: bounds validation across rules, validators, and keywords
packages/core/src/tests/data_generation/schema-rules-adapter.test.js, packages/core/src/tests/data_generation/unit/domain/domain-test-data-rule-validator.test.js, packages/core/src/tests/data_generation/unit/domain/domainKeywords.test.js, packages/core-ui/src/tests/grid/generation/test-data-generation-service.test.js, packages/core-ui/src/tests/shared/schema-row-validation.test.js
Adds comprehensive test coverage for reversed bounds rejection at every level: schema rules adapter, rule validator, keyword arguments, end-to-end generation service, and semantic validation messages.
Integration test timeout consolidation
tests/integration/cross-surface-amend-trim-parity.test.js
Adds CROSS_SURFACE_PROCESS_TIMEOUT_MS constant and replaces three hardcoded subprocess timeout values with the unified constant to support stable full-suite runs.

Sequence Diagram

sequenceDiagram
  participant HTMLPage as HTML Page
  participant ViteConfig as Vite Config
  participant SiteConfigModule as Site Config Module
  participant PlaceholderMap as Placeholder Map
  participant SiteConfig as Site Config Factory

  ViteConfig->>SiteConfigModule: dynamic import (overridable path)
  SiteConfigModule-->>ViteConfig: siteConfig instance
  ViteConfig->>PlaceholderMap: createSiteLinkPlaceholderMap(siteConfig)
  PlaceholderMap-->>ViteConfig: %ANYWAYDATA_*% → href map
  ViteConfig->>ViteConfig: register transformIndexHtml plugin
  HTMLPage->>ViteConfig: build request with %ANYWAYDATA_*% placeholders
  ViteConfig->>PlaceholderMap: transformStandaloneHtmlWithSiteConfig(html, siteConfig)
  PlaceholderMap-->>ViteConfig: resolved HTML with final hrefs
  ViteConfig-->>HTMLPage: output with injected URLs
Loading

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • eviltester/grid-table-editor#206: Main PR's change to packages/core-ui/js/gui_components/shared/test-data/ui/params-editor-modal.js (switching "Learn more" link generation to use helpModel.docsUrl directly instead of resolveRuntimeDocsUrl) directly overlaps with the retrieved PR's implementation of the guided params editor modal in the same file.
  • eviltester/grid-table-editor#229: Both PRs touch help/command help metadata plumbing—especially packages/core-ui/js/gui_components/shared/test-data/help/help-model-builder.js—changing how faker/domain help is sourced and how docsUrl is produced (runtime URL resolution vs adapter-driven help metadata).

🐰 Hop, hop, no more hard-coded trails,
buildDocsUrl now never fails!
Placeholders bloom where raw hrefs stood,
Min meets max in ordered wood—
Config is frozen, but links stay alive,
This rabbit's URLs and bounds now thrive! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title "Fix testenv runtime links" accurately and concisely captures the main change: fixing runtime links in the test environment. It directly relates to the primary objective stated in the PR summary.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 233-test-env-consistency

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/core-ui/js/site/site-config-core.js

Oops! Something went wrong! :(

ESLint: 10.4.1

A config object is using the "root" key, which is not supported in flat config system.

Flat configs always act as if they are the root config file, so this key can be safely removed.

packages/core-ui/src/tests/grid/generation/test-data-generation-service.test.js

Oops! Something went wrong! :(

ESLint: 10.4.1

A config object is using the "root" key, which is not supported in flat config system.

Flat configs always act as if they are the root config file, so this key can be safely removed.

packages/core-ui/src/tests/shared/schema-row-validation.test.js

Oops! Something went wrong! :(

ESLint: 10.4.1

A config object is using the "root" key, which is not supported in flat config system.

Flat configs always act as if they are the root config file, so this key can be safely removed.

  • 20 others
🔧 ast-grep (0.44.0)
packages/core-ui/src/tests/grid/generation/test-data-generation-service.test.js

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core-ui/js/gui_components/shared/test-data/help/runtime-docs-url.js (1)

27-33: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle /docs root URLs in owned-path normalization.

normaliseOwnedSitePath rewrites /docs/... but not /docs (and docs). That makes the sitePath === '/docs' branch in resolveRuntimeDocsUrl effectively unreachable for relative/root docs links, so those links stay pointed at production instead of the runtime/testenv host.

Suggested fix
-  if (value.startsWith('/docs/')) {
+  if (value === '/docs' || value.startsWith('/docs/')) {
     return value;
   }

-  if (value.startsWith('docs/')) {
+  if (value === 'docs' || value.startsWith('docs/')) {
     return `/${value}`;
   }
...
     if (
       parsed.pathname === '/' ||
+      parsed.pathname === '/docs' ||
       parsed.pathname.startsWith('/docs/') ||
       parsed.pathname === '/blog' ||
       parsed.pathname.startsWith('/blog/')
     ) {

Also applies to: 48-53, 98-100

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core-ui/js/gui_components/shared/test-data/help/runtime-docs-url.js`
around lines 27 - 33, The `normaliseOwnedSitePath` function in the diff handles
paths starting with `/docs/` and `docs/` but does not handle the root paths
`/docs` and `docs` themselves. Add logic to check if the value equals `/docs`
and return it as-is, and if the value equals `docs` return `/docs`. This will
ensure that root documentation links are properly normalized and the `sitePath
=== '/docs'` branch in `resolveRuntimeDocsUrl` becomes reachable for
relative/root docs links, allowing them to point to the runtime/testenv host
instead of production.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/tests/jest/testenv-root-page-links.test.js`:
- Around line 4-16: The test function `rewrites docs and blog links to the
nested site path` currently only validates docs subpaths like `docs/intro` and
the blog path, but it is missing test coverage for root docs paths. Add test
cases in the html string within this test function to include anchor elements
that reference `/docs` (the absolute docs root path) and other root
documentation paths, then add corresponding expect statements to verify that
these root paths are properly rewritten to `./site/docs` format. This will
ensure that root docs path leakage is caught by the tests.

In `@packages/core-ui/src/tests/shared/runtime-docs-url.test.js`:
- Around line 23-35: The test suite for resolveRuntimeDocsUrl only validates
rewrites for paths like /docs/test-data/domain/number but lacks a regression
case for the root /docs path itself. Add a new test case to this suite that
calls resolveRuntimeDocsUrl with just /docs as the input parameter (using the
same windowObj structure with github pages configuration) and verify that it
correctly rewrites to include the nested site path in the output URL, matching
the pattern demonstrated in the existing test.

In `@scripts/create-testenv.mjs`:
- Around line 211-227: The resolveTestEnvRootHref function handles docs subpaths
but misses the root forms of documentation URLs (https://anywaydata.com/docs,
/docs, and docs without trailing slashes), allowing them to bypass rewriting and
remain production-facing. Add additional condition checks before the existing
logic to handle these root URL forms specifically, ensuring that
https://anywaydata.com/docs returns ./site/docs, /docs returns ./site/docs, and
docs returns ./site/docs. Insert these root URL checks early in the function to
intercept these cases before they fall through to other conditions.

---

Outside diff comments:
In
`@packages/core-ui/js/gui_components/shared/test-data/help/runtime-docs-url.js`:
- Around line 27-33: The `normaliseOwnedSitePath` function in the diff handles
paths starting with `/docs/` and `docs/` but does not handle the root paths
`/docs` and `docs` themselves. Add logic to check if the value equals `/docs`
and return it as-is, and if the value equals `docs` return `/docs`. This will
ensure that root documentation links are properly normalized and the `sitePath
=== '/docs'` branch in `resolveRuntimeDocsUrl` becomes reachable for
relative/root docs links, allowing them to point to the runtime/testenv host
instead of production.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a438cd0-ee47-4fe2-96a9-5e4f009bcf5c

📥 Commits

Reviewing files that changed from the base of the PR and between 5a65c75 and 33d8e13.

📒 Files selected for processing (6)
  • apps/web/src/tests/jest/testenv-root-page-links.test.js
  • packages/core-ui/js/gui_components/shared/test-data/help/runtime-docs-url.js
  • packages/core-ui/js/help/help-tooltips.js
  • packages/core-ui/src/tests/shared/runtime-docs-url.test.js
  • packages/core-ui/src/tests/utils/help-tooltips.test.js
  • scripts/create-testenv.mjs

Comment on lines +4 to +16
test('rewrites docs and blog links to the nested site path', () => {
const html = `
<div class="header">
<a href="docs/intro">Docs</a>
<a href="/blog">Blog</a>
</div>
`;

const rewritten = rewriteTestEnvRootPageLinks(html);

expect(rewritten).toContain('href="./site/docs/intro"');
expect(rewritten).toContain('href="./site/blog"');
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add assertions for docs-root rewrites (/docs and absolute docs root).

Current tests validate docs subpaths only; they won’t catch root docs leakage.

Also applies to: 18-26

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/tests/jest/testenv-root-page-links.test.js` around lines 4 - 16,
The test function `rewrites docs and blog links to the nested site path`
currently only validates docs subpaths like `docs/intro` and the blog path, but
it is missing test coverage for root docs paths. Add test cases in the html
string within this test function to include anchor elements that reference
`/docs` (the absolute docs root path) and other root documentation paths, then
add corresponding expect statements to verify that these root paths are properly
rewritten to `./site/docs` format. This will ensure that root docs path leakage
is caught by the tests.

Comment on lines +23 to +35
test('rewrites docs links into the nested site path for github pages root pages', () => {
const resolved = resolveRuntimeDocsUrl('/docs/test-data/domain/number', {
windowObj: {
location: {
origin: 'https://eviltester.github.io',
hostname: 'eviltester.github.io',
pathname: '/grid-table-editor/generator.html',
},
},
});

expect(resolved).toBe('https://eviltester.github.io/grid-table-editor/site/docs/test-data/domain/number');
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a regression case for /docs root rewriting.

The suite validates /docs/... but not /docs, so it won’t catch the root-path miss in the resolver.

Suggested test addition
+  test('rewrites docs root links into the nested site path for github pages root pages', () => {
+    const resolved = resolveRuntimeDocsUrl('/docs', {
+      windowObj: {
+        location: {
+          origin: 'https://eviltester.github.io',
+          hostname: 'eviltester.github.io',
+          pathname: '/grid-table-editor/generator.html',
+        },
+      },
+    });
+
+    expect(resolved).toBe('https://eviltester.github.io/grid-table-editor/site/docs');
+  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('rewrites docs links into the nested site path for github pages root pages', () => {
const resolved = resolveRuntimeDocsUrl('/docs/test-data/domain/number', {
windowObj: {
location: {
origin: 'https://eviltester.github.io',
hostname: 'eviltester.github.io',
pathname: '/grid-table-editor/generator.html',
},
},
});
expect(resolved).toBe('https://eviltester.github.io/grid-table-editor/site/docs/test-data/domain/number');
});
test('rewrites docs links into the nested site path for github pages root pages', () => {
const resolved = resolveRuntimeDocsUrl('/docs/test-data/domain/number', {
windowObj: {
location: {
origin: 'https://eviltester.github.io',
hostname: 'eviltester.github.io',
pathname: '/grid-table-editor/generator.html',
},
},
});
expect(resolved).toBe('https://eviltester.github.io/grid-table-editor/site/docs/test-data/domain/number');
});
test('rewrites docs root links into the nested site path for github pages root pages', () => {
const resolved = resolveRuntimeDocsUrl('/docs', {
windowObj: {
location: {
origin: 'https://eviltester.github.io',
hostname: 'eviltester.github.io',
pathname: '/grid-table-editor/generator.html',
},
},
});
expect(resolved).toBe('https://eviltester.github.io/grid-table-editor/site/docs');
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core-ui/src/tests/shared/runtime-docs-url.test.js` around lines 23 -
35, The test suite for resolveRuntimeDocsUrl only validates rewrites for paths
like /docs/test-data/domain/number but lacks a regression case for the root
/docs path itself. Add a new test case to this suite that calls
resolveRuntimeDocsUrl with just /docs as the input parameter (using the same
windowObj structure with github pages configuration) and verify that it
correctly rewrites to include the nested site path in the output URL, matching
the pattern demonstrated in the existing test.

Comment thread scripts/create-testenv.mjs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to make all docs/blog/runtime links shown in GitHub Pages “testenv” surfaces resolve into the nested site/ path (instead of pointing at anywaydata.com), and adds regression tests to prevent link drift.

Changes:

  • Add a runtime “site URL” resolver + HTML snippet link rewriter, and use it when rendering tooltip content.
  • Rewrite root-page HTML links (app/generator/etc) during create-testenv so their docs/blog links point to ./site/....
  • Add focused Jest tests covering the resolver, tooltip rewriting, and testenv root-page link rewriting.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scripts/create-testenv.mjs Adds href-rewriting utilities and applies them to built root pages so docs/blog/home links point to ./site/....
packages/core-ui/js/help/help-tooltips.js Rewrites tooltip HTML through the shared runtime site link resolver before rendering.
packages/core-ui/js/gui_components/shared/test-data/help/runtime-docs-url.js Expands runtime URL logic to handle site + docs/blog and provides HTML rewriting for <a href>.
packages/core-ui/src/tests/utils/help-tooltips.test.js Adds a regression test asserting tooltip HTML rewrites docs/blog links in GitHub Pages environments.
packages/core-ui/src/tests/shared/runtime-docs-url.test.js Adds unit tests for runtime site/docs resolution + HTML snippet rewriting.
apps/web/src/tests/jest/testenv-root-page-links.test.js Adds tests for the create-testenv root page HTML link rewriting behavior.

Comment on lines +134 to +135
root.innerHTML =
'<span class="helpicon" data-help-role="help-icon" data-help-text=\'<p><a href="/docs/intro">Docs</a> <a href="blog">Blog</a></p>\'></span>';
Comment on lines 27 to 33
@@ -22,10 +32,26 @@ function toDocsPath(url) {
return `/${value}`;
}
Comment on lines 48 to 55
if (
parsed.pathname === '/' ||
parsed.pathname.startsWith('/docs/') ||
parsed.pathname === '/blog' ||
parsed.pathname.startsWith('/blog/')
) {
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
}
@greptile-apps

greptile-apps Bot commented Jun 21, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces runtime-resolved docs/blog links in the testenv with build-time URL resolution via a new centralized site-config-core.js module. All inline help content, tooltip links, and HTML nav placeholders now resolve through a buildDocsUrl/resolveOwnedSiteUrl abstraction backed by the appropriate site config (production or testenv override).

  • Centralized site config: Introduces site-config-core.js with createSiteConfig, resolveOwnedSiteUrl, and serializeSiteConfigModuleSource, replacing the deleted runtime-docs-url.js file and its window-location-based URL patching.
  • Build-time HTML rewriting: Adds a Vite plugin (anywaydata-site-config-html-transform) and placeholder tokens (%ANYWAYDATA_*_HREF%) in all standalone HTML pages so links resolve to the correct root at build time without JavaScript.
  • Testenv override generation: create-testenv.mjs writes a generated site config override module before invoking Vite, and cleans it up in a finally block; the semantic args validator (createOrderedArgsValidator) for domain keywords (number bounds, date ranges) is also wired up in the same PR.

Confidence Score: 5/5

Safe to merge — all link resolution is now build-time and the testenv override is written and cleaned up correctly.

The link-rewriting logic is replaced by a build-time abstraction with thorough test coverage for every edge case (exact root, sub-path, cross-config rewriting). The testenv override file is generated before Vite starts and cleaned up in a finally block. The new argsValidator for domain keywords uses numeric/lexicographic comparison that is correct for both number and ISO-date arg types. No regressions were introduced in existing call sites.

No files require special attention.

Important Files Changed

Filename Overview
packages/core-ui/js/site/site-config-core.js New core module providing createSiteConfig, resolveOwnedSiteUrl, and serializeSiteConfigModuleSource; normalisation helpers are thorough and tests cover the exact-root edge case.
scripts/create-testenv.mjs Generates a testenv site config override before the Vite build and cleans up both the override and the temp web dir in a finally block; build sequencing and cleanup are correct.
apps/web/vite.config.mjs Converts to an async factory config; dynamically imports the site config module (resolved via ANYWAYDATA_SITE_CONFIG_OVERRIDE_PATH env var or the production default) and adds the HTML placeholder transform plugin.
packages/core-ui/js/help/inline-help-content.js All doc links now resolved via buildDocsUrl at module load time; URLs are baked in from the resolved @anywaydata/site-config alias rather than being hardcoded production strings.
packages/core-ui/js/help/help-tooltips.js buildHelpTooltipContent accepts documentObj/windowObj for future API compatibility but voids them; adds hideOtherOpenTippies helper and wires it into onShow.
apps/web/site-config-html.mjs New module defining SITE_LINK_PLACEHOLDERS, createSiteLinkPlaceholderMap, and transformStandaloneHtmlWithSiteConfig; uses optional chaining with sensible fallbacks.
packages/core/js/domain/domain-keyword-arg-validators.js New createOrderedArgsValidator factory for semantic bounds checking; correctly skips validation when either bound is absent and uses JS > which works for both numeric and ISO-string date args.
packages/core/js/domain/domain-keywords.js Adds argsValidator hook to the keyword catalog and calls it after per-arg validation in validateDomainKeywordArgs; builds argsByName correctly from named arg specs.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[create-testenv.mjs] -->|writes| B[_site-config.override.mjs]
    B -->|ANYWAYDATA_SITE_CONFIG_OVERRIDE_PATH env| C[vite.config.mjs async factory]
    D[site-config.production.js] -->|default, no env var| C
    C -->|dynamic import| E[siteConfig object]
    E -->|Vite alias @anywaydata/site-config| F[inline-help-content.js
buildDocsUrl at module load]
    E -->|Vite alias @anywaydata/site-config| G[help-model-builder.js
resolveOwnedSiteUrl]
    E -->|transformIndexHtml plugin| H[HTML placeholder replacement
%ANYWAYDATA_*_HREF%]
    H --> I[app.html / generator.html
combinatorial.html / webmcp.html
index.html]
    A -->|finally block cleanup| J[rm _site-config.override.mjs]
    subgraph site-config-core.js
        K[createSiteConfig]
        L[resolveOwnedSiteUrl]
        M[serializeSiteConfigModuleSource]
    end
    D --> K
    B --> M
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[create-testenv.mjs] -->|writes| B[_site-config.override.mjs]
    B -->|ANYWAYDATA_SITE_CONFIG_OVERRIDE_PATH env| C[vite.config.mjs async factory]
    D[site-config.production.js] -->|default, no env var| C
    C -->|dynamic import| E[siteConfig object]
    E -->|Vite alias @anywaydata/site-config| F[inline-help-content.js
buildDocsUrl at module load]
    E -->|Vite alias @anywaydata/site-config| G[help-model-builder.js
resolveOwnedSiteUrl]
    E -->|transformIndexHtml plugin| H[HTML placeholder replacement
%ANYWAYDATA_*_HREF%]
    H --> I[app.html / generator.html
combinatorial.html / webmcp.html
index.html]
    A -->|finally block cleanup| J[rm _site-config.override.mjs]
    subgraph site-config-core.js
        K[createSiteConfig]
        L[resolveOwnedSiteUrl]
        M[serializeSiteConfigModuleSource]
    end
    D --> K
    B --> M
Loading

Reviews (5): Last reviewed commit: "Fix site config root links and cleanup" | Re-trigger Greptile

Comment on lines +98 to +101
const sitePath = normaliseOwnedSitePath(value);
if (!sitePath || (!sitePath.startsWith('/docs/') && sitePath !== '/docs')) {
return value;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 sitePath !== '/docs' is dead code. normaliseOwnedSitePath never returns the exact string '/docs': the bare path '/docs' doesn't match the startsWith('/docs/') guard (needs trailing slash), 'docs' without a slash fails the startsWith('docs/') check and then throws as an invalid URL, and https://anywaydata.com/docs produces parsed.pathname === '/docs' which isn't in the URL-branch allow-list. The branch is permanently false, so the condition can be simplified.

Suggested change
const sitePath = normaliseOwnedSitePath(value);
if (!sitePath || (!sitePath.startsWith('/docs/') && sitePath !== '/docs')) {
return value;
}
const sitePath = normaliseOwnedSitePath(value);
if (!sitePath || !sitePath.startsWith('/docs/')) {
return value;
}

Comment thread packages/core-ui/js/gui_components/shared/test-data/help/runtime-docs-url.js Outdated
Comment thread scripts/create-testenv.mjs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/create-testenv.mjs (1)

601-674: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Ensure temp artifacts are cleaned up on failure paths.

tempSiteConfigOverridePath (and tempWebDir) are cleaned only on the success path. If a command fails between Line 608 and Line 669, these files can remain and pollute later local runs.

Suggested fix
 async function main() {
   await clearDirectoryContents(outputDir);

   const buildMetadata = resolveBuildMetadata();
   const fullSiteBaseUrl = resolveFullSiteBaseUrl();
   await writeGeneratedTestEnvSiteConfigOverride(tempSiteConfigOverridePath);

-  runCommand(
-    'pnpm',
-    [
-      'exec',
-      'vite',
-      'build',
-      '--config',
-      path.join(repoRoot, 'apps', 'web', 'vite.config.mjs'),
-      '--base',
-      './',
-      '--outDir',
-      tempWebDir,
-    ],
-    {
-      env: {
-        ANYWAYDATA_SITE_CONFIG_OVERRIDE_PATH: tempSiteConfigOverridePath,
-      },
-    }
-  );
+  try {
+    runCommand(
+      'pnpm',
+      [
+        'exec',
+        'vite',
+        'build',
+        '--config',
+        path.join(repoRoot, 'apps', 'web', 'vite.config.mjs'),
+        '--base',
+        './',
+        '--outDir',
+        tempWebDir,
+      ],
+      {
+        env: {
+          ANYWAYDATA_SITE_CONFIG_OVERRIDE_PATH: tempSiteConfigOverridePath,
+        },
+      }
+    );

-  await copyWebBuildIntoDirectory(tempWebDir, outputDir);
-  ...
-  await rm(tempWebDir, {
-    recursive: true,
-    force: true,
-  });
-  await rm(tempSiteConfigOverridePath, { force: true });
+    await copyWebBuildIntoDirectory(tempWebDir, outputDir);
+    ...
+  } finally {
+    await rm(tempWebDir, { recursive: true, force: true });
+    await rm(tempSiteConfigOverridePath, { force: true });
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/create-testenv.mjs` around lines 601 - 674, The main function creates
temporary artifacts (tempSiteConfigOverridePath and tempWebDir) but only cleans
them up at the end of the success path. If any runCommand call fails between
creation and cleanup, these files persist and pollute subsequent runs. Wrap the
entire main function body in a try-finally block (similar to the docusaurus
build section that already uses try-finally) to ensure the cleanup code that
removes tempSiteConfigOverridePath and tempWebDir at the end is guaranteed to
execute regardless of command failures or exceptions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core-ui/js/site/site-config-core.js`:
- Around line 41-49: The normalizeDocsPath function only removes the `docs/`
prefix but does not handle the exact `docs` path without a trailing slash, which
causes duplicate paths like `<base>/docs/docs` when processing exact URLs.
Modify the return statement in normalizeDocsPath to check if the trimmed path is
exactly equal to `docs` or starts with `docs/`, and remove it in both cases.
Apply the same fix to the corresponding blog path normalization function located
in the lines 51-59 range, ensuring both functions handle exact path matches
(`docs` and `blog`) in addition to prefixed matches (`docs/` and `blog/`).

---

Outside diff comments:
In `@scripts/create-testenv.mjs`:
- Around line 601-674: The main function creates temporary artifacts
(tempSiteConfigOverridePath and tempWebDir) but only cleans them up at the end
of the success path. If any runCommand call fails between creation and cleanup,
these files persist and pollute subsequent runs. Wrap the entire main function
body in a try-finally block (similar to the docusaurus build section that
already uses try-finally) to ensure the cleanup code that removes
tempSiteConfigOverridePath and tempWebDir at the end is guaranteed to execute
regardless of command failures or exceptions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1622d0bd-39ac-4bbe-96eb-6a3ce4d3815e

📥 Commits

Reviewing files that changed from the base of the PR and between 33d8e13 and bbd5c05.

📒 Files selected for processing (28)
  • .storybook/main.js
  • apps/web/app.html
  • apps/web/combinatorial.html
  • apps/web/generator.html
  • apps/web/index.html
  • apps/web/site-config-html.mjs
  • apps/web/src/tests/jest/site-config-html.test.js
  • apps/web/src/tests/jest/testenv-site-config-override.test.js
  • apps/web/vite.config.mjs
  • apps/web/webmcp.html
  • jest.config.cjs
  • packages/core-ui/js/gui_components/app/test-data-population-toolbar/test-data-population-toolbar-view.js
  • packages/core-ui/js/gui_components/generator/constants.js
  • packages/core-ui/js/gui_components/generator/controls/generator-controls-view.js
  • packages/core-ui/js/gui_components/shared/domain-command-help-metadata.js
  • packages/core-ui/js/gui_components/shared/test-data/help/help-model-builder.js
  • packages/core-ui/js/gui_components/shared/test-data/help/runtime-docs-url.js
  • packages/core-ui/js/gui_components/shared/test-data/ui/method-picker-modal.js
  • packages/core-ui/js/gui_components/shared/test-data/ui/params-editor-modal.js
  • packages/core-ui/js/help/help-tooltips.js
  • packages/core-ui/js/help/inline-help-content.js
  • packages/core-ui/js/site/site-config-core.js
  • packages/core-ui/js/site/site-config.production.js
  • packages/core-ui/src/tests/shared/help-model-builder.test.js
  • packages/core-ui/src/tests/shared/site-config.test.js
  • packages/core-ui/src/tests/utils/help-tooltips.test.js
  • packages/core-ui/src/tests/utils/method-picker-modal.test.js
  • scripts/create-testenv.mjs
💤 Files with no reviewable changes (1)
  • packages/core-ui/js/gui_components/shared/test-data/help/runtime-docs-url.js
✅ Files skipped from review due to trivial changes (11)
  • apps/web/src/tests/jest/site-config-html.test.js
  • packages/core-ui/js/gui_components/generator/constants.js
  • apps/web/index.html
  • packages/core-ui/js/gui_components/generator/controls/generator-controls-view.js
  • apps/web/generator.html
  • packages/core-ui/js/site/site-config.production.js
  • apps/web/site-config-html.mjs
  • packages/core-ui/src/tests/shared/site-config.test.js
  • jest.config.cjs
  • .storybook/main.js
  • apps/web/src/tests/jest/testenv-site-config-override.test.js

Comment thread packages/core-ui/js/site/site-config-core.js
@eviltester

Copy link
Copy Markdown
Owner Author

closes #233

@eviltester eviltester merged commit 5168a6f into master Jun 22, 2026
16 checks passed
@eviltester eviltester deleted the 233-test-env-consistency branch June 22, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants