FitNesse nested-context compatibility findings

Scope and result

This investigation covers the five wrong outer assertions on:

The acceptance pages and expected results were not changed. Each page was run against the external Perl service on FitNesse v20251025, and again with the Java SLiM service launched by an isolated FitNesse v20251025 instance. The target page contents in the workspace and pinned JAR were compared and match.

| Page / outer assertion | Expected | Perl result | Java reference | Classification | |---|---|---|---|---| | TestCustomComparators: nested scenario check echo test glob:t*t and direct-script check echo test glob:t*t | The configured glob comparator accepts actual test for expected t*t; nested page contains t*t matches test. | Both cells render test with expected [glob:t*t]. Outer assertion test results for page TestPage should contain t*t matches test fails; the separate 2 right, 0 wrong, 0 ignored, 0 exceptions check also fails. Page: 1/2/0/0. | Both checks pass; nested response contains t*t matches test. Page: 3/0/0/0. Java execution log reports java -cp /opt/fitnesse/fitnesse.jar fitnesse.slim.SlimService 1; its test-system log says Loaded custom comparator glob: fitnesse.testsystems.slim.GlobComparator. | FitNesse context loss in the Perl PageDriver; not a Perl comparator or SLiM instruction defect. | | CustomTableRenderingAddedByPluginTest: ensure content contains table class="myUseCase" | The configured alias resolves and the configured table decorator emits the myUseCase class. | Nested response has Could not find class MyUseCase; table class="myUseCase" is absent. The negative-control page also reports Could not find class MyFixture. Page: 5/1/0/0. | The positive nested page contains <table class="myUseCase">; the negative control omits it. The custom rendering plugin is registered in the Java test-system log. Page: 6/0/0/0. Java execution log names the Java SlimService command above. | FitNesse plugin/context loss in the Perl PageDriver; not Perl fixture return behavior or protocol. | | IgnoredTestsShouldColorGray: and cell Not Executed and should be ignored has result ignore | The nested response contains class="ignore">Not Executed and should be ignored<. | The generated nested page does not expand the corresponding scenario in the same way. Its response has <tr class="slimRowColor3"><td>Not Executed and should be ignored <span class="ignore">Test not run</span></td></tr>. This outer assertion fails. Page: 5/2/0/0. | The nested response contains <tr class="scenario closed"><td class="ignore">Not Executed and should be ignored</td>...; assertion passes. | Nested scenario/test context differs. This is not an obsolete v20251025 renderer expectation and not evidence that Perl ignore markers are wrong. | | IgnoredTestsShouldColorGray: and cell Not Executed and should be ignored as well has result ignore | The nested response contains class="ignore">Not Executed and should be ignored as well<. | Actual response has <tr class="slimRowColor5"><td>Not Executed and should be ignored as well <span class="ignore">Test not run</span></td></tr>. This outer assertion fails. | The nested response contains <tr class="scenario closed"><td class="ignore">Not Executed and should be ignored as well</td>...; assertion passes. | Same nested scenario/test-context limitation. |

The three result tuples are therefore Perl: 1/2/0/0, 5/1/0/0, 5/2/0/0 and Java: 3/0/0/0, 6/0/0/0, 7/0/0/0, in right/wrong/ignored/exception order. The Java comparison classifies all five outer assertions as passing and all five Perl assertions as failing. It does not by itself establish a protocol defect: the harness execution contexts differ.

Backend and response evidence

The Perl requests were made to the existing FitNesse HTTP server configured with manually.start.test.runner=true, slim.host=127.0.0.1, and slim.port=8099. Each page's XML execution log reports Connection to running SlimService: 127.0.0.1:8099 with exit code 0, and the Perl listener logged request and response frames. The nested pages were created and requested by the Perl PageDriver adapter in t/lib/Fitnesse/Fixtures/PageDriver.pm; their HTML, including the missing alias and literal/ordinary ignored rows above, is captured in the outer result XML under FitNesse's saved test history.

The Java runs used a separately initialized FitNesse instance from /opt/fitnesse/fitnesse.jar, version v20251025, without manually.start.test.runner=true and without an external Java server. Each XML execution log contains the launched command java -cp /opt/fitnesse/fitnesse.jar fitnesse.slim.SlimService 1. Plugin registration and comparator loading are also present in those logs. The JAR's bundled page contents match the workspace's target pages. The pinned Java PageDriver, ResponseRequester, and PageCreator sources were inspected from tag 20251025.

