appium-session-recorder 0.0.2 → 0.0.4

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.
Files changed (73) hide show
  1. package/dist/index.js +33319 -0
  2. package/dist/ui/assets/index-CnJwu_Mc.js +8 -0
  3. package/dist/ui/assets/index-VIFL67d5.css +1 -0
  4. package/{src → dist}/ui/index.html +2 -1
  5. package/package.json +20 -13
  6. package/bun.lock +0 -731
  7. package/src/cli/arg-parser.ts +0 -311
  8. package/src/cli/commands/drive.ts +0 -147
  9. package/src/cli/commands/index.ts +0 -54
  10. package/src/cli/commands/proxy.ts +0 -41
  11. package/src/cli/commands/screen.ts +0 -73
  12. package/src/cli/commands/selectors.ts +0 -42
  13. package/src/cli/commands/session.ts +0 -64
  14. package/src/cli/commands/types.ts +0 -11
  15. package/src/cli/index.ts +0 -158
  16. package/src/cli/prompts.ts +0 -64
  17. package/src/cli/response.ts +0 -44
  18. package/src/core/appium/client.ts +0 -248
  19. package/src/core/index.ts +0 -5
  20. package/src/core/selectors/generate-candidates.ts +0 -155
  21. package/src/core/selectors/score-candidates.ts +0 -184
  22. package/src/core/types.ts +0 -79
  23. package/src/core/xml/parse-source.ts +0 -197
  24. package/src/index.ts +0 -7
  25. package/src/server/appium-client.ts +0 -24
  26. package/src/server/index.ts +0 -6
  27. package/src/server/interaction-recorder.ts +0 -74
  28. package/src/server/proxy-middleware.ts +0 -68
  29. package/src/server/routes.ts +0 -64
  30. package/src/server/server.ts +0 -43
  31. package/src/server/types.ts +0 -34
  32. package/src/ui/bun.lock +0 -311
  33. package/src/ui/package.json +0 -20
  34. package/src/ui/src/App.css +0 -12
  35. package/src/ui/src/App.tsx +0 -41
  36. package/src/ui/src/components/ActionCarousel.css +0 -128
  37. package/src/ui/src/components/ActionCarousel.tsx +0 -92
  38. package/src/ui/src/components/Inspector.css +0 -314
  39. package/src/ui/src/components/Inspector.tsx +0 -265
  40. package/src/ui/src/components/InteractionCard.css +0 -159
  41. package/src/ui/src/components/InteractionCard.tsx +0 -60
  42. package/src/ui/src/components/MainInspector.css +0 -304
  43. package/src/ui/src/components/MainInspector.tsx +0 -304
  44. package/src/ui/src/components/Stats.css +0 -27
  45. package/src/ui/src/components/Timeline.css +0 -31
  46. package/src/ui/src/components/Timeline.tsx +0 -37
  47. package/src/ui/src/hooks/useInteractions.ts +0 -73
  48. package/src/ui/src/index.tsx +0 -11
  49. package/src/ui/src/services/api.ts +0 -41
  50. package/src/ui/src/styles/tokens.css +0 -126
  51. package/src/ui/src/types.ts +0 -34
  52. package/src/ui/src/utils/__tests__/locators.test.ts +0 -304
  53. package/src/ui/src/utils/__tests__/xml-parser.test.ts +0 -326
  54. package/src/ui/src/utils/locators.ts +0 -14
  55. package/src/ui/src/utils/xml-parser.ts +0 -45
  56. package/src/ui/tsconfig.json +0 -34
  57. package/src/ui/tsconfig.node.json +0 -11
  58. package/src/ui/vite.config.ts +0 -22
  59. package/tests/cli/arg-parser.test.ts +0 -397
  60. package/tests/cli/drive-commands.test.ts +0 -151
  61. package/tests/cli/selectors-best.test.ts +0 -42
  62. package/tests/cli/session-commands.test.ts +0 -53
  63. package/tests/core/selector-candidates.test.ts +0 -83
  64. package/tests/core/selector-scoring.test.ts +0 -75
  65. package/tests/core/xml-parser.test.ts +0 -56
  66. package/tests/server/appium-client.test.ts +0 -229
  67. package/tests/server/interaction-recorder.test.ts +0 -377
  68. package/tests/server/proxy-middleware.test.ts +0 -343
  69. package/tests/server/routes.test.ts +0 -305
  70. package/tsconfig.json +0 -26
  71. package/vitest.config.ts +0 -16
  72. package/vitest.ui.config.ts +0 -15
  73. package/workflow.gif +0 -0
