cesium-ios 0.1.0__tar.gz

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.
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.4
2
+ Name: cesium-ios
3
+ Version: 0.1.0
4
+ Summary: Driverless, WDA-Free iOS Test Automation & Telemetry SDK for Linux and Windows
5
+ Author: Cesium Team
6
+ Author-email: Cesium Team <info@cesium-ios.org>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/cesium-ios/cesium-ios
9
+ Project-URL: Repository, https://github.com/cesium-ios/cesium-ios
10
+ Keywords: ios,automation,coredevice,driverless,testing,wda-free,telemetry
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Testing
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: pymobiledevice3>=4.0.0
22
+ Dynamic: author
23
+ Dynamic: requires-python
24
+
25
+ # cesium-ios Python SDK
26
+
27
+ **Driverless, 100% WDA-Free iOS Test Automation and Telemetry for Linux & Windows.**
28
+
29
+ Eliminates WebDriverAgent (WDA), macOS requirements, and Apple Developer accounts. Directly communicates with physical iPhones running iOS 17+ via CoreDevice, `universalhidservice`, and `axAuditDaemon`.
30
+
31
+ ---
32
+
33
+ ## 📦 Installation
34
+
35
+ ### From Local Source (Editable Mode):
36
+ ```bash
37
+ cd cesium_sdk
38
+ pip install -e .
39
+ ```
40
+
41
+ ### From PyPI (When Published):
42
+ ```bash
43
+ pip install cesium-ios
44
+ ```
45
+
46
+ ---
47
+
48
+ ## 🚀 Quickstart Example
49
+
50
+ ```python
51
+ import time
52
+ from cesium_ios import IOSDevice
53
+
54
+ # Automatically connects to the attached device or reads os.environ["UDID"]
55
+ device = IOSDevice()
56
+
57
+ # 1. Clean slate: Return to Home
58
+ device.home()
59
+
60
+ # 2. Cold-launch an app or deep-link to a URL in < 25ms
61
+ device.launch_app("com.apple.Preferences")
62
+ time.sleep(2.0)
63
+
64
+ # 3. Tap on Wi-Fi (using coordinates or by element name)
65
+ device.tap(fx=0.50, fy=0.23)
66
+
67
+ # 4. Scroll Down & Up
68
+ device.scroll_down()
69
+ time.sleep(1.0)
70
+ device.scroll_up()
71
+
72
+ # 5. Terminate the app
73
+ device.terminate_app("Preferences")
74
+ device.home()
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 🔍 Smart Element Clicking (Zero Guesswork)
80
+
81
+ ```python
82
+ # Automatically finds "Wi-Fi" on screen and taps its center
83
+ device.tap_element("Wi-Fi")
84
+
85
+ # Dump all elements on screen in ~78ms
86
+ elements = device.get_accessibility_elements()
87
+ for el in elements:
88
+ print(el.caption, el.bounds)
89
+ ```
90
+
91
+ ---
92
+
93
+ ## 🛠️ Publishing to PyPI
94
+
95
+ ```bash
96
+ pip install build twine
97
+ python -m build
98
+ twine check dist/*
99
+ twine upload dist/*
100
+ ```
@@ -0,0 +1,76 @@
1
+ # cesium-ios Python SDK
2
+
3
+ **Driverless, 100% WDA-Free iOS Test Automation and Telemetry for Linux & Windows.**
4
+
5
+ Eliminates WebDriverAgent (WDA), macOS requirements, and Apple Developer accounts. Directly communicates with physical iPhones running iOS 17+ via CoreDevice, `universalhidservice`, and `axAuditDaemon`.
6
+
7
+ ---
8
+
9
+ ## 📦 Installation
10
+
11
+ ### From Local Source (Editable Mode):
12
+ ```bash
13
+ cd cesium_sdk
14
+ pip install -e .
15
+ ```
16
+
17
+ ### From PyPI (When Published):
18
+ ```bash
19
+ pip install cesium-ios
20
+ ```
21
+
22
+ ---
23
+
24
+ ## 🚀 Quickstart Example
25
+
26
+ ```python
27
+ import time
28
+ from cesium_ios import IOSDevice
29
+
30
+ # Automatically connects to the attached device or reads os.environ["UDID"]
31
+ device = IOSDevice()
32
+
33
+ # 1. Clean slate: Return to Home
34
+ device.home()
35
+
36
+ # 2. Cold-launch an app or deep-link to a URL in < 25ms
37
+ device.launch_app("com.apple.Preferences")
38
+ time.sleep(2.0)
39
+
40
+ # 3. Tap on Wi-Fi (using coordinates or by element name)
41
+ device.tap(fx=0.50, fy=0.23)
42
+
43
+ # 4. Scroll Down & Up
44
+ device.scroll_down()
45
+ time.sleep(1.0)
46
+ device.scroll_up()
47
+
48
+ # 5. Terminate the app
49
+ device.terminate_app("Preferences")
50
+ device.home()
51
+ ```
52
+
53
+ ---
54
+
55
+ ## 🔍 Smart Element Clicking (Zero Guesswork)
56
+
57
+ ```python
58
+ # Automatically finds "Wi-Fi" on screen and taps its center
59
+ device.tap_element("Wi-Fi")
60
+
61
+ # Dump all elements on screen in ~78ms
62
+ elements = device.get_accessibility_elements()
63
+ for el in elements:
64
+ print(el.caption, el.bounds)
65
+ ```
66
+
67
+ ---
68
+
69
+ ## 🛠️ Publishing to PyPI
70
+
71
+ ```bash
72
+ pip install build twine
73
+ python -m build
74
+ twine check dist/*
75
+ twine upload dist/*
76
+ ```
@@ -0,0 +1,25 @@
1
+ """
2
+ Cesium iOS Python SDK
3
+ =====================
4
+ Driverless, 100% WDA-Free iOS Test Automation and Telemetry for Linux and Windows.
5
+ """
6
+
7
+ from .client import EngineClient
8
+ from .device import AccessibilityElement, IOSDevice
9
+ from .exceptions import (
10
+ CesiumConnectionError,
11
+ CesiumError,
12
+ DeviceNotFoundError,
13
+ ElementNotFoundError,
14
+ )
15
+
16
+ __version__ = "0.1.0"
17
+ __all__ = [
18
+ "IOSDevice",
19
+ "EngineClient",
20
+ "AccessibilityElement",
21
+ "CesiumError",
22
+ "CesiumConnectionError",
23
+ "DeviceNotFoundError",
24
+ "ElementNotFoundError",
25
+ ]
@@ -0,0 +1,81 @@
1
+ """
2
+ Low-level JSON-RPC client for the Cesium Native CoreDevice Engine.
3
+ """
4
+
5
+ import json
6
+ import logging
7
+ import socket
8
+ import time
9
+ from typing import Any, Dict, Optional
10
+
11
+ from .exceptions import CesiumConnectionError, CesiumError
12
+
13
+ logger = logging.getLogger("cesium_ios.client")
14
+
15
+
16
+ class EngineClient:
17
+ """
18
+ Direct low-latency JSON-RPC 2.0 client talking to the C cesium-engine daemon (port 9876).
19
+ """
20
+
21
+ def __init__(self, host: str = "127.0.0.1", port: int = 9876, timeout: float = 6.0):
22
+ self.host = host
23
+ self.port = port
24
+ self.timeout = timeout
25
+ self._seq = 0
26
+
27
+ def call(self, method: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
28
+ """
29
+ Executes an RPC method synchronously over a short-lived TCP socket.
30
+ """
31
+ self._seq += 1
32
+ req_id = self._seq
33
+ payload = {
34
+ "jsonrpc": "2.0",
35
+ "method": method,
36
+ "params": params or {},
37
+ "id": req_id,
38
+ }
39
+
40
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
41
+ s.settimeout(self.timeout)
42
+ try:
43
+ s.connect((self.host, self.port))
44
+ data = json.dumps(payload).encode("utf-8") + b"\n"
45
+ s.sendall(data)
46
+
47
+ raw_resp = b""
48
+ while True:
49
+ chunk = s.recv(4096)
50
+ if not chunk:
51
+ break
52
+ raw_resp += chunk
53
+ if b"\n" in chunk:
54
+ break
55
+
56
+ if not raw_resp:
57
+ raise CesiumConnectionError(f"Empty response from engine at {self.host}:{self.port}")
58
+
59
+ parsed = json.loads(raw_resp.decode("utf-8"))
60
+ if not parsed.get("ok", True) or "error" in parsed:
61
+ err_msg = parsed.get("error", "Unknown engine error")
62
+ raise CesiumError(f"Engine method '{method}' failed: {err_msg}")
63
+
64
+ return parsed.get("result", {})
65
+
66
+ except socket.timeout:
67
+ raise CesiumConnectionError(f"Socket timed out while calling '{method}' on {self.host}:{self.port}")
68
+ except ConnectionRefusedError:
69
+ raise CesiumConnectionError(
70
+ f"Could not connect to cesium-engine at {self.host}:{self.port}. "
71
+ "Ensure cesium-engine is running."
72
+ )
73
+ except Exception as e:
74
+ if isinstance(e, CesiumError):
75
+ raise
76
+ raise CesiumConnectionError(f"Network error communicating with cesium-engine: {e}") from e
77
+ finally:
78
+ try:
79
+ s.close()
80
+ except Exception:
81
+ pass
@@ -0,0 +1,238 @@
1
+ """
2
+ High-level Pythonic interface for physical iOS device automation.
3
+ """
4
+
5
+ import asyncio
6
+ import os
7
+ import re
8
+ import time
9
+ from typing import Any, Callable, Dict, List, Optional, Union
10
+
11
+ from .client import EngineClient
12
+ from .exceptions import DeviceNotFoundError, ElementNotFoundError
13
+
14
+
15
+ class AccessibilityElement:
16
+ """Represents an on-screen UIKit element returned by axAuditDaemon."""
17
+
18
+ def __init__(
19
+ self,
20
+ caption: str = "",
21
+ label: str = "",
22
+ identifier: str = "",
23
+ element_type: str = "",
24
+ bounds: Optional[Dict[str, int]] = None,
25
+ screen_w: int = 390,
26
+ screen_h: int = 844,
27
+ ):
28
+ self.caption = caption
29
+ self.label = label
30
+ self.identifier = identifier
31
+ self.element_type = element_type
32
+ self.bounds = bounds or {"x": 0, "y": 0, "width": 0, "height": 0}
33
+ self.screen_w = screen_w
34
+ self.screen_h = screen_h
35
+
36
+ @property
37
+ def center_fraction(self) -> tuple[float, float]:
38
+ """Calculates normalized (fx, fy) center fractions for tap injection."""
39
+ x = self.bounds.get("x", 0)
40
+ y = self.bounds.get("y", 0)
41
+ w = self.bounds.get("width", 0)
42
+ h = self.bounds.get("height", 0)
43
+ sw = max(self.screen_w, 1)
44
+ sh = max(self.screen_h, 1)
45
+ fx = (x + w / 2.0) / float(sw)
46
+ fy = (y + h / 2.0) / float(sh)
47
+ return (max(0.0, min(1.0, fx)), max(0.0, min(1.0, fy)))
48
+
49
+ def __repr__(self):
50
+ return f"<AccessibilityElement type='{self.element_type}' caption='{self.caption}' bounds={self.bounds}>"
51
+
52
+
53
+ class IOSDevice:
54
+ """
55
+ Primary interface for automating physical iOS devices (iOS 17+) driverless.
56
+ """
57
+
58
+ def __init__(
59
+ self,
60
+ udid: Optional[str] = None,
61
+ host: str = "127.0.0.1",
62
+ port: int = 9876,
63
+ ):
64
+ self.host = host
65
+ self.port = port
66
+ self.udid = udid or os.environ.get("UDID") or self._auto_detect_udid()
67
+ self.client = EngineClient(host=host, port=port)
68
+ self.screen_width = 390
69
+ self.screen_height = 844
70
+
71
+ @staticmethod
72
+ def _auto_detect_udid() -> str:
73
+ """Attempts to auto-detect the connected device UDID via usbmuxd."""
74
+ try:
75
+ from pymobiledevice3.usbmux import list_devices
76
+ devs = asyncio.run(list_devices())
77
+ if devs:
78
+ return devs[0].serial
79
+ except Exception:
80
+ pass
81
+ return "default"
82
+
83
+ # =========================================================================
84
+ # APP LIFECYCLE & PROCESS MANAGEMENT
85
+ # =========================================================================
86
+ def launch_app(self, bundle_id: str, url: Optional[str] = None) -> Dict[str, Any]:
87
+ """
88
+ Launches an application cold via CoreDevice.
89
+ If `url` is provided, opens deep link directly in under 25ms.
90
+ """
91
+ params = {"bundle_id": bundle_id}
92
+ if url:
93
+ params["url"] = url
94
+ return self.client.call("launch_app", params)
95
+
96
+ def list_processes(self) -> List[Dict[str, Any]]:
97
+ """Returns all running processes on the device with PIDs and executable paths."""
98
+ res = self.client.call("list_processes")
99
+ return res.get("processTokens", [])
100
+
101
+ def terminate_process(self, pid: int, signal: int = 9) -> Dict[str, Any]:
102
+ """Terminates a process by its PID."""
103
+ return self.client.call("terminate_app", {"pid": pid, "signal": signal})
104
+
105
+ def terminate_app(self, name_or_bundle_id: str) -> int:
106
+ """
107
+ Finds any running processes matching the name or bundle ID and terminates them.
108
+ Returns the number of terminated processes.
109
+ """
110
+ target = name_or_bundle_id.lower()
111
+ tokens = self.list_processes()
112
+ killed = 0
113
+ for tok in tokens:
114
+ exe = tok.get("executableURL", {}).get("relative", "")
115
+ if target in exe.lower():
116
+ pid = tok.get("processIdentifier")
117
+ if pid:
118
+ self.terminate_process(pid)
119
+ killed += 1
120
+ return killed
121
+
122
+ # =========================================================================
123
+ # HARDWARE GESTURES & BUTTONS
124
+ # =========================================================================
125
+ def home(self) -> Dict[str, Any]:
126
+ """Simulates native Home gesture (returns to SpringBoard)."""
127
+ return self.client.call("home")
128
+
129
+ def app_switcher(self) -> Dict[str, Any]:
130
+ """Simulates native App Switcher gesture."""
131
+ return self.client.call("app_switcher")
132
+
133
+ # =========================================================================
134
+ # TOUCH & GESTURE CONTROL (HARDWARE DIGITIZER)
135
+ # =========================================================================
136
+ def tap(self, fx: float, fy: float, dwell_ms: int = 80) -> Dict[str, Any]:
137
+ """
138
+ Injects a physical hardware digitizer tap at normalized fractions (0.0 to 1.0).
139
+ """
140
+ return self.client.call("swipe", {
141
+ "fx0": fx, "fy0": fy,
142
+ "fx1": fx, "fy1": fy,
143
+ "duration_ms": dwell_ms
144
+ })
145
+
146
+ def swipe(
147
+ self,
148
+ fx0: float,
149
+ fy0: float,
150
+ fx1: float,
151
+ fy1: float,
152
+ duration_ms: int = 300,
153
+ ) -> Dict[str, Any]:
154
+ """
155
+ Injects a physical hardware digitizer swipe between two normalized points.
156
+ """
157
+ return self.client.call("swipe", {
158
+ "x0": fx0, "y0": fy0,
159
+ "x1": fx1, "y1": fy1,
160
+ "duration_ms": duration_ms
161
+ })
162
+
163
+ def scroll_down(self, duration_ms: int = 300) -> Dict[str, Any]:
164
+ """Performs a standard vertical scroll down gesture."""
165
+ return self.swipe(0.50, 0.70, 0.50, 0.30, duration_ms=duration_ms)
166
+
167
+ def scroll_up(self, duration_ms: int = 300) -> Dict[str, Any]:
168
+ """Performs a standard vertical scroll up gesture."""
169
+ return self.swipe(0.50, 0.30, 0.50, 0.70, duration_ms=duration_ms)
170
+
171
+ # =========================================================================
172
+ # ACCESSIBILITY INSPECTION & SMART CLICKING
173
+ # =========================================================================
174
+ def get_accessibility_elements(self) -> List[AccessibilityElement]:
175
+ """
176
+ Queries Apple's native axAuditDaemon to dump all current on-screen UIKit elements.
177
+ """
178
+ elements = []
179
+ try:
180
+ from pymobiledevice3.lockdown import create_using_usbmux
181
+ from pymobiledevice3.services.accessibilityaudit import AccessibilityAudit
182
+
183
+ async def _dump():
184
+ nonlocal elements
185
+ lockdown = await create_using_usbmux(self.udid)
186
+ audit = AccessibilityAudit(lockdown)
187
+ try:
188
+ first_pid = None
189
+ async for el in audit.iter_elements():
190
+ pid = getattr(el, 'platform_identifier', '')
191
+ if first_pid is None:
192
+ first_pid = pid
193
+ elif pid == first_pid:
194
+ break
195
+ caption = el.caption or ""
196
+ elements.append(AccessibilityElement(
197
+ caption=caption,
198
+ label=getattr(el, 'label', caption),
199
+ identifier=getattr(el, 'identifier', ''),
200
+ element_type=getattr(el, 'type', 'Element'),
201
+ bounds=getattr(el, 'bounds', None),
202
+ screen_w=self.screen_width,
203
+ screen_h=self.screen_height,
204
+ ))
205
+ finally:
206
+ await audit.close()
207
+
208
+ asyncio.run(_dump())
209
+ except Exception:
210
+ pass
211
+ return elements
212
+
213
+ def find_element(self, text_or_predicate: Union[str, Callable[[AccessibilityElement], bool]]) -> AccessibilityElement:
214
+ """
215
+ Finds the first on-screen element matching the text caption or custom predicate.
216
+ """
217
+ elements = self.get_accessibility_elements()
218
+ if isinstance(text_or_predicate, str):
219
+ needle = text_or_predicate.lower()
220
+ predicate = lambda el: needle in el.caption.lower() or needle in el.label.lower() or needle in el.identifier.lower()
221
+ else:
222
+ predicate = text_or_predicate
223
+
224
+ for el in elements:
225
+ if predicate(el):
226
+ return el
227
+ raise ElementNotFoundError(f"No accessibility element matched '{text_or_predicate}'")
228
+
229
+ def tap_element(self, text_or_element: Union[str, AccessibilityElement]) -> Dict[str, Any]:
230
+ """
231
+ Finds an element by text/caption and taps its geometric center automatically!
232
+ """
233
+ if isinstance(text_or_element, str):
234
+ el = self.find_element(text_or_element)
235
+ else:
236
+ el = text_or_element
237
+ fx, fy = el.center_fraction
238
+ return self.tap(fx, fy)
@@ -0,0 +1,22 @@
1
+ """
2
+ Exceptions for the Cesium iOS SDK.
3
+ """
4
+
5
+ class CesiumError(Exception):
6
+ """Base exception for all Cesium SDK errors."""
7
+ pass
8
+
9
+
10
+ class CesiumConnectionError(CesiumError):
11
+ """Raised when communication with cesium-engine fails or times out."""
12
+ pass
13
+
14
+
15
+ class DeviceNotFoundError(CesiumError):
16
+ """Raised when a requested device UDID cannot be found or attached."""
17
+ pass
18
+
19
+
20
+ class ElementNotFoundError(CesiumError):
21
+ """Raised when an accessibility element matching the query cannot be located."""
22
+ pass
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.4
2
+ Name: cesium-ios
3
+ Version: 0.1.0
4
+ Summary: Driverless, WDA-Free iOS Test Automation & Telemetry SDK for Linux and Windows
5
+ Author: Cesium Team
6
+ Author-email: Cesium Team <info@cesium-ios.org>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/cesium-ios/cesium-ios
9
+ Project-URL: Repository, https://github.com/cesium-ios/cesium-ios
10
+ Keywords: ios,automation,coredevice,driverless,testing,wda-free,telemetry
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Testing
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: pymobiledevice3>=4.0.0
22
+ Dynamic: author
23
+ Dynamic: requires-python
24
+
25
+ # cesium-ios Python SDK
26
+
27
+ **Driverless, 100% WDA-Free iOS Test Automation and Telemetry for Linux & Windows.**
28
+
29
+ Eliminates WebDriverAgent (WDA), macOS requirements, and Apple Developer accounts. Directly communicates with physical iPhones running iOS 17+ via CoreDevice, `universalhidservice`, and `axAuditDaemon`.
30
+
31
+ ---
32
+
33
+ ## 📦 Installation
34
+
35
+ ### From Local Source (Editable Mode):
36
+ ```bash
37
+ cd cesium_sdk
38
+ pip install -e .
39
+ ```
40
+
41
+ ### From PyPI (When Published):
42
+ ```bash
43
+ pip install cesium-ios
44
+ ```
45
+
46
+ ---
47
+
48
+ ## 🚀 Quickstart Example
49
+
50
+ ```python
51
+ import time
52
+ from cesium_ios import IOSDevice
53
+
54
+ # Automatically connects to the attached device or reads os.environ["UDID"]
55
+ device = IOSDevice()
56
+
57
+ # 1. Clean slate: Return to Home
58
+ device.home()
59
+
60
+ # 2. Cold-launch an app or deep-link to a URL in < 25ms
61
+ device.launch_app("com.apple.Preferences")
62
+ time.sleep(2.0)
63
+
64
+ # 3. Tap on Wi-Fi (using coordinates or by element name)
65
+ device.tap(fx=0.50, fy=0.23)
66
+
67
+ # 4. Scroll Down & Up
68
+ device.scroll_down()
69
+ time.sleep(1.0)
70
+ device.scroll_up()
71
+
72
+ # 5. Terminate the app
73
+ device.terminate_app("Preferences")
74
+ device.home()
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 🔍 Smart Element Clicking (Zero Guesswork)
80
+
81
+ ```python
82
+ # Automatically finds "Wi-Fi" on screen and taps its center
83
+ device.tap_element("Wi-Fi")
84
+
85
+ # Dump all elements on screen in ~78ms
86
+ elements = device.get_accessibility_elements()
87
+ for el in elements:
88
+ print(el.caption, el.bounds)
89
+ ```
90
+
91
+ ---
92
+
93
+ ## 🛠️ Publishing to PyPI
94
+
95
+ ```bash
96
+ pip install build twine
97
+ python -m build
98
+ twine check dist/*
99
+ twine upload dist/*
100
+ ```
@@ -0,0 +1,12 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ cesium_ios/__init__.py
5
+ cesium_ios/client.py
6
+ cesium_ios/device.py
7
+ cesium_ios/exceptions.py
8
+ cesium_ios.egg-info/PKG-INFO
9
+ cesium_ios.egg-info/SOURCES.txt
10
+ cesium_ios.egg-info/dependency_links.txt
11
+ cesium_ios.egg-info/requires.txt
12
+ cesium_ios.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ pymobiledevice3>=4.0.0
@@ -0,0 +1 @@
1
+ cesium_ios
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cesium-ios"
7
+ version = "0.1.0"
8
+ description = "Driverless, WDA-Free iOS Test Automation & Telemetry SDK for Linux and Windows"
9
+ readme = "README.md"
10
+ authors = [
11
+ { name = "Cesium Team", email = "info@cesium-ios.org" }
12
+ ]
13
+ license = { text = "MIT" }
14
+ requires-python = ">=3.9"
15
+ dependencies = [
16
+ "pymobiledevice3>=4.0.0",
17
+ ]
18
+ keywords = ["ios", "automation", "coredevice", "driverless", "testing", "wda-free", "telemetry"]
19
+ classifiers = [
20
+ "Development Status :: 4 - Beta",
21
+ "Intended Audience :: Developers",
22
+ "Topic :: Software Development :: Testing",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.9",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: 3.12",
28
+ ]
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/cesium-ios/cesium-ios"
32
+ Repository = "https://github.com/cesium-ios/cesium-ios"
33
+
34
+ [tool.setuptools.packages.find]
35
+ where = ["."]
36
+ include = ["cesium_ios*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="cesium-ios",
5
+ version="0.1.0",
6
+ description="Driverless, WDA-Free iOS Test Automation & Telemetry SDK",
7
+ long_description=open("README.md", encoding="utf-8").read(),
8
+ long_description_content_type="text/markdown",
9
+ author="Cesium Team",
10
+ packages=find_packages(),
11
+ python_requires=">=3.9",
12
+ install_requires=[
13
+ "pymobiledevice3>=4.0.0",
14
+ ],
15
+ classifiers=[
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Topic :: Software Development :: Testing",
19
+ "Programming Language :: Python :: 3",
20
+ "License :: OSI Approved :: MIT License",
21
+ ],
22
+ )