Repository navigation
Fixes
-
Desktop browser sessions no longer fail to start (#4).
tb_openBrowsersent the legacy JSON-Wireplatformcapability alongside the W3CplatformName. Thewebdriverclient rejects any top-level capability that is neither standard W3C nor colon-namespaced as soon as an extension capability (tb:options) is present, so every desktop session failed client-side withInvalid or unsupported WebDriver capabilities found ("platform")before a request ever reached the hub. Mobile sessions were unaffected, since that path emits only valid andappium:-namespaced keys. -
screenResolutionis now actually applied (#4). TestingBot reads the kebab-casescreen-resolutionkey insidetb:options; the camelCase spelling was dropped silently and desktop VMs stayed at the 1280x1024 default. -
Credentials no longer reach the
appium-mcpchild (#5). The env filter strippedTESTINGBOT_KEY/TESTINGBOT_SECRET/TB_KEY/TB_SECRET, butgetConfig()also acceptsTESTINGBOT_USERNAMEandTESTINGBOT_ACCESS_KEY. Anyone configured via those names passed them straight into the child process, contradicting the design that the child receives credentials only baked into the injected hub URL. -
tb_listSessionsno longer advertises a tool that doesn't exist (#5). Its description pointed attb_appiumEndpoint, which has never been registered. It now points atappium_session_management(action: 'list'), which is what actually owns mobile sessions. -
SessionManageris reusable aftercloseAll()(#5). The shutdown flag latched on permanently, so every laterregister()threwSessionManager is shutting down— a library host that tore the tool family down and brought it back up in the same process got a silently dead manager. The flag is now held only for the duration of the sweep, andregister()restarts the idle reaper thatcloseAll()stopped. -
Locator and key edge cases (#5): an id starting with a digit now gets CSS's hex escape rather than a backslash (
#2fa-code→#\32 fa-code);by: "class"with"btn primary"builds the compound selector.btn.primaryinstead of one class literally namedbtn primary; and"+"— both the chord separator and a real key — is now pressable, alone or as"Control++". -
Node version gate matches
engines.node(#5).preflight()enforced Node 18 while the package declares>=20.
Added
tb_navigateacceptswaitUntilandtimeoutMs(#5).navigateToreturns per the session'spageLoadStrategy, which on a page with slow third-party resources can leave the agent looking at a half-built DOM.tb_navigatenow confirmsdocument.readyStateitself:load(default,complete),domcontentloaded(interactiveor better — returns earlier on ad-heavy pages), ornoneto skip the check. A timeout warns rather than failing the call, since the navigation itself succeeded and the page is usually usable.
Security
- Tool arguments are logged wholesale by the CallTool handler, so
args.text(tb_type's payload — whatever gets typed into a login form),args.capabilitiesandargs.remoteServerUrlare now redacted, along with generic*.secret/*.token/*.accessKey. Only reachable underTESTINGBOT_DEBUG=trueor dev mode, as the default log level iserror.
Testing
Both fixes above shipped because every browse test mocked WebDriver.newSession, so the capabilities could never disagree with the client that has to accept them — and the integration suite that would have caught it had gone stale and never ran in CI.
tests/tools/browse-capabilities.contract.test.tsdrives the realwebdriverclient against a local stub hub, asserting the actual JSON body sent. Free and fast, so it runs in the normal unit pass.- The desktop integration suite now covers every browser and shared tool in a single session, and asserts the requested resolution reaches the VM.
- New mobile-browser and
appium-mcp-child integration suites. The latter opens no session and costs nothing. .github/workflows/integration.ymlruns these nightly and on demand, failing fast when credentials are absent rather than skipping into a green run that verified nothing, and sweeping leaked sessions afterwards.
Unit tests: 120 → 156.
Full changelog: v0.1.7...v0.1.8