@kraken-e2e/driver-ios 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/dist/appium-server.d.ts +23 -0
- package/dist/appium-server.d.ts.map +1 -0
- package/dist/appium-server.js +144 -0
- package/dist/appium-server.js.map +1 -0
- package/dist/doctor.d.ts +15 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +86 -0
- package/dist/doctor.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/locators.d.ts +16 -0
- package/dist/locators.d.ts.map +1 -0
- package/dist/locators.js +35 -0
- package/dist/locators.js.map +1 -0
- package/dist/manifest.d.ts +12 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +26 -0
- package/dist/manifest.js.map +1 -0
- package/dist/wdio-session.d.ts +59 -0
- package/dist/wdio-session.d.ts.map +1 -0
- package/dist/wdio-session.js +126 -0
- package/dist/wdio-session.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { CORE_OPERATIONS, KrakenError, } from '@kraken-e2e/contracts';
|
|
5
|
+
import { IOS_HID_KEY_USAGES, toIosSelector } from './locators.js';
|
|
6
|
+
const DEFAULT_WAIT_MS = 10_000;
|
|
7
|
+
/**
|
|
8
|
+
* UserSession adapter for XCUITest. All 11 core operations are supported —
|
|
9
|
+
* pressKey included, via device-level HID keyboard events (contract 2.0):
|
|
10
|
+
* the M1 gate first BLOCKED on a pressKey asymmetry, the mandated research
|
|
11
|
+
* found the faithful mechanism, and SemanticKey was redefined (back removed —
|
|
12
|
+
* an Android-only concept). Governance working as designed (ADR-0001 §5.4).
|
|
13
|
+
*/
|
|
14
|
+
export class IosUserSession {
|
|
15
|
+
browser;
|
|
16
|
+
services;
|
|
17
|
+
actorId;
|
|
18
|
+
driverId = 'ios';
|
|
19
|
+
platform;
|
|
20
|
+
capabilities;
|
|
21
|
+
#disposed = false;
|
|
22
|
+
#screenshots = 0;
|
|
23
|
+
/** Distinguishes artifacts across the run's many sessions (one per scenario). */
|
|
24
|
+
#sessionTag = randomUUID().slice(0, 8);
|
|
25
|
+
constructor(browser, actor, services) {
|
|
26
|
+
this.browser = browser;
|
|
27
|
+
this.services = services;
|
|
28
|
+
this.actorId = actor.id;
|
|
29
|
+
this.platform = actor.platform;
|
|
30
|
+
this.capabilities = Object.fromEntries(CORE_OPERATIONS.map((op) => [op, 'supported']));
|
|
31
|
+
}
|
|
32
|
+
async #element(target) {
|
|
33
|
+
const selector = toIosSelector(target);
|
|
34
|
+
const element = await this.browser.$(selector);
|
|
35
|
+
if (element.error || (element.elementId === undefined && !(await element.isExisting()))) {
|
|
36
|
+
throw new KrakenError('KRK-SESSION-ELEMENT-NOT-FOUND', `Actor "${this.actorId}" (ios) found no element for ${target.by}="${target.value}".`, {
|
|
37
|
+
data: { selector, target: { ...target } },
|
|
38
|
+
fix: target.by === 'testId'
|
|
39
|
+
? 'Check the accessibility identifier in the app (Appium Inspector helps), or use { by: "native" } with a class chain/predicate.'
|
|
40
|
+
: undefined,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return element;
|
|
44
|
+
}
|
|
45
|
+
async tap(target) {
|
|
46
|
+
await (await this.#element(target)).click();
|
|
47
|
+
}
|
|
48
|
+
async typeText(target, text) {
|
|
49
|
+
await (await this.#element(target)).setValue(text);
|
|
50
|
+
}
|
|
51
|
+
async readText(target) {
|
|
52
|
+
return (await this.#element(target)).getText();
|
|
53
|
+
}
|
|
54
|
+
async waitFor(target, state, opts) {
|
|
55
|
+
const selector = toIosSelector(target);
|
|
56
|
+
const element = await this.browser.$(selector);
|
|
57
|
+
const timeout = opts?.timeoutMs ?? DEFAULT_WAIT_MS;
|
|
58
|
+
const interval = opts?.pollMs ?? 100;
|
|
59
|
+
try {
|
|
60
|
+
if (state === 'attached') {
|
|
61
|
+
await element.waitForExist({ timeout, interval });
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
await element.waitForDisplayed({ timeout, interval, reverse: state === 'hidden' });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (cause) {
|
|
68
|
+
throw new KrakenError('KRK-SESSION-WAIT-TIMEOUT', `Actor "${this.actorId}" (ios) waited ${timeout}ms for ${target.by}="${target.value}" to be ${state}.`, { cause, data: { selector } });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async isDisplayed(target) {
|
|
72
|
+
const element = await this.browser.$(toIosSelector(target));
|
|
73
|
+
if (element.error || (element.elementId === undefined && !(await element.isExisting()))) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return element.isDisplayed();
|
|
77
|
+
}
|
|
78
|
+
async scrollIntoView(target) {
|
|
79
|
+
const element = await this.#element(target);
|
|
80
|
+
await this.browser.execute('mobile: scroll', {
|
|
81
|
+
elementId: element.elementId,
|
|
82
|
+
toVisible: true,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async pressKey(key) {
|
|
86
|
+
// FAITHFUL system-key semantics via device-level HID keyboard events
|
|
87
|
+
// (contract 2.0; live-verified on iOS 18.6 — ADR-0008 amendment).
|
|
88
|
+
await this.browser.execute('mobile: performIoHidEvent', {
|
|
89
|
+
page: 0x07,
|
|
90
|
+
usage: IOS_HID_KEY_USAGES[key],
|
|
91
|
+
durationSeconds: 0.005,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async navigate(destination) {
|
|
95
|
+
await this.browser.execute('mobile: deepLink', { url: destination });
|
|
96
|
+
}
|
|
97
|
+
async screenshot() {
|
|
98
|
+
this.#screenshots += 1;
|
|
99
|
+
const base64 = await this.browser.takeScreenshot();
|
|
100
|
+
const dir = join(this.services.artifactsDir, this.actorId);
|
|
101
|
+
mkdirSync(dir, { recursive: true });
|
|
102
|
+
const path = join(dir, `ios-${this.#sessionTag}-${this.#screenshots}.png`);
|
|
103
|
+
writeFileSync(path, Buffer.from(base64, 'base64'));
|
|
104
|
+
return { kind: 'screenshot', path };
|
|
105
|
+
}
|
|
106
|
+
async source() {
|
|
107
|
+
return this.browser.getPageSource();
|
|
108
|
+
}
|
|
109
|
+
async dispose() {
|
|
110
|
+
if (this.#disposed)
|
|
111
|
+
return;
|
|
112
|
+
this.#disposed = true;
|
|
113
|
+
try {
|
|
114
|
+
await this.browser.deleteSession();
|
|
115
|
+
}
|
|
116
|
+
catch (cause) {
|
|
117
|
+
this.services.logger.debug('deleteSession failed during dispose (ignored)', {
|
|
118
|
+
cause: cause instanceof Error ? cause.message : String(cause),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
native(kind) {
|
|
123
|
+
throw new KrakenError('KRK-SESSION-OP-UNSUPPORTED', `native("${String(kind)}") is not exposed by driver-ios yet (planned: ADR-0008).`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=wdio-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wdio-session.js","sourceRoot":"","sources":["../src/wdio-session.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kraken-e2e/driver-ios",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "iOS driver: Appium 3 + appium-xcuitest-driver (hostRequirements: darwin — macOS only, Apple platform restriction)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./manifest": {
|
|
12
|
+
"types": "./dist/manifest.d.ts",
|
|
13
|
+
"default": "./dist/manifest.js"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22.13.0"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@kraken-e2e/contracts": "^0.1.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^22.15.0",
|
|
30
|
+
"typescript": "~6.0.3",
|
|
31
|
+
"vitest": "^4.1.9",
|
|
32
|
+
"@kraken-e2e/contracts": "0.1.0",
|
|
33
|
+
"@kraken-e2e/core": "0.1.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"appium": "3.5.2",
|
|
37
|
+
"appium-xcuitest-driver": "11.17.1",
|
|
38
|
+
"webdriverio": "9.29.1"
|
|
39
|
+
},
|
|
40
|
+
"license": "GPL-3.0-only",
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc -p tsconfig.build.json",
|
|
43
|
+
"typecheck": "tsc --noEmit",
|
|
44
|
+
"test": "vitest run"
|
|
45
|
+
}
|
|
46
|
+
}
|