Skip to content

chore: [DO NOT MERGE] CI run for rebased beta - #3111

Merged
mykola-mokhnach merged 39 commits into
masterfrom
sync/rebase-beta
Nov 1, 2026
Merged

mykola-mokhnach merged 39 commits into
masterfrom
sync/rebase-beta

Conversation

@mykola-mokhnach

Copy link
Copy Markdown
Contributor

CI-only draft: runs the checks on the rebased beta (see #3110). Do not merge; master is fast-forwarded with a push instead. Will be closed afterwards.

mykola-mokhnach and others added 30 commits October 31, 2026 20:30
Targets the recently released Appium 4 beta (4.0.0-beta.1). Bumps the
appium peer dependency and all lockstep @appium/* packages to their
Appium 4 beta releases, and updates driver code for the resulting API
removals/changes described in the Appium 3-to-4 migration guide
(appium/appium#22790).

- @appium/strongbox, @appium/types, @appium/docutils, @appium/oxc-config,
  @appium/semantic-release-config, @appium/tsconfig bumped to their
  Appium 4 lockstep beta releases (engine/ESM-only bumps, verified
  byte-identical source vs. master where diffable, not API changes)
- Removed the driverData mechanism and the legacy 4-argument
  createSession override (both removed upstream); createSession now
  takes the single w3cCapabilities argument
- Removed the already-deprecated reset API (driver.reset() /
  POST /session/:sessionId/appium/app/reset), which only ever threw a
  deprecation error
- Fixed a real regression in the W3C timeouts command: BaseDriver's
  generic timeouts() handler no longer dispatches through
  scriptTimeoutW3C/pageLoadTimeoutW3C/implicitWaitW3C - it now calls
  setScriptTimeout/setPageLoadTimeout/setImplicitWait directly for both
  the legacy and W3C timeout forms. Renamed setAsyncScriptTimeout to
  setScriptTimeout to match, dropped the now-unreachable W3C/MJSONWP
  wrapper methods, and made sure BaseDriver's own scriptTimeoutMs/
  pageLoadTimeoutMs stay in sync too, since GET /timeouts now reports
  them on Appium 4 (it never did on Appium 3)
- Replaced the Location type (removed from @appium/types along with the
  legacy geolocation endpoint) with a local LocationWithAltitude
  interface
- Narrowed fs.glob()'s now-widened overloaded return type at the
  handful of call sites that don't use its withFileTypes/lazy options
- Made getStrings's language parameter optional in its type signature,
  matching its actual (always-optional) runtime/wire behavior - caught
  by the new compile-time execute-method-map param checking
- Bridged two known upstream typing lags (appium-webdriveragent and
  appium-ios-simulator still resolve AppiumLogger from pre-Appium4
  @appium/types copies) with documented `as any` casts; confirmed
  neither package's compiled output actually calls the removed
  errorAndThrow, so this is a type-only gap, not a runtime one
- Dropped @colors/colors and the local isEmpty/escapeRegExp/
  isPlainObject/truncateString/memoize shims in lib/utils, now that the
  appium peerDependency bump makes their appium/support equivalents
  available (both were carrying "replace once this driver declares
  that minimum" TODOs)
- Replaced the pem devDependency in the Safari SSL e2e test with a
  direct `openssl req -x509` invocation
- Bumped commander to v15

BREAKING CHANGE: requires Appium >=4.0.0-beta.0 and drops Node 20
support (minimum is now ^22.22.2 || ^24.15.0 || >=26.0.0), matching
Appium 4's own minimum supported Node engine. The appium/app/reset
endpoint is also gone; use the corresponding 'mobile:' extensions to
manage app state instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tart

resetProperties() previously set only the legacy pageLoadMs/implicitWaitMs
fields, leaving BaseDriver's own scriptTimeoutMs/pageLoadTimeoutMs (now
exposed by GET /timeouts on Appium 4) at their stock 30000/300000 defaults
instead of the values that actually drive the browser session.

Route through setImplicitWait/setPageLoadTimeout/setScriptTimeout instead so
both stay in sync from the start, and add a regression test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The recorder waited a fixed 3 minutes for xctrace/instruments to exit
after SIGINT. Large traces (e.g. CPU Profiler, all processes) can take
longer to finalize, and on timeout the process is now killed and the
trace deleted, so the caller got nothing back. Let the caller raise the
limit; the default stays at 3 minutes.

Co-authored-by: Cassian433 <262026629+Cassian433@users.noreply.github.com>
…3023)

* Add 'value' and 'maxAttempts' to optional paramsfix: pass value and maxAttempts of mobile selectPickerWheelValue to WDA

Backport of #3017 to beta.

Original commit: ba9e634

* Add test for passing value and maxAttempts to WDAtest: backport picker wheel argument regression coverage
* fix: stop the running screen recording when forceRestart is set

* fix: keep the ffmpeg process until stop succeeds so a failed stop can be retried

---------

Co-authored-by: Cassian433 <262026629+Cassian433@users.noreply.github.com>
* fix: parse unquoted and RFC 5987 Content-Disposition filenames

* refactor: use filenameFromContentDisposition from base-driver

---------

Co-authored-by: Cassian433 <262026629+Cassian433@users.noreply.github.com>
BREAKING CHANGE: Removed the launchApp command and the POST /appium/app/launch route. Use mobile: launchApp instead.
BREAKING CHANGE: Removed the closeApp command and the POST /appium/app/close route. Use mobile: terminateApp instead.
BREAKING CHANGE: Removed the asyncScriptTimeout command and the POST /timeouts/async_script route. Use setScriptTimeout instead.
BREAKING CHANGE: Removed the no-op getSafariIsIphone driver method.
BREAKING CHANGE: Removed the no-op getSafariDeviceSize driver method.
BREAKING CHANGE: Removed the no-op getSafariIsNotched driver method.
BREAKING CHANGE: Removed the no-op getExtraTranslateWebCoordsOffset driver method.
BREAKING CHANGE: Removed the no-op getExtraNativeWebTapOffset driver method.
BREAKING CHANGE: Removed the deprecated hasElementId driver property.
BREAKING CHANGE: Removed the nativeWebTapTabBarVisibility setting. It had no effect, and setting it is no longer accepted.
BREAKING CHANGE: Removed the nativeWebTapSmartAppBannerVisibility setting. It had no effect, and setting it is no longer accepted.
BREAKING CHANGE: Removed the safariTabBarPosition setting. It had no effect, and setting it is no longer accepted.
)

* fix: declare autoLaunch capability in driver constraints

* fix: accept nullable implicit wait values from beta dependencies
* fix: retain and clean up screen recorder after stop failure

(cherry picked from commit 1a32f67)

* test: adapt beta recorder retry regression to kill escalation
BREAKING CHANGE: Removed the undocumented XCUITestDriver.executeAtomAsync method. It had no internal callers and was not exposed as a command. Driver subclasses that call it should use this.remote.executeAtomAsync(atom, args, this.curWebFrames) followed by this.waitForAtom(promise) instead.
#3041)

BREAKING CHANGE: Removed the asyncWaitMs driver property. Use scriptTimeoutMs (base driver) instead.
BREAKING CHANGE: GET /timeouts reports script: null for a new session, not 0.
BREAKING CHANGE: execute now uses the script timeout that the client sets (before: ignored). A client that sends 0, or a value shorter than its scripts, now gets script timeout.
* feat: add execute method for retrieving pressable buttons

* chore: fix route name

* docs: update description
…m unzip (#3080)

BREAKING CHANGE: the bsdtar utility is no longer used and the APPIUM_PREFER_SYSTEM_UNZIP environment variable has no effect. Non-UTF-8-flagged zip file names are decoded as utf8; cp437 is not supported.
…(tunnel preferred, usbmux fallback) (#3082)

BREAKING CHANGE: appium-ios-device is no longer used.
BREAKING CHANGE: The lockdown simulate-location service is gone, so setting the geolocation on real devices below iOS/tvOS 17 is not supported.
BREAKING CHANGE: The appium:safariSocketChunkSize capability has been removed.
BREAKING CHANGE: The appium:safariWebInspectorMaxFrameLength no longer has an effect on real devices.
BREAKING CHANGE: mobile: killApp always returns false on real devices below iOS/tvOS 17 (and on Linux/Windows hosts without a tunnel), because the instruments service it used is gone.
…exts (#3090)

* fix: stop stale remote debugger listeners when switching webview contexts

* chore(deps): bump appium-remote-debugger to ^18.0.3

* refactor: split setContext into private helpers
harsha509 and others added 9 commits October 31, 2026 20:33
* fix: remove perf recording temp files when start or upload fails

* style: format performance spec
* fix: align default screenshotQuality setting with WDA

* refactor: make WDA the source of truth for its settings
Restore beta's versions of files where the rebase of duplicated master
backports regressed them (recordscreen, types, implicit-wait, driver
command table) and fix a duplicated test declaration.

@KazuCocoa KazuCocoa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three reproducible timeout/compatibility issues to address before the major release. Reproduced against d9d43f9 with Appium 4.0.0-beta.7 (within the declared peer dependency range); device operations were stubbed for session initialization.

Comment thread lib/driver.ts
): Promise<DefaultCreateSessionResult<XCUITestDriverConstraints>> {
try {
const [sessionId, initialCaps] = await super.createSession(w3cCaps1, w3cCaps2, w3cCaps3, driverData);
const [sessionId, initialCaps] = await super.createSession(w3cCapabilities);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Synchronize the initial page-load timeout before starting the backend

Appium 4's BaseDriver.createSession() assigns the initial timeouts directly to its properties rather than calling the overridden setters. Creating a session with timeouts: {pageLoad: 45000} therefore makes getTimeouts().pageLoad return 45000, but this driver's pageLoadMs remains 6000. getNewRemoteDebugger() and mobileStartAutomationSession() both consume the latter, so the configured page-load budget is not actually used. I reproduced this by stubbing device startup and calling the real createSession(). Please synchronize pageLoadMs from pageLoadTimeoutMs after the superclass call and before start(), and cover an initial timeouts capability rather than only construction defaults and later timeout commands.

Comment thread lib/driver.ts
override setImplicitWait(ms: TimeoutValue): void {
super.setImplicitWait(ms);
// the automation session needs a number: null (no limit in BaseDriver) gives 0
this.syncAutomationSessionTimeout('implicitWaitTimeoutMs', ms ?? 0);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve unlimited implicit waits in the automation backend

BaseDriver treats implicit: null as an unlimited wait, but ms ?? 0 turns it into a zero-wait lookup for an active AutomationSession. The same conversion also occurs in mobileStartAutomationSession(). With a stubbed evaluator that returns no element on its first call and an element on its second, the actual remote-debugger findElements() implementation returns [] after one attempt with this conversion; using Infinity finds the element on the second attempt. Please preserve unlimited-wait semantics in both initialization and updates. The existing tests currently assert zero, so they lock in the mismatch between GET /timeouts and actual lookup behavior.

Comment thread package.json
},
"peerDependencies": {
"appium": "^3.0.0-rc.2"
"appium": "^4.0.0-beta.6"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Restore or explicitly remove the remaining legacy implicit-wait route

After switching to Appium 4, POST /session/:sessionId/timeouts/implicit_wait is still registered in lib/method-map.ts with command implicitWait, but neither this driver nor the new BaseDriver implements that method. On this head, typeof driver.implicitWait is undefined, and driver.executeCommand('implicitWait', 1000) rejects with NotYetImplementedError. If this deprecated route is being retained, add a bridge that validates the value and calls setImplicitWait(); if its removal is intentional for the major release, remove the route and its documentation alongside the other deleted APIs.

@mykola-mokhnach
mykola-mokhnach merged commit d9d43f9 into master Nov 1, 2026
41 of 45 checks passed
@mykola-mokhnach
mykola-mokhnach deleted the sync/rebase-beta branch November 1, 2026 07:11
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 13.0.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants