Repository navigation
fix(nightwatch-devtools): read the performance log off the command queue - #472
Merged
Merged
Conversation
The no-BiDi network fallback read Chrome's performance log with browser.getLog, a queued Nightwatch command. That read runs inside captureTrace, which is reached from the fire-and-forget drain after a DOM-mutating command and from the navigation poll's timers, so it is issued while the test's next command is in flight. Nightwatch's queue adds a command issued then as a child of the running node, and finishing it resolves that command's await early: the same hazard that made setValue return before it finished typing when the performance timings were read with browser.execute. The log now goes over the raw WebDriver transport, POST /session/:id/se/log, the route selenium-webdriver (and so Nightwatch) sends for getLog. The perfLogsRequested gate stays: it still saves a round trip per command on a session that asked for no log. captureBrowserLogs had no caller anywhere in the repo, so it is deleted with the unwrapDriverValue helper only it and the old read used.
Contributor
[Medium impact] The PR appears safe to merge; the previous connection-settings issue is addressed. SummaryThe PR reads Chrome performance logs through the direct WebDriver transport instead of Nightwatch's command queue.
Reviews (2) · Last reviewed commit: "fix(nightwatch-devtools): use Nightwatch..." · Reviewed by Greptile |
…er calls Direct WebDriver calls built their address from host, port and path prefix only, so against an https or authenticated grid every one of them (drains, snapshot probes, screenshots, the performance log, the Appium executor) went out as plain http without credentials and failed. They now follow Nightwatch's own rules: https when webdriver.ssl is set or the port is 443, and basic auth from username and access_key.
4 of 13 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Follow-up to #467. That PR moved the post-navigation performance read off Nightwatch's command queue, because a queued command issued while the test's own command was running made that command's await resolve early (
setValuereturned before it finished typing; #457). The no-BiDi network fallback had the same problem in a second place:SessionCapturer.captureNetworkFromPerformanceLogsstill read Chrome's performance log withbrowser.getLog('performance'), which is also a queued command.It runs while a test command is in flight. The read happens at the end of
captureTrace, after the collector drain, andcaptureTraceis called from:browserProxy.tsdrainOutgoingPage, fire-and-forget (.catch(() => {})) from the command callback of every DOM-mutating command. By the time its HTTP drain has returned, the test has usually started its next command.session.tsanchorAfterNavigation, after apollUntilReadyloop of 150 ms timer ticks.injectAndCapture, chained off the navigation's thenable.Nightwatch makes a command issued then a child of the running one. In Nightwatch 3.16.0,
lib/core/queue.jsadd()creates the new node withparent: this.currentNode, so agetLogissued while the test'ssetValueis running becomes a child of thatsetValue.getLogitself (lib/api/client-commands/getLog.js) is a queuedClientCommandthat callssessionLog, so this is the same path #467 removed forbrowser.execute.Fix. The log is now read over the raw WebDriver transport (
helpers/webdriverHttp.tswebdriverPost) withPOST /session/:id/se/logand{ type: 'performance' }. That is the route selenium-webdriver mapsGET_LOGto (lib/http.js), and Nightwatch's transport calls selenium-webdriver'sdriver.manage().logs().get(type)(method-mappings.jsgetLogContents), so the driver receives the same request it did before. The core transport already unwrapsvalueand resolvesnullon a W3C error or a transport failure, so the localunwrapDriverValuehelper and the error-message filtering are no longer needed. TheperfLogsRequestedgate stays: over HTTP a refused log type resolvesnullquietly, but the gate still saves one round trip per command on a session that asked for no log, andnullis no more distinguishable from an empty log thangetLog'sundefinedwas.Dead code.
captureBrowserLogswas not called anywhere:git grep captureBrowserLogsacross the repo found only its definition and its own tests in nightwatch-devtools. (Selenium's method with the same name is a separate, live method.) The method, its tests,unwrapDriverValueand themapChromeBrowserLogsimport are deleted.CLAUDE.md's
perfLogsRequestedentry and the parser's doc comment are updated to describe the HTTP read.Type of change
Packages touched
shared(types and contracts)core(framework-agnostic capture/reporting)elements(published element/snapshot API —@wdio/elements)service(WebdriverIO adapter)nightwatch-devtools(Nightwatch adapter)selenium-devtools(Selenium adapter)selenium-devtools-py(Selenium Python adapter)backend(server)app(UI)script(page-injected runtime)trace(Trace mode)Capability matrix
packages/conformance/src/features.tsupdated, and tables regenerated withpnpm docs:capabilities, if this adds or changes user-facing behaviourNo capability changes.
pnpm docs:capabilities --checkpasses.Notes for reviewers
reads the log over the WebDriver transport, never the command queueinpackages/nightwatch-devtools/tests/session.test.ts. A local driver stub records each request, and the mock browser'sgetLogwould return the same entries. The test asserts that the stub received exactlyPOST /session/sess-perf/se/logwith body{"type":"performance"}, thatbrowser.getLogwas never called, and that the entry was parsed into a network row. Withsession.tsreverted to main, this test fails, and so do the threecaptureTracetests that now serve the log from the stub.invalid argumenterror body now resolves with no rows, which replaces the old thrown-error test.pnpm build,pnpm test(227 files, 3015 tests),pnpm lint(0 errors),pnpm typecheck,pnpm docs:capabilities --check, and the conformance suite (15/15) run twice. All passed.bidi: falseinexamples/nightwatch/nightwatch.conf.cjs(it already requestsgoog:loggingPrefs: { performance: 'ALL' }) and run:setValuefinishes typing before the submit click.Screenshots / recordings
N/A, no UI change.
🤖 Generated with Claude Code