prompttest 1.5.0 → 1.5.2
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/README.md +21 -4
- package/dist/bin/prompttest.js +352 -213
- package/dist/engine.bundle.js +222 -183
- package/dist/index.js +222 -183
- package/dist/lib/adb.d.ts +27 -2
- package/dist/lib/ci.d.ts +49 -0
- package/dist/lib/license.d.ts +51 -0
- package/dist/lib/live-server.d.ts +4 -0
- package/dist/lib/profiler.d.ts +75 -0
- package/dist/lib/reporter.d.ts +14 -0
- package/dist/lib/runner-utils.d.ts +26 -0
- package/dist/lib/scaffold.d.ts +53 -0
- package/package.json +16 -5
package/dist/lib/adb.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ export interface AndroidDevice {
|
|
|
18
18
|
model?: string;
|
|
19
19
|
/** The product name of the device (optional) */
|
|
20
20
|
product?: string;
|
|
21
|
+
/** Transport connection type: 'usb' | 'wifi' | 'emulator' */
|
|
22
|
+
connectionType?: 'usb' | 'wifi' | 'emulator';
|
|
21
23
|
}
|
|
22
24
|
export interface DeviceMetrics {
|
|
23
25
|
battery?: {
|
|
@@ -42,6 +44,16 @@ export interface DeviceMetrics {
|
|
|
42
44
|
};
|
|
43
45
|
}
|
|
44
46
|
export declare function parseDeviceMetrics(batteryOutput: string, displayOutput: string, memoryOutput: string, graphicsOutput: string): DeviceMetrics;
|
|
47
|
+
/**
|
|
48
|
+
* Classifies a device connection type from its serial or model properties.
|
|
49
|
+
*/
|
|
50
|
+
export declare function classifyDeviceConnection(serial: string): 'usb' | 'wifi' | 'emulator';
|
|
51
|
+
/**
|
|
52
|
+
* Deduplicates multiple transport connections for the same physical Android hardware.
|
|
53
|
+
* Priority: USB > Wi-Fi (IP:port) > Wi-Fi (mDNS) > Emulator.
|
|
54
|
+
* Prevents simultaneous execution collisions on the same physical phone.
|
|
55
|
+
*/
|
|
56
|
+
export declare function deduplicateDevices(devices: AndroidDevice[]): AndroidDevice[];
|
|
45
57
|
/**
|
|
46
58
|
* AndroidDriver is responsible for executing ADB commands and handling device interactions.
|
|
47
59
|
* It manages the default targeted device, executes shell commands, extracts device state,
|
|
@@ -113,10 +125,23 @@ export declare class AndroidDriver {
|
|
|
113
125
|
*/
|
|
114
126
|
execAdbBinary(args: readonly string[] | string[], serial?: string, timeoutMs?: number): Promise<Buffer>;
|
|
115
127
|
/**
|
|
116
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Retrieves all raw connected Android devices from ADB without deduplication.
|
|
130
|
+
*/
|
|
131
|
+
getRawConnectedDevices(): Promise<AndroidDevice[]>;
|
|
132
|
+
/**
|
|
133
|
+
* Retrieves a list of currently connected Android devices.
|
|
134
|
+
* By default, deduplicates multiple transport channels for the same physical phone (prioritizing USB > Wi-Fi).
|
|
135
|
+
* @param options.deduplicate Set to false to return raw unfiltered endpoints.
|
|
117
136
|
* @returns A promise resolving to an array of AndroidDevice objects.
|
|
118
137
|
*/
|
|
119
|
-
getConnectedDevices(
|
|
138
|
+
getConnectedDevices(options?: {
|
|
139
|
+
deduplicate?: boolean;
|
|
140
|
+
}): Promise<AndroidDevice[]>;
|
|
141
|
+
/**
|
|
142
|
+
* Helper utility to deduplicate a list of AndroidDevice items.
|
|
143
|
+
*/
|
|
144
|
+
deduplicateDevices(devices: AndroidDevice[]): AndroidDevice[];
|
|
120
145
|
/**
|
|
121
146
|
* Wakes up the device screen and attempts to dismiss the keyguard.
|
|
122
147
|
* @param serial Optional target device serial.
|
package/dist/lib/ci.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file ci.ts
|
|
3
|
+
* @description One-Command CI/CD Workflow Scaffolder for PromptTest (CI-01).
|
|
4
|
+
* Generates automated regression workflows for GitHub Actions (using reactivecircus/android-emulator-runner)
|
|
5
|
+
* and GitLab CI with headless emulator virtualization and artifact reporting.
|
|
6
|
+
*/
|
|
7
|
+
export type CiProvider = 'github-actions' | 'gitlab-ci';
|
|
8
|
+
export type CiTrigger = 'push' | 'pull_request' | 'schedule';
|
|
9
|
+
export type CiTarget = 'specs' | 'explore';
|
|
10
|
+
export interface CiWorkflowOptions {
|
|
11
|
+
/** Target CI provider platform */
|
|
12
|
+
provider?: CiProvider;
|
|
13
|
+
/** Trigger events to invoke the pipeline */
|
|
14
|
+
triggers?: CiTrigger[];
|
|
15
|
+
/** Execution mode: running specs vs autonomous exploration */
|
|
16
|
+
target?: CiTarget;
|
|
17
|
+
/** Spec file or glob pattern to execute */
|
|
18
|
+
specPattern?: string;
|
|
19
|
+
/** Target Android package name (required for explore target) */
|
|
20
|
+
packageName?: string;
|
|
21
|
+
/** Node.js runtime version to configure */
|
|
22
|
+
nodeVersion?: number;
|
|
23
|
+
/** Android API level for the emulator runner */
|
|
24
|
+
apiLevel?: number;
|
|
25
|
+
/** CPU architecture for the emulator image */
|
|
26
|
+
arch?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface CiInitResult {
|
|
29
|
+
provider: CiProvider;
|
|
30
|
+
filePath: string;
|
|
31
|
+
fileName: string;
|
|
32
|
+
content: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Synthesizes a production-ready GitHub Actions YAML workflow
|
|
36
|
+
* utilizing headless Android emulator runners and artifact publishing.
|
|
37
|
+
*/
|
|
38
|
+
export declare function generateGithubWorkflow(options?: CiWorkflowOptions): string;
|
|
39
|
+
/**
|
|
40
|
+
* Synthesizes a GitLab CI YAML configuration.
|
|
41
|
+
*/
|
|
42
|
+
export declare function generateGitlabWorkflow(options?: CiWorkflowOptions): string;
|
|
43
|
+
/**
|
|
44
|
+
* Scaffolds the CI workflow file directly into the repository directory.
|
|
45
|
+
*/
|
|
46
|
+
export declare function initCi(options?: CiWorkflowOptions & {
|
|
47
|
+
destDir?: string;
|
|
48
|
+
customFileName?: string;
|
|
49
|
+
}): Promise<CiInitResult>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module license
|
|
3
|
+
* @description
|
|
4
|
+
* Viral Report Attribution & Offline Pro Licensing (LC-01).
|
|
5
|
+
* Cryptographically validates offline license keys, stores activation state,
|
|
6
|
+
* and controls white-label report formatting.
|
|
7
|
+
*/
|
|
8
|
+
export interface LicensePayload {
|
|
9
|
+
tier: 'free' | 'pro' | 'enterprise';
|
|
10
|
+
holder: string;
|
|
11
|
+
issuedAt: number;
|
|
12
|
+
expiresAt: number;
|
|
13
|
+
whiteLabel: boolean;
|
|
14
|
+
features: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface LicenseInfo {
|
|
17
|
+
active: boolean;
|
|
18
|
+
tier: 'free' | 'pro' | 'enterprise';
|
|
19
|
+
holder?: string;
|
|
20
|
+
expiresAt?: string;
|
|
21
|
+
whiteLabel: boolean;
|
|
22
|
+
features: string[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Generates a signed license key string for testing or license distribution.
|
|
26
|
+
*/
|
|
27
|
+
export declare function generateLicenseKey(payload: LicensePayload, secret?: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Cryptographically verifies an offline license key string.
|
|
30
|
+
*/
|
|
31
|
+
export declare function verifyLicenseKey(key: string, secret?: string): {
|
|
32
|
+
valid: boolean;
|
|
33
|
+
payload?: LicensePayload;
|
|
34
|
+
error?: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Activates and persists a valid license key locally.
|
|
38
|
+
*/
|
|
39
|
+
export declare function activateLicense(key: string, secret?: string): {
|
|
40
|
+
success: boolean;
|
|
41
|
+
message: string;
|
|
42
|
+
payload?: LicensePayload;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Retrieves current active license state.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getLicenseInfo(secret?: string): LicenseInfo;
|
|
48
|
+
/**
|
|
49
|
+
* Removes active license key and reverts to free tier.
|
|
50
|
+
*/
|
|
51
|
+
export declare function deactivateLicense(): boolean;
|
|
@@ -24,6 +24,10 @@ export interface LiveServerOptions {
|
|
|
24
24
|
initialReport?: QaReportData;
|
|
25
25
|
/** Optional AndroidDriver instance for interactive device state and actions. */
|
|
26
26
|
driver?: AndroidDriver;
|
|
27
|
+
/** Optional factory for creating an AutonomousExplorer instance (allows clean dependency injection in tests). */
|
|
28
|
+
explorerFactory?: (driver?: AndroidDriver) => {
|
|
29
|
+
explore: (options: any) => Promise<void>;
|
|
30
|
+
};
|
|
27
31
|
}
|
|
28
32
|
export interface LiveServerHandle {
|
|
29
33
|
/** The underlying Node.js HTTP server instance. */
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module profiler
|
|
3
|
+
* @description
|
|
4
|
+
* Real-Time Mobile Performance & FPS Profiler (PF-01).
|
|
5
|
+
* Samples `dumpsys gfxinfo <pkg>` and `dumpsys meminfo <pkg>` during test execution,
|
|
6
|
+
* computes frame rendering statistics, jank percentages, and memory growth.
|
|
7
|
+
*/
|
|
8
|
+
import { AndroidDriver } from './adb.js';
|
|
9
|
+
export interface FrameStats {
|
|
10
|
+
totalFrames: number;
|
|
11
|
+
jankyFrames: number;
|
|
12
|
+
jankPercentage: number;
|
|
13
|
+
p50Ms?: number;
|
|
14
|
+
p90Ms?: number;
|
|
15
|
+
p95Ms?: number;
|
|
16
|
+
p99Ms?: number;
|
|
17
|
+
missedVsync?: number;
|
|
18
|
+
slowUiThread?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface MemorySample {
|
|
21
|
+
timestamp: number;
|
|
22
|
+
stepIndex?: number;
|
|
23
|
+
stepName?: string;
|
|
24
|
+
totalPssKb: number;
|
|
25
|
+
nativeHeapKb?: number;
|
|
26
|
+
javaHeapKb?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface PerformanceReport {
|
|
29
|
+
packageName: string;
|
|
30
|
+
durationMs: number;
|
|
31
|
+
fpsCompliance: 'PASS' | 'WARN' | 'FAIL';
|
|
32
|
+
frames: FrameStats;
|
|
33
|
+
memory: {
|
|
34
|
+
startPssKb: number;
|
|
35
|
+
peakPssKb: number;
|
|
36
|
+
endPssKb: number;
|
|
37
|
+
deltaPssKb: number;
|
|
38
|
+
samples: MemorySample[];
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parses dumpsys gfxinfo stdout to extract frame counts, jank percentage, and percentile latencies.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseGfxInfo(stdout: string): FrameStats;
|
|
45
|
+
/**
|
|
46
|
+
* Parses dumpsys meminfo stdout to extract Total PSS, Native Heap, and Java Heap values in KB.
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseMemInfo(stdout: string): {
|
|
49
|
+
totalPssKb: number;
|
|
50
|
+
nativeHeapKb?: number;
|
|
51
|
+
javaHeapKb?: number;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* PerformanceProfiler tracks real-time frame times, jank metrics, and memory growth.
|
|
55
|
+
*/
|
|
56
|
+
export declare class PerformanceProfiler {
|
|
57
|
+
private driver;
|
|
58
|
+
private serial?;
|
|
59
|
+
private packageName;
|
|
60
|
+
private startTime;
|
|
61
|
+
private memorySamples;
|
|
62
|
+
constructor(driver?: AndroidDriver, serial?: string);
|
|
63
|
+
/**
|
|
64
|
+
* Starts tracking performance for the target package.
|
|
65
|
+
*/
|
|
66
|
+
start(packageName: string): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Captures a discrete memory sample at a step transition.
|
|
69
|
+
*/
|
|
70
|
+
sample(stepIndex: number, stepName: string): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Finalizes tracking and returns the performance report.
|
|
73
|
+
*/
|
|
74
|
+
stop(): Promise<PerformanceReport>;
|
|
75
|
+
}
|
package/dist/lib/reporter.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* JUnit XML. It plays a critical role in providing observability and
|
|
8
8
|
* traceability for autonomous test executions.
|
|
9
9
|
*/
|
|
10
|
+
import type { PerformanceReport } from './profiler.js';
|
|
10
11
|
/**
|
|
11
12
|
* Represents a single executed step or action during the test run.
|
|
12
13
|
*/
|
|
@@ -64,6 +65,14 @@ export interface QaReportData {
|
|
|
64
65
|
errorsDetected: string[];
|
|
65
66
|
/** Optional relative path to screen recording video (MP4). */
|
|
66
67
|
videoPath?: string;
|
|
68
|
+
/** Optional performance profiler metrics (PF-01). */
|
|
69
|
+
performanceMetrics?: PerformanceReport;
|
|
70
|
+
/** Details of any locators auto-healed during the test run */
|
|
71
|
+
healsApplied?: Array<{
|
|
72
|
+
original: string;
|
|
73
|
+
healed: string;
|
|
74
|
+
stepNumber: number;
|
|
75
|
+
}>;
|
|
67
76
|
/** The chronological list of all audit steps executed. */
|
|
68
77
|
steps: AuditStep[];
|
|
69
78
|
}
|
|
@@ -148,10 +157,15 @@ export declare class QaReporter implements Reporter {
|
|
|
148
157
|
private formats;
|
|
149
158
|
private videoPath?;
|
|
150
159
|
private embedScreenshots;
|
|
160
|
+
private performanceMetrics?;
|
|
151
161
|
private screenshotBuffers;
|
|
152
162
|
private stepListeners;
|
|
153
163
|
private completeListeners;
|
|
154
164
|
private errorListeners;
|
|
165
|
+
/**
|
|
166
|
+
* Sets the performance metrics collected by the profiler.
|
|
167
|
+
*/
|
|
168
|
+
setPerformanceMetrics(metrics: PerformanceReport): void;
|
|
155
169
|
/**
|
|
156
170
|
* Constructs a new QaReporter.
|
|
157
171
|
*
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* and diagnostic error generation.
|
|
8
8
|
*/
|
|
9
9
|
import { UiNode } from './crawler.js';
|
|
10
|
+
import { AndroidDriver } from './adb.js';
|
|
10
11
|
import { MemoryEngine } from './memory.js';
|
|
11
12
|
import type { QaReportData, Reporter, ReportFormat } from './reporter.js';
|
|
12
13
|
/**
|
|
@@ -73,6 +74,8 @@ export interface RunOptions {
|
|
|
73
74
|
tags?: string;
|
|
74
75
|
/** Emit machine-readable JSON execution summary to stdout. */
|
|
75
76
|
json?: boolean;
|
|
77
|
+
/** Real-time mobile performance & FPS profiler (PF-01). */
|
|
78
|
+
profile?: boolean;
|
|
76
79
|
}
|
|
77
80
|
/**
|
|
78
81
|
* Represents a single parsed action step in a plain-English test spec.
|
|
@@ -149,6 +152,8 @@ export interface PromptStep {
|
|
|
149
152
|
emailBodyContains?: string;
|
|
150
153
|
/** Healed locator provenance (original target string) */
|
|
151
154
|
healedFrom?: string;
|
|
155
|
+
/** Healed replacement string chosen by self-healing */
|
|
156
|
+
healedTo?: string;
|
|
152
157
|
}
|
|
153
158
|
/**
|
|
154
159
|
* Recursively expands `INCLUDE '<path>'` directives within a spec file.
|
|
@@ -288,3 +293,24 @@ export declare function createSyntheticReport(packageName: string, deviceId: str
|
|
|
288
293
|
* @returns Sanitized or masked string.
|
|
289
294
|
*/
|
|
290
295
|
export declare function maskSensitiveValue(value: string, target?: string): string;
|
|
296
|
+
export interface FailureTriageParams {
|
|
297
|
+
outputDir: string;
|
|
298
|
+
specName: string;
|
|
299
|
+
currentSpecName: string;
|
|
300
|
+
stepNum: number;
|
|
301
|
+
step: PromptStep;
|
|
302
|
+
error: Error;
|
|
303
|
+
stepStartTime: number;
|
|
304
|
+
startTime: number;
|
|
305
|
+
errorShot?: Buffer;
|
|
306
|
+
lastHierarchy?: {
|
|
307
|
+
xml?: string;
|
|
308
|
+
flat?: UiNode[];
|
|
309
|
+
} | null;
|
|
310
|
+
driver: AndroidDriver;
|
|
311
|
+
serial?: string;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Assembles failure triage folder, logs, hierarchy XML, match scores, and a ZIP archive.
|
|
315
|
+
*/
|
|
316
|
+
export declare function createFailureTriageBundle(params: FailureTriageParams): Promise<string | undefined>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module scaffold
|
|
3
|
+
* @description
|
|
4
|
+
* Inspects an active Android screen (or raw XML hierarchy) and synthesizes
|
|
5
|
+
* a starter plain-English test spec (.txt) containing Launch, Wait, form Type,
|
|
6
|
+
* button Tap, and element Verify steps.
|
|
7
|
+
*/
|
|
8
|
+
import { AndroidDriver } from './adb.js';
|
|
9
|
+
import { UiNode } from './crawler.js';
|
|
10
|
+
export interface ScaffoldOptions {
|
|
11
|
+
/** Target package to scaffold. Defaults to active foreground app */
|
|
12
|
+
packageName?: string;
|
|
13
|
+
/** Specific device serial to connect to */
|
|
14
|
+
deviceSerial?: string;
|
|
15
|
+
/** Explicit output path for the generated spec. Defaults to specs/<pkg>_scaffold.txt */
|
|
16
|
+
outputPath?: string;
|
|
17
|
+
/** Driver instance for dependency injection */
|
|
18
|
+
driver?: AndroidDriver;
|
|
19
|
+
/** Whether to explore interconnected screens and generate a multi-screen journey spec */
|
|
20
|
+
journey?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ScaffoldResult {
|
|
23
|
+
packageName: string;
|
|
24
|
+
specContent: string;
|
|
25
|
+
specPath?: string;
|
|
26
|
+
stepsCount: number;
|
|
27
|
+
inputCount: number;
|
|
28
|
+
buttonCount: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Sanitizes node labels by stripping Private Use Area (PUA) icon font glyphs,
|
|
32
|
+
* special/non-printable unicode codepoints, and leading/trailing punctuation.
|
|
33
|
+
*/
|
|
34
|
+
export declare function sanitizeNodeLabel(label: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Derives a human-readable clean label from a UiNode.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getNodeLabel(node: UiNode): string;
|
|
39
|
+
/**
|
|
40
|
+
* Synthesizes a valid PromptTest specification from a flat list of UiNodes.
|
|
41
|
+
*/
|
|
42
|
+
export declare function scaffoldSpecFromNodes(nodes: UiNode[], packageName?: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Validates that every generated step in a spec string parses cleanly with the PromptTest DSL.
|
|
45
|
+
*/
|
|
46
|
+
export declare function validateScaffoldedSpec(specContent: string): {
|
|
47
|
+
valid: boolean;
|
|
48
|
+
errors: string[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Connects to the device, retrieves screen hierarchy, and writes a scaffolded spec file.
|
|
52
|
+
*/
|
|
53
|
+
export declare function scaffoldSpec(options?: ScaffoldOptions): Promise<ScaffoldResult>;
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prompttest",
|
|
3
|
-
"version": "1.5.
|
|
4
|
-
"description": "Ultra-fast, zero-code autonomous mobile testing & visual QA brain for Android",
|
|
3
|
+
"version": "1.5.2",
|
|
4
|
+
"description": "Ultra-fast, zero-code autonomous mobile testing & visual QA brain for Android & iOS",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
|
-
"homepage": "https://github.
|
|
6
|
+
"homepage": "https://shriramsingh.github.io/prompttest-studio-site/",
|
|
7
7
|
"bugs": {
|
|
8
8
|
"url": "https://github.com/shriramsingh/prompttest-community/issues"
|
|
9
9
|
},
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"main": "dist/index.js",
|
|
16
16
|
"types": "dist/index.d.ts",
|
|
17
17
|
"bin": {
|
|
18
|
-
"prompttest": "dist/bin/prompttest.js"
|
|
18
|
+
"prompttest": "dist/bin/prompttest.js",
|
|
19
|
+
"prompttest-mobile": "dist/bin/prompttest.js"
|
|
19
20
|
},
|
|
20
21
|
"files": [
|
|
21
22
|
"dist",
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
"test:student": "tsx bin/prompttest.ts run specs/coachconnect_student.txt host.exp.exponent",
|
|
60
61
|
"audit": "npm audit --audit-level=high",
|
|
61
62
|
"build": "node scripts/build.mjs",
|
|
63
|
+
"package:mobile": "npm run build && node scripts/prepare-mobile-package.mjs",
|
|
62
64
|
"package:sea": "node scripts/package-sea.mjs",
|
|
63
65
|
"pack:verify": "node scripts/verify-pack.mjs",
|
|
64
66
|
"pack:smoke": "npm run build && node scripts/smoke-pack.mjs",
|
|
@@ -68,9 +70,18 @@
|
|
|
68
70
|
"preversion": "npm run typecheck && npm test",
|
|
69
71
|
"version:patch": "npm version patch",
|
|
70
72
|
"version:minor": "npm version minor",
|
|
71
|
-
"version:major": "npm version major"
|
|
73
|
+
"version:major": "npm version major",
|
|
74
|
+
"publish:all": "node scripts/publish-all.mjs",
|
|
75
|
+
"publish:all:dry": "node scripts/publish-all.mjs --dry-run"
|
|
72
76
|
},
|
|
73
77
|
"keywords": [
|
|
78
|
+
"prompttest-mobile",
|
|
79
|
+
"prompttest",
|
|
80
|
+
"mobile-testing",
|
|
81
|
+
"mobile-qa",
|
|
82
|
+
"android-automation",
|
|
83
|
+
"appium-alternative",
|
|
84
|
+
"detox-alternative",
|
|
74
85
|
"android",
|
|
75
86
|
"testing",
|
|
76
87
|
"automation",
|