v8: establish the standalone @wdio/browserstack-service v8 maintenance line - #42
Open
AakashHotchandani wants to merge 125 commits into
Open
AakashHotchandani wants to merge 125 commits into
AakashHotchandani wants to merge 125 commits into
Conversation
…ide the gRPC core Adds the WebdriverIO service (@wdio/browserstack-service) as packages/browserstack-service and moves the existing gRPC/protobuf core (@browserstack/wdio-browserstack-service) into packages/core (git history preserved), so both ship from this repo. - npm workspace: root build builds core then service; tests scoped to the service. - service: esbuild bundle (deps external) + tsc declarations; strict files allowlist (build + README + LICENSE + ambient d.ts); peerDeps for webdriverio/@wdio/* so the consumer keeps a single shared copy. - release: Changesets + npm OIDC trusted publishing via .github/workflows/release.yml (main -> latest, v8 -> v8 dist-tag); the gRPC core is ignored by Changesets and stays on the SDK team's manual publish flow. - fix(tests): the @wdio/reporter mock no longer imports the real module from within its own mock (a top-level vi.importActual + static import deadlocked vitest and hung reporter.test.ts); stub the stats classes instead. Full suite: 39 files / 980 tests pass and the run exits cleanly. - repo metadata -> browserstack/wdio-browserstack-service; an added changeset bumps the first release to 9.29.0 (current npm latest is 9.28.0). Verified locally: npm ci + build + test green; clean 80-file / ~590kB tarball; a real BrowserStack session passed with webdriverio deduped to one copy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The committed lockfile was stale (carried entries from the pre-conversion layout), so CI's `npm ci` failed the sync check (EUSAGE: lockfile's @types/node@12.20.55 vs @types/node@25.9.3, missing undici-types). Regenerated against the current npm-workspace package.json set (760 -> 592 packages). `npm ci --dry-run` now passes; toolchain (typescript, vitest, esbuild, ts-proto, @bufbuild/buf + 7 platform optionalDeps) and workspace links (core <-> service) preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The previous lockfile commit was produced by `npm install --package-lock-only` against a stale node_modules, so npm shortcut it ('up to date, audited ... in 2s') and only pruned the old tree instead of fully resolving. CI's `npm ci` then rebuilt the ideal tree from package.json and found mismatches (Invalid @types/node@12.20.55 vs 25.9.3, Missing esbuild@0.28.1, etc.).
Regenerated with both package-lock.json and node_modules absent so the resolution is computed purely from package.json (598 packages). Verified locally with npm@10.9.8 (CI's npm): `npm ci` installs cleanly, `npm run build` (core buf+tsc / service esbuild+tsc) succeeds, and `npm test` passes 980/980.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-install) The service declares non-optional peerDependencies (@wdio/cli, @wdio/logger, @wdio/reporter, @wdio/types, webdriverio). npm 7+ auto-installs peers by default, so CI's `npm ci` requires their full closure in the lock (@wdio/cli@9.28.0 -> create-wdio, tsx, inquirer, ejs, execa, esbuild@0.28.1, @vitest/snapshot@2.1.9, ...). Prior lock commits were generated with a local ~/.npmrc legacy-peer-deps=true (left over from unrelated work), which suppressed peer auto-install and produced a lock missing that closure -> CI EUSAGE 'Missing @wdio/cli@9.28.0 from lock file' etc. Regenerated with --no-legacy-peer-deps to match CI's default (598 -> 720 packages). Verified CI-exact: `npm ci --no-legacy-peer-deps` installs cleanly, build succeeds, 980/980 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ake timers CI's Node 18.20 job (supported per engines: node >=18.20.0; wdio v9 supports 18.20) surfaced three Node-18-only failures that Node 20/22 tolerate: 1. PerformanceTester.start/end/measure called performance.mark/measure directly. Under vitest's full fake timers (7 test files) performance.now() goes negative, and Node 18's perf_hooks rejects negative timestamps (ERR_PERFORMANCE_INVALID_TIMESTAMP), throwing out of callers' before() hooks. Routed all mark/measure through safeMark/safeMeasure wrappers — instrumentation must never throw into business logic (no-op on the happy path; transparent on Node 20+). 2. uploadLogs used fs.openAsBlob (Node >=20 only). Added a Node-18 fallback to new Blob([readFileSync]) for the small log archive. 3. util.test.ts faked via bare useFakeTimers(); scoped to toFake:['Date'] (it never advances timers), matching reporter.test.ts. Verified locally on Node 18.20.5 AND Node 22: npm ci + build + 980/980 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nternal docs Addresses automated PR review findings on #37: - [SECURITY] release.yml: pin changesets/action, actions/checkout, actions/setup-node to full commit SHAs (with version comments) since this workflow holds id-token:write + publish. ci.yml left on tags (contents:read only). - [DOCS] packages/core/package.json: description now describes the gRPC/protobuf core (not the service); dropped the 'webdriverio' keyword — corrects the public npm listing. - [SECURITY] removed the five docs/ strategy/migration files from the public repo (kept internally). Their only cross-references were among themselves. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tadata These two review fixes were edited but accidentally left unstaged when f935a52 (docs removal) was committed, so they never landed. Committing them now: - release.yml: pin changesets/action, actions/checkout, actions/setup-node to full commit SHAs (with version comments). - packages/core/package.json: description now describes the gRPC/protobuf core; dropped the 'webdriverio' keyword. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
setup-node's `registry-url` writes `//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}` into .npmrc; with no NODE_AUTH_TOKEN that empty token line can shadow npm OIDC Trusted Publishing at publish time. npm defaults to registry.npmjs.org and publishConfig.access=public already covers the scoped publish, so the line is unnecessary. Splitting the changesets publish into its own top-level step is noted as a further OIDC-hardening follow-up.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- v8 service (8.48.0) swapped into packages/browserstack-service; metadata repointed to browserstack/wdio-browserstack-service; core dep ^2.0.2; files += README/LICENSE-MIT. - ported safeMark/safeMeasure (Node-18 perf_hooks) into performance-tester. - changeset baseBranch=v8. - regenerated package-lock.json with DEFAULT npm (no --legacy-peer-deps): npm ci is in sync, so v8 does NOT need the flag (resolves reviewer concern). - build green (core buf+tsc; service tsc); per-file tests pass. KNOWN-OUTSTANDING: full-suite 'vitest --run' hangs in teardown (open PerformanceObserver handles + vitest 1.x not force-exiting). Toolchain decision pending (vitest 1.x->3). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per-file tests all pass and exit cleanly; whole-suite vitest --run still hangs in teardown under vitest 1.x (open handle survives pool/teardown cleanup). Standalone teardown remains the outstanding follow-up. setupFiles wires the per-file cleanup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…flake, per-file runner Root causes of the standalone 'teardown hang' (upstream only runs these inside the full monorepo suite, never standalone): - __mocks__/@wdio/reporter.ts imported the stats classes from '@wdio/reporter' — the module it mocks — deadlocking mock resolution at collection (file hung, no output). Stats are type-only in the service, so replaced with stub classes. THIS was what wedged the whole-suite run. - util.test.ts logPatcher spied process.emit at describe scope without resetting it, so a stray emit made the count flaky (7 vs 6). Clear the spy in the test. - reporter.test.ts: scope fake timers to ['Date'] (mirrors v9). - vitest.setup.ts: restore real timers + disconnect the PerformanceTester observer per file (dynamic import to avoid a circular-decorator init failure). - test script now runs each file in its own process (scripts/test-isolated.mjs), judging by test result not clean exit, so any residual post-test open-handle lingering can't wedge CI. Result: 41/41 files pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generate the gRPC/protobuf client inside @wdio/browserstack-service at build time (buf generate -> src/grpc/generated) instead of depending on the separately-published @browserstack/wdio-browserstack-service core. - move buf.yaml / buf.gen.yaml + src/proto/** + the barrel (-> src/grpc/index.ts) from packages/core into packages/browserstack-service - rewire all imports from '@browserstack/wdio-browserstack-service' to the local './grpc/index.js' barrel - deps: drop the core, add @grpc/grpc-js + @bufbuild/protobuf; devDeps: add @bufbuild/buf + ts-proto - build/clean/prepack run `buf generate` before tsc; src/proto ships in the tarball, src/grpc/generated stays gitignored - delete packages/core; collapse root build script; changeset ignore: [] The published @browserstack/wdio-browserstack-service@2.0.x stays on npm as-is (historical); nothing publishes a separate core going forward. Verified on Node 22 + npm 10: build green (buf generate -> tsc), 41/41 test files pass, npm pack ships build/grpc + src/proto and no core dep. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Parity with the v9 fix (7c949da). CI runs plain `npm ci` (legacy-peer-deps=false default), which requires the auto-installed `@wdio/cli` peerDependency closure to be present in the lockfile. The prior lockfile was generated with legacy-peer-deps=true and omitted that closure, so npm ci failed "out of sync". Regenerating with the peer tree exposed the same @types/node hoist non-determinism as v9 (protobufjs/ts-proto pulls @types/node@25, @manypkg/find-root pins ^12.7.1, and the v8 stack wants ^22), fixed with: - overrides @types/node ^22.2.0 — collapses the 3-way spread to a single 22.x (matches the service's declared ^22.2.0; types-only, no runtime impact), so npm install and npm ci agree. Unlike v9, NO estree-walker workaround is needed: v8 uses vitest ^1.6.0, which predates @vitest/mocker, so the deeply-nested-transitive drop that affected v9 doesn't occur here. Verified: `npm ci --legacy-peer-deps=false` passes, build passes, 0 runtime holes, full @wdio/cli peer tree present, cross-platform complete, per-file tests green (service.test.ts 97/97). The aggregate `npm test` (test-isolated.mjs) still hits the pre-existing all-at-once teardown follow-up, unrelated to the lockfile. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ow (upstream #15330) Ports webdriverio/webdriverio#15330 (merged into monorepo v8 after the 2026-06-16 extract): in the CLI/binary v8 flow, forward screenshot-on-failure to the binary over gRPC as a TEST_SCREENSHOT log (uploaded via the binary's authorized testhub session) instead of the direct-HTTP onScreenshot path (which 401s under the worker's binary-issued JWT); register the command/result listeners in CLI mode so the screenshot command result is captured; and honor the incoming log kind in the mocha CLI framework. Keeps the standalone v8 line at parity with the monorepo. Src-only change (matches upstream — no test changes); builds clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…elease.yml - Move @wdio/logger|reporter|types from peerDependencies to dependencies (pinned 8.x), mirroring the v9 line so the published package carries them. - Switch release.yml to the manual/hybrid model (parity with the v9 branch): push opens the "Version Packages" PR only; publishing is a manual workflow_dispatch (publish=true) → v8 dist-tag via publishConfig.tag, over OIDC. The existing take-over-publishing changeset (minor) computes the first standalone v8 release as 8.49.0 (> npm v8 8.48.3). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| const sessionId = browser.sessionId | ||
|
|
||
| // a utility function to escape single and double quotes | ||
| const escapeString = (str: string) => str.replace(/'/g, "\\'").replace(/"/g, '\\"') |
| const sessionId = browser.sessionId | ||
|
|
||
| // a utility function to escape single and double quotes | ||
| const escapeString = (str: string) => str.replace(/'/g, "\\'").replace(/"/g, '\\"') |
| // a utility function to check if the hostname is browserstack | ||
|
|
||
| const isBrowserstack = (str: string ): boolean => { | ||
| return str.includes('browserstack.com') |
…lour) + SHA-pin ci.yml actions - test-isolated.mjs: under CI=true vitest forces ANSI colour even when piped, so the summary regexes (`Tests \d+ passed`) failed to match (colour codes between "Tests" and the count) and every passing file was mis-flagged "no test summary" → CI red. Strip ANSI in classify() and set NO_COLOR/FORCE_COLOR=0 on the spawned vitest. Verified: `CI=true npm test` → 41/41 files pass. - ci.yml: pin actions/checkout + actions/setup-node to full commit SHAs (resolves the semgrep github-actions-mutable-action-tag findings, parity with the v9 line). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| function classify(output) { | ||
| // CI (CI=true) makes vitest force ANSI colour even when piped, which would break the | ||
| // summary regexes below (colour codes sit between "Tests" and the count). Strip them first. | ||
| const clean = output.replace(new RegExp(String.fromCharCode(27) + '\[[0-9;]*m', 'g'), '') |
…ith/slice + drop vestigial nested workflows
- getHierarchy (insights-handler.ts + util.ts): replace `new RegExp(' ' + test.description + '$')`
with an endsWith/slice suffix strip — avoids ReDoS and regex-metacharacter mismatches when the
Jasmine description contains regex specials. Behaviour-preserving; mirrors the v9 fix (65d7c33).
- Remove packages/browserstack-service/.github/workflows/{ci,release}.yml — vestigial duplicates
from the extraction (GitHub only runs root-level workflows; these never executed) that carried
unpinned action tags. Root workflows are already SHA-pinned.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… peer (v8) Same parity fix as v9: the extraction moved webdriverio from dependencies into peerDependencies. The v8 package published from the WebdriverIO monorepo (@wdio/browserstack-service@8.48.3) keeps webdriverio in dependencies (8.46.0) and peers only @wdio/cli. Move it back to dependencies to restore install parity and avoid npm ERESOLVE against deps peering a non-overlapping webdriverio range. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(v8): declare webdriverio as a dependency, not a peer (install parity)
Port of webdriverio/webdriverio#15374 (v8 backport of #15373) to the standalone repo. With skipAppOverride: true the service classifies the session as App Automate even when no app option is set, skips the app upload, and does not inject an appium:app capability — the user supplies the app reference themselves. Conflicting app option is warned about and ignored; skipAppOverride: false with no app fails fast before any session starts. The option is stripped from bstack:options and never forwarded to the hub. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…exit-signal/log-redaction Ports 4 upstream webdriverio/webdriverio v8 commits to the standalone v8 line: - #15231 test management (testPlanId) support + CLI-only caps stripping + build-start errors - #15217 raise gRPC send/receive message size limit to 20 MB - #15146 terminate CLI process with SIGINT (not SIGKILL) on Unix - #15200 redact credentials from CLI log output Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…LI flow v8 port of the v9 fix, plus the hook-routing backport v8 never received: - beforeHook/afterHook CLI branches: route hook lifecycle to the binary via the TestFramework tracker (gRPC). Without this the v8 CLI flow emits no HookRunStarted/HookRunFinished at all (the legacy Listener -> api/v1/batch path is not functional in the CLI pipeline). - cli/skipReporter (new): reports tests that never reach beforeTest/afterTest (static it.skip, this.skip() in before/beforeEach hooks, suites aborted by a failed before hook) through the tracker using the same INIT_TEST -> TEST PRE -> LOG_REPORT POST -> TEST POST sequence afterTest uses, serialized (wdio does not await reporter hooks) and deduped against started tests. - reporter.onTestSkip CLI branch + service.afterHook skip cascade (port of the legacy insights-handler skip propagation). - Hook results: reading `testResult.status` (nonexistent on TestResult) left hook_result at 'pending', coerced downstream to 'passed' — failed before-hooks produced green builds while CI exited 1. Map from the actual passed/skipped fields. Without these, such tests are invisible on the dashboard and their Automate sessions are never linked to the build. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The regression test assigned to the module-scope accessibilityScripts singleton and reset it as the last statement of the test body, so any earlier throw — a failed expect, or onBeforeExecute rejecting — left a populated commandsToWrap behind for every later test in the file, turning one real failure into a cascade. afterEach only calls vi.resetAllMocks(), which does not restore a plain property written onto the mocked module. Capture the original and restore it in a finally block, rather than resetting to a hardcoded [] that would be wrong if the shared mock ever gains a non-empty default. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
DEF-12: the guard added to AccessibilityHandler.before() changed behaviour in a file the
repo tests densely (accessibility-handler.test.ts, 26 cases) with no test of its own.
Drives the real payload shape — an HttpCommandExecutor-class startA11yScanning between two
Element commands — and asserts all three wraps are attempted and the trailing command still
wraps. Verified to fail without the guard ("expected spy to be called 3 times, but got 2")
and pass with it.
The existing suite never reached this loop: the shared browser mock has no
overwriteCommand, so `'overwriteCommand' in browser` was false in every other case.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e rows Two parity defects found in PR review. preferScenarioName never renamed the session on the CLI flow. onAfterTest read the scenario name from `test.title`, which _cucumberTestView leaves undefined on purpose — legacy calls _setSessionName(feature.name) with no test argument, so sessionNameFormat has to receive undefined as its fourth argument. Populating `title` would have changed what every sessionNameFormat callback is handed, so the name is read off the live `world` instead; this observer runs in-process, so the object has not been through the binary's JSON round-trip. Automate results keyed on `test.fullName`, the raw pickle name, which every Examples row of an outline shares when the outline title carries no placeholder. Those rows collapsed last-write-wins, so a failing row followed by a passing one reported the session passed. Cucumber now keys on the scenario's own uuid; mocha's key is unchanged. The existing preferScenarioName test passed a fabricated `test.title`, bypassing _cucumberTestView, so it stayed green while the integrated path was dead. It now uses the real view shape and reads the name from `world`, and the blanket getState mock is keyed so it stops answering every state identically. Adds an outline-collision regression test. Both tests fail against the unfixed module. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
SDK-4177. browserCommand resolves the active test through insightsHandler's `_tests` map and returns before the SDK-6277 screenshot branch when it finds no entry. Legacy seeded that map from insights-handler's beforeScenario, which the CLI branch skips, and TestReporter's map is keyed on `testStats.fullTitle` / `getHookIdentifier` — neither matches `getUniqueIdentifierForCucumber(world)`. So screenshots were dropped for cucumber on the binary flow where legacy forwarded them. beforeScenario now reads the scenario uuid after the TEST/PRE event — the uuid is minted by loadScenarioData during that event, so reading earlier would seed the previous scenario's — and hands it to setTestData. The lookup is guarded: getState dereferences the instance, so an absent tracked instance would have thrown out of the customer's hook rather than just losing the attribution. setTestData accepts a world and lets it through to seed `_tests`. The key moves to getIdentifier(), which for every non-pickle test returns getUniqueIdentifier(test, framework) — the previous key unchanged, so mocha and jasmine keep their behaviour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…, not only when it passes (v8) Rolls the mandatory-to-run gate (SDK-7256) onto the v8 line. main already has this via #202; v8-based PRs (e.g. #212) were still running the old mandatory-to-pass gate on pull_request events, so a failing-but-run verdict kept the gate red. CI/workflow only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On the CLI flow service.before() merges the capabilities the binary hands back, and those carry the SDK's own options. NOT_ALLOWED_KEYS_IN_CAPS is the only strip between that merge and the hub, and it did not list preferScenarioName, so the hub rejected the session outright — `additional properties ["preferScenarioName"] outside of the schema` — and the run exited 1 with no session where the legacy flow, which never calls the binary, exited 0. The leak is framework-agnostic, so this changes mocha and jasmine too: an option that is a no-op for them stops crashing the run. preferScenarioName is cucumber-only — _scenariosThatRan is pushed only in afterScenario, so the `length === 1` gate can never fire for mocha. Unblocks the three cucumber session-naming parity rows, which could not be measured while no session was ever created. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ry-run-v8 ci(sdk-pr-review-gate): green when the agent RAN on the latest commit, not only when it passes (v8)
…e (SDK-7358) Two changes to the end-of-build summary rendering added in this PR. Colour: a warn entry (an outdated SDK) is tinted yellow and an error entry (a deprecated one) red, with the block's first line of text emphasised. Lines are wrapped and reset individually rather than the block as a whole, so a truncated or interleaved write cannot leave the customer's terminal stuck in colour. Applied to the stream copy only — the archived copy stays plain, because escape codes reach a log file as literal bytes and break anchored searches over it. Archiving: switch from the info/warn/error helpers to logToFile. Those helpers also call @wdio/logger, which writes to the console, so the customer saw the block twice — once raw from the stream write, once prefixed by the logger. logToFile writes to the log file only. Unlike v9, this branch's logToFile does not redact, but neither did the helpers it replaces, so redaction behaviour is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The earlier strip covered preferScenarioName only. sessionNamePrependTopLevelSuiteTitle
reaches the outgoing capabilities by the same route and the hub rejects it the same way
("additional properties [...] outside of the schema"), which is what kept the cucumber
session-name parity row unmeasurable. sessionNameOmitTestTitle is listed alongside it:
same family, same route into caps, not a W3C capability.
Both are read from testContextOptions, so stripping them from the outgoing capabilities
does not disable either option.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The binary re-bases test_file_path and location itself but never touches the bdd_meta blob, so the absolute path we put there reached the dashboard verbatim, home directory included — where the legacy flow published a repo-relative path read off the cucumber world's gherkinDocument.uri. Adds featureUriForMeta(), used only for the meta blob; the file-path pair stays absolute because the binary owns re-basing those. The existing test asserted the meta path equalled the absolute feature uri, which encoded the defect; it now asserts cwd-relative and pins the file path as still absolute. Verified at unit level and by source inspection. The O11Y read-back that produced the original evidence for this defect was not reproduced — the testRuns endpoint returned no rows for the fix run — so dashboard confirmation is still outstanding. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…lob too The BEFORE_ALL cascade builds its own bdd_meta blob inline rather than going through buildBddMetaInfo, so the previous fix missed it and cascade rows kept sending the absolute feature path into a blob the binary never re-bases. Per-field contract, now consistent at all five emit sites: test_file_path and location go out absolute because the binary re-bases them; every bdd_meta feature.path goes out cwd-relative because the binary leaves that blob alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…tags-v8' into release_v8_24_sep
Release v8 24 sep
Review follow-up on SDK-7358. renderCustomerVisibleSummary wrapped the whole `for (const entry of entries)` loop in one try/catch, so a stream that rejected entry N aborted the loop: entries N+1.. were neither written nor archived. The PR's own "still returns the response when rendering throws" test shows a throwing write is a considered scenario. Only one entry exists today (the version nudge), but the proto is explicitly built for more entry types, so the gap widens as they are added. Moves the catch inside the loop body, and writes the archived copy before the stream write so archival no longer depends on the write succeeding. The outer catch stays — stopBinSession rethrows, so a throw escaping this method would cost the caller its response. Covered by a new test that fails without the fix (only the throwing entry reaches stderr; the two after it are dropped). Package suite on Node 25: 46 files, 1056 tests, 0 failures. tsc --noEmit exit 0. (No lint script exists on this branch.) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Version Packages
Ports the v9 Percy fixes (#210, #228) to the v8 line: - Route web `snapshot` to @percy/webdriverio instead of @percy/selenium-webdriver (whose Selenium-only APIs a WebdriverIO browser does not provide), and add @percy/webdriverio ^3.3.4 (3.3.3 shipped without _iframe_shim.js and failed to load; fixed in 3.3.4). - Bump @percy/selenium-webdriver to ^2.2.8 so the Automate percyScreenshot path stops resolving to the broken 2.2.6/2.2.7, which added an unguarded top-level require('selenium-webdriver') and silently disabled Percy on WebdriverIO. - Wrap all Percy entry points so their errors are logged rather than thrown into the user's test; PERCY_RAISE_ERROR=true restores throwing. - Document the percy / percyCaptureMode options in the README. SDK-7756 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s-v8 feat(browserstack-service): render end-of-build summary entries (SDK-7358) [v8]
Version Packages
…formisation-v8
Sdk v8 pre prod
Version Packages
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.
Parallels the v9 conversion (#37) for the v8 line. The
v8branch is the long-lived v8 maintenance line, published to the npmv8dist-tag viapublishConfig.tag.Contents
@wdio/logger|reporter|typespeer→dep; manual/hybridrelease.yml(parity with v9);take-over-publishing(minor) + screenshot changesets → first standalone v8 release computes8.49.0(> npmv88.48.3).Release
Manual/OIDC: push opens the "Version Packages" PR; Run workflow → publish does
changeset publish --tag v8with provenance. Gate the first v8 publish behind the v9 first-publish + freeze.Regression
SDKWdioRegressionSharded:RUN_V8=true,WDIO_V8_BRANCH_NAME=v8,INSTALL_MODE=build-package.🤖 Generated with Claude Code