Skip to content

Conformance suite: run the Nightwatch adapter, and the bug it found - #432

Merged
vishnuv688 merged 6 commits into
mainfrom
feat/300-nightwatch-scenario
Oct 19, 2026
Merged

vishnuv688 merged 6 commits into
mainfrom
feat/300-nightwatch-scenario

Conversation

@vishnuv688

Copy link
Copy Markdown
Member

Refs #300. Stacked on #428; merge that first, then this one shows only its own three commits.

Adds the Nightwatch adapter to the conformance suite, which brings it to three of the four adapters. The first run was red for the three reasons a new adapter is expected to be: one real adapter bug, three places where the suite had assumed every adapter looked like Selenium, and two documented differences to declare. All of it is resolved here, and the suite is green with every difference either fixed or declared.

The bug it found

A navigation the browser refused produced a Nightwatch row with result: null and no error: no red row, nothing in the Errors tab. Nightwatch reports such a failure as {status: -1, value: null, error} with the Error itself under error, and callbackError descended into the W3C value wrapper first, found null, and returned nothing. The wrapper is now read before descending. Six unit tests pin the shapes, built on the exact object the plugin's callback receives, and a changeset is included.

Suite assumptions it corrected

Assumption What Nightwatch does Change
A fill's text is the first string argument setValue(selector, text) leads with the selector The first string argument that is not the row's own selector
Run controls are served by a shell command Reruns go through the backend's framework path with a registered config file run-controls-are-served: a command or a configFile serves them
One driver request per user action Its transport re-issues a refused navigation (measured 3 attempts, 1 s apart, with the plugin's own reads in between) The fake counts a retry run as the one action the user issued; the run ends only with the next user action

Declared differences

Both carry their reason in the allowlist and show as allowlisted in the report:

  • No Run-all. The backend reruns a Nightwatch config's suites and tests through its framework path; there is no whole-run entry. Already on the capability matrix.
  • No-BiDi <script> fallback misses a page the test leaves within tens of milliseconds, the same race Selenium's fallback has.

Declaring them exposed two faults in how gaps were judged, fixed here: a gap listing only adapters-agree-* rules was never "occurring" and always "stale", so per-run rules are now judged by the run and comparison rules by the comparison (which reports its own stale gaps); and two adapters declaring the same gap on the same step no longer reject each other.

How Nightwatch runs

Through its own CLI, against a config and spec under scenarios/nightwatch/, with webdriver.start_process: false pointed at the fake WebDriver and the recording backend reached through the reuse handshake the plugin already honours. nightwatch and @wdio/nightwatch-devtools become dev dependencies of the conformance package so the config can resolve them.

Observed, not acted on

The plugin re-sends its session metadata 11 times for one session, and warns Cannot read properties of undefined (reading 'replace') when the session has no BiDi socket. Both harmless; worth a follow-up issue.

Verification

pnpm build, pnpm test (2580 tests, 55 in the conformance package), pnpm lint, pnpm typecheck and a frozen-lockfile install with CI's pnpm version: all green. The adapter fix was confirmed end to end: before it, the suite failed failed-command-has-error-row for Nightwatch; after it, the row carries net::ERR_FAILED at /broken, the browser's own text.

@greptile-apps

greptile-apps Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; all three previous findings are fixed, and no new blocking issue was found.

Summary

Adds Nightwatch to the conformance suite and fixes missing errors on failed Nightwatch commands.

  • The conformance suite now runs Nightwatch alongside its Selenium adapters.
  • Failed Nightwatch commands now show the browser’s error on their action row.
  • The suite reads Nightwatch fills and run controls using their actual shapes.
  • Known adapter gaps now match the reports and comparisons that judge them.

Reviews (3) · Last reviewed commit: "fix(conformance): show a comparison's st..." · Reviewed by Greptile

Comment thread packages/conformance/src/agreement.ts Outdated
Comment thread packages/conformance/src/normalize.ts Outdated
Comment thread packages/conformance/src/agreement.ts
Nightwatch reports a navigation the browser refused as {status: -1,
value: null, error} with the Error itself under `error`. callbackError
descended into the W3C `value` wrapper first, found null, and returned
nothing, so the row rendered as a success with no result: no red row,
nothing in the Errors tab. The wrapper is now read before descending.
Found by the conformance suite's first Nightwatch run.
Three assumptions the first Nightwatch run exposed. A fill's text is the
first string argument that is not the row's own selector, since
Nightwatch's setValue leads with the selector. Run controls are served by
a shell command or by a config file the backend reruns through its
framework path, so the rule is now run-controls-are-served. And the fake
counts a client's own retries of a refused navigation as the one action
the user issued: Nightwatch's transport re-issues a failed protocol
action, with the adapter's reads in between, so a retry run ends only
with the next user action.
A config and a spec under scenarios/nightwatch, run through Nightwatch's
own CLI against the fake WebDriver with start_process false, reaching
the recording backend through the reuse handshake the plugin already
honours. Nightwatch's two documented differences are declared: no
Run-all, and the no-BiDi <script> fallback missing a short-lived page.

Declaring them exposed two faults in how gaps are judged, fixed here. A
gap listing only adapters-agree-* rules was never occurring, since no
run shows those, and always stale, since judge() looked for them in the
run: per-run rules are now judged by the run and comparison rules by the
comparison, which reports its own stale gaps. And two adapters declaring
the same gap on the same step or document no longer reject each other: a
difference the other side's own gap declares is not a hidden bug.

Refs #300
@vishnuv688
vishnuv688 force-pushed the feat/300-conformance-suite branch from bb7cd4a to 9485829 Compare October 19, 2026 11:42
@vishnuv688
vishnuv688 force-pushed the feat/300-nightwatch-scenario branch from d9ed6a6 to 0e21d24 Compare October 19, 2026 11:42
vishnuv688 and others added 3 commits October 19, 2026 17:17
The text was taken as whichever argument differed from the row's
selector, so a Nightwatch setValue that typed its own selector lost
both arguments and normalized to no input, while the Python payload
kept the same text and the two compared as different. Every binding
passes the text last, so read it by position instead of by value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nightwatch's run-controls gap explained any run-controls difference
once Nightwatch held it, so losing canRunTests or canRunSuites would
still be reported as allowlisted. A gap on that rule now names the
controls it accounts for in lacksRunControls, and the comparison
removes only those before comparing, so any other control lost is
reported as unexplained.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
judgeDivergences reports a gap the comparison no longer needs as
stale, and that fails the test, but the agreement section rendered
only the unexplained and allowlisted differences. A mode whose only
problem was a stale gap therefore read AGREE while the run failed.
The section now lists those gaps and gives the mode a failing verdict,
reusing the per-run stale renderer, which now names the adapter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vishnuv688
vishnuv688 changed the base branch from feat/300-conformance-suite to main October 19, 2026 12:28
@vishnuv688
vishnuv688 merged commit 043055a into main Oct 19, 2026
7 checks passed
@vishnuv688
vishnuv688 deleted the feat/300-nightwatch-scenario branch October 19, 2026 13:12
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.

1 participant