In the Java path, ResponseRequester.execute builds a MockRequest, resolves its wiki page through FitnesseFixtureContext.context, and executes FitNesseExpediter with that same context. PageCreator also creates pages using that context's root page. This keeps the nested request inside the active FitNesse context established for the outer test, including the test-system configuration and suite scenario context.

The Perl PageDriver instead issues independent HTTP saveData, saveProperties, and GET requests to the main server. The HTTP server creates a normal request context from its global configuration. It does not receive the active FitnesseFixtureContext from the outer test. As a result, the nested request does not inherit the CustomComparators=glob:... registry, the plugin-registered my use case alias and parsed-symbol decorator, or the scenario context that makes the ignored scenario rows render as the upstream page asserts.

Pinned Java v20251025 source trace

The source paths below are from the v20251025 tag:

These registration and lookup operations happen in FitNesse's Java test system. They are not SLiM instructions or Perl fixture APIs. A Perl-side alias would not install the parsed-symbol decorator, and a Perl-side comparator would not affect FitNesse's assertion comparison. Making these two tests pass while retaining the upstream PageDriver contract therefore requires a generic bridge that executes nested requests in the active Java FitnesseFixtureContext (or an equivalent FitNesse test-system extension). Copying these registrations into global server configuration or recognizing these page names would change their scope and would not reproduce the upstream behavior.

Current independent verification

The two target pages were rerun in fresh isolated FitNesse v20251025 instances using the Perl pipe child and the external Perl TCP listener. Both transports reproduced CustomTableRenderingAddedByPluginTest 5/1/0/0 and TestCustomComparators 1/2/0/0. The Perl test-system command or listener trace positively identified the backend; neither page raised a Perl exception or caused a server crash.

For the Java reference, an isolated FitNesse v20251025 server with the unchanged bundled wiki launched java -cp /opt/fitnesse/fitnesse.jar fitnesse.slim.SlimService 1 with exit code 0. It returned 6/0/0/0 for CustomTableRenderingAddedByPluginTest and 3/0/0/0 for TestCustomComparators. The Java and Perl results differ because the Perl PageDriver uses a separate HTTP request context, not because the Perl server returned different fixture values.

The full regression matrix also matched its reviewed per-page baselines: isolated pipe 50/50, 373/6/2/1; isolated TCP 50/50, 373/7/2/0; native pipe 93/93, 543/41/5/315; native TCP 93/93, 538/46/5/315. No baseline or acceptance page was changed. These two pages remain harness-limited; no genuine Perl SLiM defect was found in this investigation.

Responsibility and decision

All three failures share the harness boundary: nested-page behavior is being tested, but the Perl adapter cannot express Java PageDriver's same-process request-context semantics. The responsible components are FitNesse request/test-system context and the Perl test fixture adapter. The SLiM engine performs the requested fixture operations and returns the expected values/stop response; comparator lookup, plugin table decoration, and nested response interpretation are on the FitNesse side.

The prior baseline note that called the ignored-row assertions obsolete was incorrect. FitNesse v20251025 can emit the expected class="ignore" scenario-cell shape, as demonstrated by the Java reference run. The alternate slimRowColor3/slimRowColor5 plus ignore-span markup is the actual page/table shape produced by the Perl nested request in its different context; it is not the only markup the v20251025 renderer emits.

No implementation change is justified in the SLiM protocol engine, ResponseExaminer, or individual fixture methods. No page-specific workaround, global comparator/plugin registration, or fabricated HTML should be added. A correct fix requires a FitNesse-side context-aware nested-request bridge (or an equivalent FitNesse test-system extension) that lets the Perl PageDriver create and execute a nested page using the active request's FitnesseFixtureContext. It must preserve request-local plugin/comparator registration and scenario resolution rather than copying a guessed subset of settings. That crosses the current HTTP fixture-adapter boundary and is a substantial harness change, so it is documented as the smallest viable next step and is not implemented here.

Acceptance baseline

The committed individual results remain TestCustomComparators 1/2/0/0, CustomTableRenderingAddedByPluginTest 5/1/0/0, and IgnoredTestsShouldColorGray 5/2/0/0. The native suite remains at 93 pages and its existing result counts. No baseline count or conformance classification was changed. These pages remain harness-limited until nested execution can retain the active FitNesse context.