From 3e4ca8e32fad2d52bbb12bbc7c207cd121699ce8 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 9 Nov 2026 08:12:38 +0100 Subject: [PATCH] feat!: add Appium 4 support BREAKING CHANGE: requires Appium ^4.0.0-beta.6 and Node ^22.22.2 || ^24.15.0 || >=26.0.0. createSession takes a single w3cCapabilities argument, and the default exports are removed (use the named export). --- README.md | 2 +- docs/getting-started/index.md | 3 ++- lib/commands/cookies.ts | 6 ++++++ lib/commands/find.ts | 6 ++++++ lib/commands/record-screen.ts | 7 +++++++ lib/driver.ts | 30 ++++++++++++------------------ lib/index.ts | 5 +---- lib/logger.ts | 4 +--- lib/safari.ts | 2 -- package.json | 16 ++++++++-------- 10 files changed, 44 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 0403359..78bbdc6 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ This is an Appium driver for automating the Safari browser on macOS, iOS and iPadOS. > [!IMPORTANT] -> Since major version *4.0.0*, this driver is only compatible with Appium 3. +> Since major version *6.0.0*, this driver is only compatible with Appium 4. ## Documentation diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 74bde10..612d02c 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -25,7 +25,8 @@ and prerequisites of Appium itself can be found in [the Appium documentation](ht | Safari driver version | Supported Appium server version | | --- | --- | -| >= 4.0.0 | Appium 3 | +| >= 6.0.0 | Appium 4 | +| 4.0.0 - 5.0.11 | Appium 3 | | 3.0.0 - 3.5.26 | Appium 2 | ## Installation diff --git a/lib/commands/cookies.ts b/lib/commands/cookies.ts index 8193277..8ac6278 100644 --- a/lib/commands/cookies.ts +++ b/lib/commands/cookies.ts @@ -1,5 +1,11 @@ import type {SafariDriver} from '../driver.js'; +declare module '../driver.js' { + interface SafariDriver { + deleteCookies(...args: Parameters): ReturnType; + } +} + /** * Delete all cookies visible to the current page. * diff --git a/lib/commands/find.ts b/lib/commands/find.ts index 76d9198..08b8932 100644 --- a/lib/commands/find.ts +++ b/lib/commands/find.ts @@ -2,6 +2,12 @@ import {util} from 'appium/support.js'; import type {SafariDriver} from '../driver.js'; +declare module '../driver.js' { + interface SafariDriver { + findElOrEls(...args: Parameters): ReturnType; + } +} + /** * Find element(s) using the specified strategy and selector. * This is needed to make lookup by image working. diff --git a/lib/commands/record-screen.ts b/lib/commands/record-screen.ts index 083e15f..474b40c 100644 --- a/lib/commands/record-screen.ts +++ b/lib/commands/record-screen.ts @@ -6,6 +6,13 @@ import {util, fs, net, tempDir} from 'appium/support.js'; import type {SafariDriver} from '../driver.js'; import {parseRuntimeIdentifier} from '../utils.js'; +declare module '../driver.js' { + interface SafariDriver { + startRecordingScreen(...args: Parameters): ReturnType; + stopRecordingScreen(...args: Parameters): ReturnType; + } +} + const DEFAULT_TIME_LIMIT_MS = 60 * 10 * 1000; // 10 minutes const DEFAULT_EXT = '.mp4'; diff --git a/lib/driver.ts b/lib/driver.ts index 05e567d..3dd23d8 100644 --- a/lib/driver.ts +++ b/lib/driver.ts @@ -1,7 +1,6 @@ import type { RouteMatcher, DefaultCreateSessionResult, - DriverData, InitialOpts, StringRecord, ExternalDriver, @@ -9,9 +8,9 @@ import type { } from '@appium/types'; import {BaseDriver} from 'appium/driver.js'; -import * as cookieCommands from './commands/cookies.js'; -import * as findCommands from './commands/find.js'; -import * as recordScreenCommands from './commands/record-screen.js'; +import {deleteCookies} from './commands/cookies.js'; +import {findElOrEls} from './commands/find.js'; +import {startRecordingScreen, stopRecordingScreen, type ScreenRecorder} from './commands/record-screen.js'; import {desiredCapConstraints, type SafariConstraints} from './desired-caps.js'; import {newMethodMap} from './method-map.js'; import {SafariDriverServer} from './safari.js'; @@ -35,14 +34,7 @@ export class SafariDriver static newMethodMap = newMethodMap; proxyReqRes: ((...args: any[]) => any) | null = null; - _screenRecorder: recordScreenCommands.ScreenRecorder | null = null; - - deleteCookies = cookieCommands.deleteCookies; - - findElOrEls = findCommands.findElOrEls; - - startRecordingScreen = recordScreenCommands.startRecordingScreen; - stopRecordingScreen = recordScreenCommands.stopRecordingScreen; + _screenRecorder: ScreenRecorder | null = null; private isProxyActive = false; private _safari: SafariDriverServer | null = null; @@ -83,12 +75,9 @@ export class SafariDriver } override async createSession( - w3cCaps1: W3CSafariDriverCaps, - w3cCaps2?: W3CSafariDriverCaps, - w3cCaps3?: W3CSafariDriverCaps, - driverData?: DriverData[], + w3cCapabilities: W3CSafariDriverCaps, ): Promise> { - const [sessionId, caps] = await super.createSession(w3cCaps1, w3cCaps2, w3cCaps3, driverData); + const [sessionId, caps] = await super.createSession(w3cCapabilities); this._safari = new SafariDriverServer(this.log); try { await this.safari.start(formatCapsForServer(caps), { @@ -125,4 +114,9 @@ export class SafariDriver } } -export default SafariDriver; +Object.assign(SafariDriver.prototype, { + deleteCookies, + findElOrEls, + startRecordingScreen, + stopRecordingScreen, +}); diff --git a/lib/index.ts b/lib/index.ts index 0c10727..634e1cb 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,4 +1 @@ -import {SafariDriver} from './driver.js'; - -export default SafariDriver; -export {SafariDriver}; +export {SafariDriver} from './driver.js'; diff --git a/lib/logger.ts b/lib/logger.ts index 4f6bb01..6f22e78 100644 --- a/lib/logger.ts +++ b/lib/logger.ts @@ -1,5 +1,3 @@ import {logger} from 'appium/support.js'; -const log = logger.getLogger('Safari'); - -export default log; +export const log = logger.getLogger('Safari'); diff --git a/lib/safari.ts b/lib/safari.ts index 4ff96a8..519f242 100644 --- a/lib/safari.ts +++ b/lib/safari.ts @@ -203,5 +203,3 @@ export class SafariDriverServer { } } } - -export default SafariDriverServer; diff --git a/package.json b/package.json index 4b437df..641d8f3 100644 --- a/package.json +++ b/package.json @@ -63,20 +63,20 @@ "teen_process": "^4.0.4" }, "devDependencies": { - "@appium/docutils": "^3.0.0", - "@appium/oxc-config": "^1.1.0", - "@appium/semantic-release-config": "^1.1.0", - "@appium/tsconfig": "^1.2.0", - "@appium/types": "^1.0.0-rc.1", + "@appium/docutils": "^4.0.0-beta.5", + "@appium/oxc-config": "^2.0.0-beta.2", + "@appium/semantic-release-config": "^2.0.0-beta.1", + "@appium/tsconfig": "^2.0.0-beta.1", + "@appium/types": "^2.0.0-beta.5", "@types/node": "^26.0.0", "@types/portscanner": "^2.1.4", - "webdriverio": "^9.0.5" + "webdriverio": "^10.1.0" }, "peerDependencies": { - "appium": "^3.0.0-rc.2" + "appium": "^4.0.0-beta.6" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "node": "^22.22.2 || ^24.15.0 || >=26.0.0", "npm": ">=10" }, "appium": {