@@ -1,64 +0,0 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { AppiumCommandClient } from '../../core/appium/client';
3
- import { ensureNoUnexpectedFlags, expectOptionalString, expectStringFlag, parseFlags } from '../arg-parser';
4
- import type { CommandExecutionResult } from './types';
5
-
6
- export async function runSessionCreate(args: string[]): Promise<CommandExecutionResult> {
7
- const parsed = parseFlags(args);
8
- if (!parsed.success) throw new Error(parsed.error);
9
- if (parsed.positionals.length > 0) throw new Error(`Unexpected arguments: ${parsed.positionals.join(', ')}`);
10
-
11
- ensureNoUnexpectedFlags(parsed.flags, ['appium-url', 'caps-file', 'caps-json']);
12
-
13
- const appiumUrl = expectStringFlag('appium-url', parsed.flags['appium-url']);
14
- const capsFile = expectOptionalString(parsed.flags['caps-file']);
15
- const capsJson = expectOptionalString(parsed.flags['caps-json']);
16
-
17
- if ((capsFile && capsJson) || (!capsFile && !capsJson)) {
18
- throw new Error('Provide exactly one of --caps-file or --caps-json');
19
- }
20
-
21
- let capabilities: Record<string, unknown>;
22
-
23
- if (capsFile) {
24
- const raw = await readFile(capsFile, 'utf8');
25
- capabilities = JSON.parse(raw);
26
- } else {
27
- capabilities = JSON.parse(capsJson!);
28
- }
29
-
30
- const client = new AppiumCommandClient(appiumUrl);
31
- const session = await client.createSession(capabilities);
32
-
33
- return {
34
- command: 'session.create',
35
- result: {
36
- appiumUrl,
37
- sessionId: session.sessionId,
38
- value: session.value,
39
- },
40
- };
41
- }
42
-
43
- export async function runSessionDelete(args: string[]): Promise<CommandExecutionResult> {
44
- const parsed = parseFlags(args);
45
- if (!parsed.success) throw new Error(parsed.error);
46
- if (parsed.positionals.length > 0) throw new Error(`Unexpected arguments: ${parsed.positionals.join(', ')}`);
47
-
48
- ensureNoUnexpectedFlags(parsed.flags, ['appium-url', 'session-id']);
49
-
50
- const appiumUrl = expectStringFlag('appium-url', parsed.flags['appium-url']);
51
- const sessionId = expectStringFlag('session-id', parsed.flags['session-id']);
52
-
53
- const client = new AppiumCommandClient(appiumUrl);
54
- await client.deleteSession(sessionId);
55
-
56
- return {
57
- command: 'session.delete',
58
- result: {
59
- appiumUrl,
60
- sessionId,
61
- deleted: true,
62
- },
63
- };
64
- }
@@ -1,11 +0,0 @@
1
- import type { CliOutputOptions } from '../response';
2
-
3
- export type CommandHandlerInput = {
4
- args: string[];
5
- output: CliOutputOptions;
6
- };
7
-
8
- export type CommandExecutionResult = {
9
- command: string;
10
- result: unknown;
11
- };
package/src/cli/index.ts DELETED
@@ -1,158 +0,0 @@
1
- import * as p from '@clack/prompts';
2
- import { runPrompts } from './prompts';
3
- import { startServer } from '../server';
4
- import { parseArgs, parseCliInput } from './arg-parser';
5
- import { dispatchCommand } from './commands';
6
- import { emitResponse, errorResponse, successResponse } from './response';
7
- import { AppiumCommandError } from '../core/appium/client';
8
- import type { RecorderOptions } from '../server';
9
-
10
- function showHelp() {
11
- console.log(`
12
- 🎬 Appium Session Recorder
13
-
14
- USAGE:
15
- bun run cli [legacy-options]
16
- bun run cli <group> <command> [flags]
17
-
18
- LEGACY OPTIONS:
19
- -p, --port <number> Proxy server port (default: 4724)
20
- -u, --appium-url <url> Appium server URL (default: http://127.0.0.1:4723)
21
- --host <host> Proxy server host (default: 127.0.0.1)
22
- -h, --help Show this help message
23
- -v, --version Show version
24
-
25
- GLOBAL COMMAND FLAGS:
26
- --pretty Pretty-print JSON output
27
- --output <path> Write command JSON output to file
28
- (supported only with <group> <command> mode)
29
-
30
- COMMAND GROUPS:
31
- proxy start Start proxy server (JSON-first output)
32
- session create Create Appium session
33
- session delete Delete Appium session
34
- screen snapshot Capture screenshot/source and parsed metadata
35
- screen elements List parsed elements
36
- selectors best Return top ranked selectors for an element
37
- drive tap Tap element by selector
38
- drive type Type text into element by selector
39
- drive back Navigate back
40
- drive swipe Perform swipe gesture
41
- drive scroll Scroll in a direction (up/down/left/right)
42
- `);
43
- }
44
-
45
- function showVersion() {
46
- console.log('Appium Session Recorder v3.0.0');
47
- }
48
-
49
- async function runLegacyCLI(argv: string[]): Promise<void> {
50
- const result = parseArgs(argv);
51
-
52
- if (!result.success) {
53
- console.error(`Error: ${result.error}`);
54
- process.exit(1);
55
- }
56
-
57
- const args = result.args;
58
-
59
- if (args.help) {
60
- showHelp();
61
- process.exit(0);
62
- }
63
-
64
- if (args.version) {
65
- showVersion();
66
- process.exit(0);
67
- }
68
-
69
- // Determine if we need to run interactive prompts
70
- const hasRequiredArgs = args.port !== undefined || args.appiumUrl !== undefined;
71
-
72
- let promptConfig: Partial<RecorderOptions> = {
73
- port: args.port,
74
- appiumUrl: args.appiumUrl,
75
- host: args.host,
76
- };
77
-
78
- if (!hasRequiredArgs) {
79
- // Run interactive prompts
80
- promptConfig = await runPrompts();
81
- }
82
-
83
- // Display startup banner
84
- console.log('');
85
- p.intro('🎬 Starting Appium Session Recorder');
86
-
87
- const s = p.spinner();
88
- s.start('Initializing server...');
89
-
90
- try {
91
- // Start server
92
- startServer(promptConfig);
93
- s.stop('✅ Server initialized');
94
-
95
- console.log('');
96
- console.log(`📊 Configuration:`);
97
- console.log(` Port: ${promptConfig.port}`);
98
- console.log(` Appium URL: ${promptConfig.appiumUrl}`);
99
- console.log(` Host: ${promptConfig.host}`);
100
-
101
- p.outro('🚀 Server is running! Press Ctrl+C to stop.');
102
- } catch (error) {
103
- s.stop('❌ Failed to start server');
104
- console.error(error);
105
- process.exit(1);
106
- }
107
-
108
- // Handle graceful shutdown
109
- process.on('SIGINT', () => {
110
- console.log('\n');
111
- p.outro('👋 Shutting down...');
112
- process.exit(0);
113
- });
114
- }
115
-
116
- export async function runCLI(): Promise<void> {
117
- const parsedInput = parseCliInput(process.argv);
118
-
119
- if (!parsedInput.success) {
120
- const response = errorResponse('cli.parse', 'CLI_PARSE_ERROR', parsedInput.error);
121
- await emitResponse(response, { pretty: true });
122
- process.exit(1);
123
- }
124
-
125
- const cliInput = parsedInput.value;
126
-
127
- if (cliInput.mode === 'legacy') {
128
- await runLegacyCLI(cliInput.legacyArgv ?? process.argv);
129
- return;
130
- }
131
-
132
- const route = cliInput.route!;
133
- const commandName = `${route.group}.${route.command}`;
134
-
135
- try {
136
- const execution = await dispatchCommand(route.group, route.command, route.args);
137
- const response = successResponse(execution.command, execution.result);
138
- await emitResponse(response, cliInput.global);
139
- } catch (error) {
140
- if (error instanceof AppiumCommandError) {
141
- const response = errorResponse(commandName, error.code, error.message, {
142
- status: error.status,
143
- details: error.details,
144
- });
145
- await emitResponse(response, cliInput.global);
146
- process.exit(1);
147
- return;
148
- }
149
-
150
- const response = errorResponse(
151
- commandName,
152
- 'COMMAND_EXECUTION_ERROR',
153
- error instanceof Error ? error.message : 'Unknown error',
154
- );
155
- await emitResponse(response, cliInput.global);
156
- process.exit(1);
157
- }
158
- }
@@ -1,64 +0,0 @@
1
- import * as p from '@clack/prompts';
2
- import type {RecorderOptions} from '../server/types';
3
-
4
- export async function runPrompts(): Promise<Partial<RecorderOptions>> {
5
- console.clear();
6
-
7
- p.intro('🎬 Appium Session Recorder');
8
-
9
- const defaults = {
10
- port: '4724',
11
- host: '127.0.0.1',
12
- appiumUrl: 'http://127.0.0.1:4723',
13
- } as const;
14
-
15
- const answers = await p.group(
16
- {
17
- port: () => p.text({
18
- message: `Proxy port (default: ${defaults.port}):`,
19
- placeholder: defaults.port,
20
- defaultValue: defaults.port,
21
- validate: (value) => {
22
- if (!value || value.trim().length === 0) return;
23
- const num = Number(value);
24
- if (isNaN(num) || num < 1 || num > 65535) {
25
- return 'Please enter a valid port number (1-65535)';
26
- }
27
- },
28
- }),
29
- host: () => p.text({
30
- message: `Proxy host (default: ${defaults.host}):`,
31
- placeholder: defaults.host,
32
- defaultValue: defaults.host,
33
- validate: (value) => {
34
- if (!value || value.trim().length === 0) return undefined;
35
- },
36
- }),
37
- appiumUrl: () => p.text({
38
- message: `Appium server URL (default: ${defaults.appiumUrl}):`,
39
- placeholder: defaults.appiumUrl,
40
- defaultValue: defaults.appiumUrl,
41
- validate: (value) => {
42
- if (!value || value.trim().length === 0) return;
43
- try {
44
- new URL(value);
45
- } catch {
46
- return 'Please enter a valid URL';
47
- }
48
- },
49
- }),
50
- },
51
- {
52
- onCancel: () => {
53
- p.cancel('Operation cancelled.');
54
- process.exit(0);
55
- },
56
- }
57
- );
58
-
59
- return {
60
- port: Number((answers.port as string) || defaults.port),
61
- host: ((answers.host as string) || defaults.host).trim(),
62
- appiumUrl: ((answers.appiumUrl as string) || defaults.appiumUrl).trim(),
63
- };
64
- }
@@ -1,44 +0,0 @@
1
- import { mkdir, writeFile } from 'node:fs/promises';
2
- import path from 'node:path';
3
- import type { CommandResponse } from '../core/types';
4
-
5
- export type CliOutputOptions = {
6
- pretty: boolean;
7
- output?: string;
8
- };
9
-
10
- export function successResponse<T>(command: string, result: T): CommandResponse<T> {
11
- return {
12
- ok: true,
13
- command,
14
- timestamp: new Date().toISOString(),
15
- result,
16
- };
17
- }
18
-
19
- export function errorResponse(command: string, code: string, message: string, details?: unknown): CommandResponse {
20
- return {
21
- ok: false,
22
- command,
23
- timestamp: new Date().toISOString(),
24
- error: {
25
- code,
26
- message,
27
- details,
28
- },
29
- };
30
- }
31
-
32
- export async function emitResponse(response: CommandResponse, options: CliOutputOptions): Promise<void> {
33
- const output = options.pretty
34
- ? `${JSON.stringify(response, null, 2)}\n`
35
- : `${JSON.stringify(response)}\n`;
36
-
37
- process.stdout.write(output);
38
-
39
- if (options.output) {
40
- const outPath = path.resolve(options.output);
41
- await mkdir(path.dirname(outPath), { recursive: true });
42
- await writeFile(outPath, output, 'utf8');
43
- }
44
- }
@@ -1,248 +0,0 @@
1
- import type { Point } from '../types';
2
-
3
- const W3C_ELEMENT_KEY = 'element-6066-11e4-a52e-4f735466cecf';
4
-
5
- export class AppiumCommandError extends Error {
6
- constructor(
7
- message: string,
8
- public readonly code: string,
9
- public readonly status: number,
10
- public readonly details?: unknown,
11
- ) {
12
- super(message);
13
- }
14
- }
15
-
16
- export class AppiumCommandClient {
17
- constructor(private readonly appiumUrl: string) {}
18
-
19
- private parseWindowSize(value: unknown): { width: number; height: number } | null {
20
- if (!value || typeof value !== 'object') {
21
- return null;
22
- }
23
-
24
- const candidate = value as Record<string, unknown>;
25
- const width = Number(candidate.width);
26
- const height = Number(candidate.height);
27
-
28
- if (!Number.isFinite(width) || width <= 0 || !Number.isFinite(height) || height <= 0) {
29
- return null;
30
- }
31
-
32
- return { width, height };
33
- }
34
-
35
- private async tryGetWindowSize(sessionId: string, endpoint: '/window/rect' | '/window/size'): Promise<{ width: number; height: number } | null> {
36
- try {
37
- const result = await this.request<unknown>('GET', `/session/${sessionId}${endpoint}`);
38
- return this.parseWindowSize(result);
39
- } catch {
40
- return null;
41
- }
42
- }
43
-
44
- private async getWindowSize(sessionId: string): Promise<{ width: number; height: number }> {
45
- const rect = await this.tryGetWindowSize(sessionId, '/window/rect');
46
- if (rect) {
47
- return rect;
48
- }
49
-
50
- const size = await this.tryGetWindowSize(sessionId, '/window/size');
51
- if (size) {
52
- return size;
53
- }
54
-
55
- throw new AppiumCommandError(
56
- 'Unable to determine window size for scroll gesture',
57
- 'WINDOW_SIZE_UNAVAILABLE',
58
- 500,
59
- );
60
- }
61
-
62
- private async request<T>(method: string, path: string, body?: unknown): Promise<T> {
63
- const response = await fetch(`${this.appiumUrl}${path}`, {
64
- method,
65
- headers: {
66
- 'Content-Type': 'application/json',
67
- },
68
- body: body === undefined ? undefined : JSON.stringify(body),
69
- });
70
-
71
- let data: any = null;
72
- try {
73
- data = await response.json();
74
- } catch {
75
- data = null;
76
- }
77
-
78
- if (!response.ok) {
79
- const errorMessage = data?.value?.message || data?.message || `Appium request failed (${response.status})`;
80
- const errorCode = data?.value?.error || 'APPIUM_REQUEST_FAILED';
81
- throw new AppiumCommandError(errorMessage, errorCode, response.status, data);
82
- }
83
-
84
- if (data && typeof data === 'object' && 'value' in data) {
85
- return data.value as T;
86
- }
87
-
88
- return data as T;
89
- }
90
-
91
- async createSession(caps: Record<string, unknown>): Promise<{ sessionId: string; value: unknown }> {
92
- const payload = 'capabilities' in caps
93
- ? caps
94
- : {
95
- capabilities: {
96
- alwaysMatch: caps,
97
- firstMatch: [{}],
98
- },
99
- };
100
-
101
- const response = await fetch(`${this.appiumUrl}/session`, {
102
- method: 'POST',
103
- headers: {
104
- 'Content-Type': 'application/json',
105
- },
106
- body: JSON.stringify(payload),
107
- });
108
-
109
- const data: any = await response.json();
110
-
111
- if (!response.ok) {
112
- const errorMessage = data?.value?.message || data?.message || `Failed to create session (${response.status})`;
113
- const errorCode = data?.value?.error || 'APPIUM_SESSION_CREATE_FAILED';
114
- throw new AppiumCommandError(errorMessage, errorCode, response.status, data);
115
- }
116
-
117
- const sessionId = data?.sessionId || data?.value?.sessionId;
118
- if (!sessionId) {
119
- throw new AppiumCommandError('Appium did not return a sessionId', 'APPIUM_SESSION_ID_MISSING', 500, data);
120
- }
121
-
122
- return {
123
- sessionId,
124
- value: data?.value,
125
- };
126
- }
127
-
128
- async deleteSession(sessionId: string): Promise<void> {
129
- await this.request('DELETE', `/session/${sessionId}`);
130
- }
131
-
132
- async getSource(sessionId: string): Promise<string> {
133
- return await this.request<string>('GET', `/session/${sessionId}/source`);
134
- }
135
-
136
- async getScreenshot(sessionId: string): Promise<string> {
137
- return await this.request<string>('GET', `/session/${sessionId}/screenshot`);
138
- }
139
-
140
- async captureState(sessionId: string): Promise<{ source: string; screenshot: string }> {
141
- const [source, screenshot] = await Promise.all([
142
- this.getSource(sessionId),
143
- this.getScreenshot(sessionId),
144
- ]);
145
-
146
- return {
147
- source,
148
- screenshot,
149
- };
150
- }
151
-
152
- async findElement(sessionId: string, using: string, value: string): Promise<string> {
153
- const result = await this.request<Record<string, string>>('POST', `/session/${sessionId}/element`, {
154
- using,
155
- value,
156
- });
157
-
158
- return result[W3C_ELEMENT_KEY] || result.ELEMENT;
159
- }
160
-
161
- async tap(sessionId: string, using: string, value: string): Promise<void> {
162
- const elementId = await this.findElement(sessionId, using, value);
163
- if (!elementId) {
164
- throw new AppiumCommandError('Element not found for tap command', 'ELEMENT_NOT_FOUND', 404, {
165
- using,
166
- value,
167
- });
168
- }
169
-
170
- await this.request('POST', `/session/${sessionId}/element/${elementId}/click`, {});
171
- }
172
-
173
- async clear(sessionId: string, using: string, value: string): Promise<void> {
174
- const elementId = await this.findElement(sessionId, using, value);
175
- if (!elementId) {
176
- throw new AppiumCommandError('Element not found for clear command', 'ELEMENT_NOT_FOUND', 404, {
177
- using,
178
- value,
179
- });
180
- }
181
- await this.request('POST', `/session/${sessionId}/element/${elementId}/clear`, {});
182
- }
183
-
184
- async type(sessionId: string, using: string, value: string, text: string, clearFirst: boolean): Promise<void> {
185
- const elementId = await this.findElement(sessionId, using, value);
186
- if (!elementId) {
187
- throw new AppiumCommandError('Element not found for type command', 'ELEMENT_NOT_FOUND', 404, {
188
- using,
189
- value,
190
- });
191
- }
192
-
193
- if (clearFirst) {
194
- await this.request('POST', `/session/${sessionId}/element/${elementId}/clear`, {});
195
- }
196
-
197
- await this.request('POST', `/session/${sessionId}/element/${elementId}/value`, {
198
- text,
199
- value: [...text],
200
- });
201
- }
202
-
203
- async back(sessionId: string): Promise<void> {
204
- await this.request('POST', `/session/${sessionId}/back`, {});
205
- }
206
-
207
- async swipe(sessionId: string, from: Point, to: Point, durationMs: number): Promise<void> {
208
- await this.request('POST', `/session/${sessionId}/actions`, {
209
- actions: [
210
- {
211
- type: 'pointer',
212
- id: 'finger1',
213
- parameters: { pointerType: 'touch' },
214
- actions: [
215
- { type: 'pointerMove', duration: 0, x: from.x, y: from.y },
216
- { type: 'pointerDown', button: 0 },
217
- { type: 'pause', duration: Math.max(50, durationMs) },
218
- { type: 'pointerMove', duration: Math.max(50, durationMs), x: to.x, y: to.y },
219
- { type: 'pointerUp', button: 0 },
220
- ],
221
- },
222
- ],
223
- });
224
-
225
- await this.request('DELETE', `/session/${sessionId}/actions`);
226
- }
227
-
228
- async scroll(sessionId: string, direction: 'up' | 'down' | 'left' | 'right', durationMs = 300): Promise<void> {
229
- const { width, height } = await this.getWindowSize(sessionId);
230
-
231
- const centerX = Math.round(width * 0.5);
232
- const centerY = Math.round(height * 0.5);
233
- const startY = Math.round(height * 0.8);
234
- const endY = Math.round(height * 0.2);
235
- const startX = Math.round(width * 0.8);
236
- const endX = Math.round(width * 0.2);
237
-
238
- const coords: Record<'up' | 'down' | 'left' | 'right', { from: Point; to: Point }> = {
239
- down: { from: { x: centerX, y: startY }, to: { x: centerX, y: endY } },
240
- up: { from: { x: centerX, y: endY }, to: { x: centerX, y: startY } },
241
- left: { from: { x: startX, y: centerY }, to: { x: endX, y: centerY } },
242
- right: { from: { x: endX, y: centerY }, to: { x: startX, y: centerY } },
243
- };
244
-
245
- const { from, to } = coords[direction];
246
- await this.swipe(sessionId, from, to, durationMs);
247
- }
248
- }
package/src/core/index.ts DELETED
@@ -1,5 +0,0 @@
1
- export * from './types';
2
- export * from './appium/client';
3
- export * from './xml/parse-source';
4
- export * from './selectors/generate-candidates';
5
- export * from './selectors/score-candidates';