quantikmind-cli 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.
- quantikmind_cli-0.1.0/PKG-INFO +695 -0
- quantikmind_cli-0.1.0/README.md +663 -0
- quantikmind_cli-0.1.0/pyproject.toml +69 -0
- quantikmind_cli-0.1.0/quantikmind_cli/__init__.py +6 -0
- quantikmind_cli-0.1.0/quantikmind_cli/agent/__init__.py +1 -0
- quantikmind_cli-0.1.0/quantikmind_cli/agent/prometheus.py +117 -0
- quantikmind_cli-0.1.0/quantikmind_cli/agent/push.py +1 -0
- quantikmind_cli-0.1.0/quantikmind_cli/agent/service.py +1 -0
- quantikmind_cli-0.1.0/quantikmind_cli/api.py +326 -0
- quantikmind_cli-0.1.0/quantikmind_cli/cli.py +1672 -0
- quantikmind_cli-0.1.0/quantikmind_cli/config.py +111 -0
- quantikmind_cli-0.1.0/quantikmind_cli/git.py +83 -0
- quantikmind_cli-0.1.0/quantikmind_cli/manifest.py +134 -0
- quantikmind_cli-0.1.0/quantikmind_cli/record_tests.py +268 -0
- quantikmind_cli-0.1.0/quantikmind_cli/scanner.py +547 -0
- quantikmind_cli-0.1.0/quantikmind_cli/subset.py +106 -0
- quantikmind_cli-0.1.0/quantikmind_cli.egg-info/PKG-INFO +695 -0
- quantikmind_cli-0.1.0/quantikmind_cli.egg-info/SOURCES.txt +30 -0
- quantikmind_cli-0.1.0/quantikmind_cli.egg-info/dependency_links.txt +1 -0
- quantikmind_cli-0.1.0/quantikmind_cli.egg-info/entry_points.txt +2 -0
- quantikmind_cli-0.1.0/quantikmind_cli.egg-info/requires.txt +7 -0
- quantikmind_cli-0.1.0/quantikmind_cli.egg-info/top_level.txt +1 -0
- quantikmind_cli-0.1.0/setup.cfg +4 -0
- quantikmind_cli-0.1.0/tests/test_api.py +353 -0
- quantikmind_cli-0.1.0/tests/test_cli.py +2766 -0
- quantikmind_cli-0.1.0/tests/test_config.py +52 -0
- quantikmind_cli-0.1.0/tests/test_e2e_smoke.py +263 -0
- quantikmind_cli-0.1.0/tests/test_git.py +78 -0
- quantikmind_cli-0.1.0/tests/test_manifest.py +317 -0
- quantikmind_cli-0.1.0/tests/test_prometheus.py +117 -0
- quantikmind_cli-0.1.0/tests/test_record_tests.py +348 -0
- quantikmind_cli-0.1.0/tests/test_scanner.py +207 -0
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: quantikmind-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Command-line tools for Quantik Mind test selection and runtime signal collection.
|
|
5
|
+
Author-email: Quantik Mind <info@quantikmind.com>
|
|
6
|
+
Project-URL: Homepage, https://www.quantikmind.com
|
|
7
|
+
Project-URL: Repository, https://github.com/Quantik-Mind/quantikmind-platform
|
|
8
|
+
Project-URL: Issues, https://github.com/Quantik-Mind/quantikmind-platform/issues
|
|
9
|
+
Keywords: quantik-mind,quantikmind,testing,qa,quality-assurance,ci,ci-cd,cli,risk-based-testing,test-selection,observability,devops,devsecops
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
21
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
|
+
Classifier: Topic :: Software Development :: Testing
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
Requires-Dist: click>=8.1
|
|
27
|
+
Requires-Dist: requests>=2.31
|
|
28
|
+
Requires-Dist: PyYAML>=6.0
|
|
29
|
+
Requires-Dist: rich>=13.0
|
|
30
|
+
Provides-Extra: test
|
|
31
|
+
Requires-Dist: pytest>=8.0; extra == "test"
|
|
32
|
+
|
|
33
|
+
# Quantik Mind CLI
|
|
34
|
+
|
|
35
|
+
Current release: `0.1.0b1` Free Trial Beta (`0.1.0 Beta`) for early adopters
|
|
36
|
+
and design partners. This is not a stable 1.0 GA contract.
|
|
37
|
+
|
|
38
|
+
`qmind` connects a repository, CI pipeline, and local Prometheus metrics to
|
|
39
|
+
Quantik Mind. The current CLI supports the core customer integration flow:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
qmind init
|
|
43
|
+
qmind sync library
|
|
44
|
+
qmind record build
|
|
45
|
+
pytest $(qmind subset) --junitxml=test-results/junit.xml
|
|
46
|
+
qmind record tests --results-dir test-results
|
|
47
|
+
qmind status
|
|
48
|
+
qmind observability configure prometheus --file prometheus-signals.yaml
|
|
49
|
+
qmind observability status
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
Package publishing is not part of this Free Trial Beta readiness PR. For local
|
|
55
|
+
development, free-trial, or early-adopter installs, install the CLI from this
|
|
56
|
+
repository:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
cd quantikmind-cli
|
|
60
|
+
pip install -e .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
This installs the `qmind` command in the active Python environment. A packaged
|
|
64
|
+
install flow can be added after package publishing is available.
|
|
65
|
+
|
|
66
|
+
## Quickstart
|
|
67
|
+
|
|
68
|
+
Run these commands from the repository root of the project you want Quantik
|
|
69
|
+
Mind to select tests for.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
qmind init
|
|
73
|
+
qmind sync library
|
|
74
|
+
qmind status
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`qmind init` creates `qmind.yaml` in the repository and stores your API key in
|
|
78
|
+
`~/.qmind/credentials.yaml`. `qmind sync library` scans implemented framework
|
|
79
|
+
types and uploads the functional test library. `qmind status` checks
|
|
80
|
+
connectivity, project setup, signal readiness, and subscription usage.
|
|
81
|
+
|
|
82
|
+
## Project-Scoped API Keys
|
|
83
|
+
|
|
84
|
+
The full CLI workflow is designed to run with one project-scoped API key. In
|
|
85
|
+
the Settings API Access UI, create a key with the `CLI full project workflow`
|
|
86
|
+
preset for the target project.
|
|
87
|
+
|
|
88
|
+
Required scopes for that preset:
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
library:read
|
|
92
|
+
library:write
|
|
93
|
+
build:read
|
|
94
|
+
build:write
|
|
95
|
+
selection:read
|
|
96
|
+
selection:run
|
|
97
|
+
results:read
|
|
98
|
+
results:write
|
|
99
|
+
history:read
|
|
100
|
+
history:write
|
|
101
|
+
observability:read
|
|
102
|
+
observability:write
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Project-scoped keys cannot create projects, cannot access other projects, and
|
|
106
|
+
do not grant organization-admin permissions. Revoke or rotate keys from the
|
|
107
|
+
same API Access screen. After rotating, replace `QMIND_API_KEY` in CI secrets
|
|
108
|
+
or rerun `qmind init --api-key <new-key> --project-id <project-id>`.
|
|
109
|
+
|
|
110
|
+
For CI or non-interactive setup, pass values explicitly or use environment
|
|
111
|
+
variables:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
qmind init \
|
|
115
|
+
--api-key "$QMIND_API_KEY" \
|
|
116
|
+
--api-url "$QMIND_API_URL" \
|
|
117
|
+
--project-id "$QMIND_PROJECT_ID" \
|
|
118
|
+
--framework pytest \
|
|
119
|
+
--test-dir tests \
|
|
120
|
+
--results-dir test-results \
|
|
121
|
+
--non-interactive
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
For an existing project, `--project-id` binds the local repository to that
|
|
125
|
+
project and validates the key against it. It does not create a project:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
qmind init \
|
|
129
|
+
--api-key "$QMIND_API_KEY" \
|
|
130
|
+
--api-url "http://localhost:8000" \
|
|
131
|
+
--project-id "$QMIND_PROJECT_ID" \
|
|
132
|
+
--framework pytest \
|
|
133
|
+
--non-interactive
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
You can also use an explicit YAML or JSON library file instead of scanner
|
|
137
|
+
discovery:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
qmind sync library --file ./test-library.yaml --dry-run --output ./qmind-library.preview.json
|
|
141
|
+
qmind sync library --file ./test-library.yaml
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Manifest duration fields are preserved for savings metrics. Use any one of
|
|
145
|
+
`avg_duration_ms`, `duration_ms`, `estimated_duration_ms`, or
|
|
146
|
+
`constraints.estimated_duration_ms`; the CLI uploads them as `avg_duration_ms`.
|
|
147
|
+
|
|
148
|
+
## Recommended CI Flow
|
|
149
|
+
|
|
150
|
+
Record the build, request the selected subset, run your existing test runner,
|
|
151
|
+
then import JUnit XML results:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
qmind record build
|
|
155
|
+
pytest $(qmind subset) --junitxml=test-results/junit.xml
|
|
156
|
+
qmind record tests --results-dir test-results
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
During early rollout, use a fallback policy that matches your risk tolerance.
|
|
160
|
+
Many teams start by falling back to the full suite when selection is unavailable
|
|
161
|
+
or no tests are selected.
|
|
162
|
+
|
|
163
|
+
`qmind record build` reads Git metadata by default. Outside a git repository,
|
|
164
|
+
pass explicit metadata:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
qmind record build --commit "$BUILD_SHA" --branch "$BRANCH_NAME" --message "$BUILD_NAME"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`qmind record tests --results-dir` imports JUnit XML. CSV history import is not
|
|
171
|
+
supported yet.
|
|
172
|
+
|
|
173
|
+
## Project Observability
|
|
174
|
+
|
|
175
|
+
Prometheus is configured per project. The default flow is URL-only. Quantik
|
|
176
|
+
Mind connects to Prometheus, tries to auto-detect a supported metric preset,
|
|
177
|
+
and creates the project observability profile when detection succeeds.
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
qmind observability configure prometheus --url "http://prometheus:9090"
|
|
181
|
+
qmind observability status
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
If detection is partial, the CLI shows which preset signals were detected and
|
|
185
|
+
which were missing. Custom PromQL mapping is the advanced fallback:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
qmind observability configure prometheus --file prometheus-signals.yaml
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Supported runtime signal names are `error_rate`, `latency_p95`,
|
|
192
|
+
`request_rate`, and `cpu`/`cpu_load`.
|
|
193
|
+
|
|
194
|
+
Example:
|
|
195
|
+
|
|
196
|
+
```yaml
|
|
197
|
+
observability:
|
|
198
|
+
provider: prometheus
|
|
199
|
+
url: http://prometheus:9090
|
|
200
|
+
service_label: service
|
|
201
|
+
signals:
|
|
202
|
+
error_rate:
|
|
203
|
+
query: |
|
|
204
|
+
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
|
|
205
|
+
/
|
|
206
|
+
sum(rate(http_requests_total[5m])) by (service)
|
|
207
|
+
latency_p95:
|
|
208
|
+
query: |
|
|
209
|
+
histogram_quantile(
|
|
210
|
+
0.95,
|
|
211
|
+
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service)
|
|
212
|
+
)
|
|
213
|
+
request_rate:
|
|
214
|
+
query: |
|
|
215
|
+
sum(rate(http_requests_total[5m])) by (service)
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
`qmind status` reports runtime/observability as `not configured` until a
|
|
219
|
+
project-level Prometheus config or fresh project agent metrics are present.
|
|
220
|
+
|
|
221
|
+
## Test Runner Examples
|
|
222
|
+
|
|
223
|
+
### pytest
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
qmind record build
|
|
227
|
+
mkdir -p test-results
|
|
228
|
+
pytest $(qmind subset --framework pytest) --junitxml=test-results/junit.xml
|
|
229
|
+
qmind record tests --results-dir test-results
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### jest
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
qmind record build
|
|
236
|
+
mkdir -p test-results
|
|
237
|
+
npx jest $(qmind subset --framework jest) --ci --reporters=default --reporters=jest-junit
|
|
238
|
+
qmind record tests --results-dir test-results
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Configure `jest-junit` so it writes JUnit XML into `test-results`, for example
|
|
242
|
+
with `JEST_JUNIT_OUTPUT_DIR=test-results`.
|
|
243
|
+
|
|
244
|
+
### Maven
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
qmind record build
|
|
248
|
+
mvn test $(qmind subset --framework maven)
|
|
249
|
+
qmind record tests --results-dir target/surefire-reports
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Gradle
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
qmind record build
|
|
256
|
+
./gradlew test $(qmind subset --framework gradle)
|
|
257
|
+
qmind record tests --results-dir build/test-results
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## CI Examples
|
|
261
|
+
|
|
262
|
+
### GitHub Actions
|
|
263
|
+
|
|
264
|
+
Store `QMIND_API_KEY`, `QMIND_API_URL`, and `QMIND_PROJECT_ID` as repository or
|
|
265
|
+
environment secrets.
|
|
266
|
+
|
|
267
|
+
```yaml
|
|
268
|
+
name: qmind-tests
|
|
269
|
+
|
|
270
|
+
on:
|
|
271
|
+
push:
|
|
272
|
+
branches: [main]
|
|
273
|
+
pull_request:
|
|
274
|
+
|
|
275
|
+
jobs:
|
|
276
|
+
test:
|
|
277
|
+
runs-on: ubuntu-latest
|
|
278
|
+
env:
|
|
279
|
+
QMIND_API_KEY: ${{ secrets.QMIND_API_KEY }}
|
|
280
|
+
QMIND_API_URL: ${{ secrets.QMIND_API_URL }}
|
|
281
|
+
QMIND_PROJECT_ID: ${{ secrets.QMIND_PROJECT_ID }}
|
|
282
|
+
QMIND_FRAMEWORK: pytest
|
|
283
|
+
QMIND_TEST_DIR: tests
|
|
284
|
+
QMIND_RESULTS_DIR: test-results
|
|
285
|
+
steps:
|
|
286
|
+
- uses: actions/checkout@v4
|
|
287
|
+
|
|
288
|
+
- uses: actions/setup-python@v5
|
|
289
|
+
with:
|
|
290
|
+
python-version: "3.11"
|
|
291
|
+
|
|
292
|
+
- name: Install dependencies
|
|
293
|
+
run: |
|
|
294
|
+
pip install -e quantikmind-cli
|
|
295
|
+
pip install -r requirements.txt
|
|
296
|
+
|
|
297
|
+
- name: Configure Quantik Mind
|
|
298
|
+
run: qmind init --non-interactive
|
|
299
|
+
|
|
300
|
+
- name: Sync test library
|
|
301
|
+
run: qmind sync library
|
|
302
|
+
|
|
303
|
+
- name: Run selected tests
|
|
304
|
+
run: |
|
|
305
|
+
qmind record build
|
|
306
|
+
mkdir -p test-results
|
|
307
|
+
pytest $(qmind subset) --junitxml=test-results/junit.xml
|
|
308
|
+
qmind record tests --results-dir test-results
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### GitLab CI
|
|
312
|
+
|
|
313
|
+
Set `QMIND_API_KEY`, `QMIND_API_URL`, and `QMIND_PROJECT_ID` as protected CI/CD
|
|
314
|
+
variables.
|
|
315
|
+
|
|
316
|
+
```yaml
|
|
317
|
+
qmind_tests:
|
|
318
|
+
image: python:3.11
|
|
319
|
+
stage: test
|
|
320
|
+
variables:
|
|
321
|
+
QMIND_FRAMEWORK: pytest
|
|
322
|
+
QMIND_TEST_DIR: tests
|
|
323
|
+
QMIND_RESULTS_DIR: test-results
|
|
324
|
+
script:
|
|
325
|
+
- pip install -e quantikmind-cli
|
|
326
|
+
- pip install -r requirements.txt
|
|
327
|
+
- qmind init --non-interactive
|
|
328
|
+
- qmind sync library
|
|
329
|
+
- qmind record build
|
|
330
|
+
- mkdir -p test-results
|
|
331
|
+
- pytest $(qmind subset) --junitxml=test-results/junit.xml
|
|
332
|
+
- qmind record tests --results-dir test-results
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Jenkins
|
|
336
|
+
|
|
337
|
+
Store the API key in Jenkins credentials and provide the API URL and project ID
|
|
338
|
+
as environment variables or folder-level configuration.
|
|
339
|
+
|
|
340
|
+
```groovy
|
|
341
|
+
pipeline {
|
|
342
|
+
agent any
|
|
343
|
+
|
|
344
|
+
environment {
|
|
345
|
+
QMIND_API_URL = credentials('qmind-api-url')
|
|
346
|
+
QMIND_PROJECT_ID = credentials('qmind-project-id')
|
|
347
|
+
QMIND_FRAMEWORK = 'pytest'
|
|
348
|
+
QMIND_TEST_DIR = 'tests'
|
|
349
|
+
QMIND_RESULTS_DIR = 'test-results'
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
stages {
|
|
353
|
+
stage('Test') {
|
|
354
|
+
steps {
|
|
355
|
+
withCredentials([string(credentialsId: 'qmind-api-key', variable: 'QMIND_API_KEY')]) {
|
|
356
|
+
sh '''
|
|
357
|
+
pip install -e quantikmind-cli
|
|
358
|
+
pip install -r requirements.txt
|
|
359
|
+
qmind init --non-interactive
|
|
360
|
+
qmind sync library
|
|
361
|
+
qmind record build
|
|
362
|
+
mkdir -p test-results
|
|
363
|
+
pytest $(qmind subset) --junitxml=test-results/junit.xml
|
|
364
|
+
qmind record tests --results-dir test-results
|
|
365
|
+
'''
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## Runtime Signals Via Agent
|
|
374
|
+
|
|
375
|
+
The Prometheus agent runs inside the customer network. It reads local
|
|
376
|
+
Prometheus and pushes selected runtime metrics outbound to Quantik Mind over
|
|
377
|
+
HTTPS:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
qmind agent init --prometheus-url http://localhost:9090 --push-interval 30
|
|
381
|
+
qmind agent start
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
No inbound firewall rule is required for this agent flow. Quantik Mind reads
|
|
385
|
+
the agent-pushed metrics cache first. If the cache is empty, stale, or
|
|
386
|
+
unavailable, Quantik Mind falls back to direct Prometheus access when that
|
|
387
|
+
direct path has been configured separately.
|
|
388
|
+
|
|
389
|
+
`qmind agent start` is a foreground process. Run it under your existing process
|
|
390
|
+
supervisor if you need long-running behavior today. The CLI does not currently
|
|
391
|
+
install a systemd unit, launchd service, Docker container, or other daemon
|
|
392
|
+
wrapper.
|
|
393
|
+
|
|
394
|
+
## Command Reference
|
|
395
|
+
|
|
396
|
+
### `qmind init`
|
|
397
|
+
|
|
398
|
+
Creates repository configuration and stores local credentials.
|
|
399
|
+
|
|
400
|
+
Common options:
|
|
401
|
+
|
|
402
|
+
- `--api-key` or `QMIND_API_KEY`
|
|
403
|
+
- `--api-url` or `QMIND_API_URL`
|
|
404
|
+
- `--project-id` or `QMIND_PROJECT_ID`
|
|
405
|
+
- `--project-name` or `QMIND_PROJECT_NAME`
|
|
406
|
+
- `--framework` or `QMIND_FRAMEWORK`
|
|
407
|
+
- `--test-dir` or `QMIND_TEST_DIR`
|
|
408
|
+
- `--results-dir` or `QMIND_RESULTS_DIR`
|
|
409
|
+
- `--non-interactive`
|
|
410
|
+
|
|
411
|
+
### `qmind sync library`
|
|
412
|
+
|
|
413
|
+
Scans the configured test directory and uploads the functional test library.
|
|
414
|
+
Current scanner support includes `pytest`, `jest`, `maven`, `gradle`,
|
|
415
|
+
`cypress`, `playwright`, and `robot`.
|
|
416
|
+
|
|
417
|
+
Optional overrides:
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
qmind sync library --framework pytest --test-dir tests
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
For proprietary or non-discoverable enterprise test suites, manifest import is
|
|
424
|
+
the recommended path. This includes TestComplete projects, custom enterprise
|
|
425
|
+
runners, Selenium/Appium wrappers, legacy suites, and internal tools where
|
|
426
|
+
scanner discovery cannot reliably infer the complete inventory.
|
|
427
|
+
|
|
428
|
+
```bash
|
|
429
|
+
qmind sync library --manifest qmind-tests.yaml
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
The manifest may be YAML or JSON and uses the same upload path as scanner-based
|
|
433
|
+
sync. `qmind sync library --manifest ...` reads `project_id` and `api_url` from
|
|
434
|
+
`qmind.yaml`, loads credentials from `~/.qmind/credentials.yaml`, skips scanner
|
|
435
|
+
discovery, and uploads the declared tests.
|
|
436
|
+
|
|
437
|
+
Example TestComplete/custom runner manifest:
|
|
438
|
+
|
|
439
|
+
```yaml
|
|
440
|
+
tests:
|
|
441
|
+
- test_id: Login.ValidUser
|
|
442
|
+
name: Valid user login
|
|
443
|
+
framework: testcomplete
|
|
444
|
+
service: auth-service
|
|
445
|
+
suite: LoginSuite
|
|
446
|
+
business_criticality: critical
|
|
447
|
+
repo_ref:
|
|
448
|
+
selector: LoginSuite.ValidUser
|
|
449
|
+
path: TestComplete/LoginSuite
|
|
450
|
+
code_mapping:
|
|
451
|
+
file_globs:
|
|
452
|
+
- src/auth/**
|
|
453
|
+
tags:
|
|
454
|
+
- smoke
|
|
455
|
+
- login
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Required fields are `test_id`, `name`, `framework`, and `service`. Optional
|
|
459
|
+
fields are `suite`, `business_criticality`, `repo_ref`, `code_mapping`, `tags`,
|
|
460
|
+
and `metadata`. `suite` defaults to `default`; `business_criticality` defaults
|
|
461
|
+
to `medium` and must be one of `low`, `medium`, `high`, or `critical`.
|
|
462
|
+
`repo_ref`, `code_mapping`, and `tags` are preserved in the upload payload when
|
|
463
|
+
present. `metadata` is accepted in the manifest for forward compatibility but is
|
|
464
|
+
not uploaded because the current library upload contract does not document a
|
|
465
|
+
metadata field.
|
|
466
|
+
|
|
467
|
+
### `qmind record build`
|
|
468
|
+
|
|
469
|
+
Records the current git commit, message, author, and changed files for the
|
|
470
|
+
configured project.
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
qmind record build
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### `qmind subset`
|
|
477
|
+
|
|
478
|
+
Requests the selected tests and prints canonical `test_id` values to stdout.
|
|
479
|
+
Selection stats are printed to stderr so command substitution remains usable.
|
|
480
|
+
Use `--internal-ids` only when you explicitly need backend numeric IDs for
|
|
481
|
+
diagnostics.
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
pytest $(qmind subset --framework pytest)
|
|
485
|
+
mvn test $(qmind subset --framework maven)
|
|
486
|
+
./gradlew test $(qmind subset --framework gradle)
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Use `--json` when another tool needs the complete machine-readable selection
|
|
490
|
+
payload, including Dynamic Risk Intelligence metrics returned by the backend:
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
qmind subset --json
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Example:
|
|
497
|
+
|
|
498
|
+
```json
|
|
499
|
+
{
|
|
500
|
+
"selected_tests": [
|
|
501
|
+
"tests/test_checkout.py::test_checkout_pays",
|
|
502
|
+
"tests/test_checkout.py::TestInvoices::test_invoice_renders"
|
|
503
|
+
],
|
|
504
|
+
"business_metrics": {
|
|
505
|
+
"risk_coverage": 84.2,
|
|
506
|
+
"top_risk_coverage": 91.5,
|
|
507
|
+
"residual_risk": 15.8,
|
|
508
|
+
"risk_efficiency": 1.68
|
|
509
|
+
},
|
|
510
|
+
"risk_coverage": 84.2,
|
|
511
|
+
"risk_efficiency": 1.68
|
|
512
|
+
}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### `qmind record tests`
|
|
516
|
+
|
|
517
|
+
Imports JUnit XML test results.
|
|
518
|
+
|
|
519
|
+
```bash
|
|
520
|
+
qmind record tests --results-dir test-results
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
If `--results-dir` is omitted, the CLI uses `results_dir` from `qmind.yaml`.
|
|
524
|
+
History import requires each JUnit testcase to resolve to a `test_id` that was
|
|
525
|
+
already uploaded by `qmind sync library` or manifest import. The CLI normalizes
|
|
526
|
+
supported runner output to the scanner ID shape when the report preserves enough
|
|
527
|
+
identity:
|
|
528
|
+
|
|
529
|
+
- pytest dotted `classname` values such as `tests.test_login` plus
|
|
530
|
+
`name="test_valid_login"` become `tests/test_login.py::test_valid_login`.
|
|
531
|
+
- pytest class cases such as `tests.test_login.TestLogin` become
|
|
532
|
+
`tests/test_login.py::TestLogin::test_valid_login`.
|
|
533
|
+
- Maven/Gradle Surefire-style `classname="com.acme.InvoiceTest"` plus
|
|
534
|
+
`name="createsInvoice"` becomes `InvoiceTest.createsInvoice`.
|
|
535
|
+
- Cypress, Playwright, Jest, and Robot reports match scanner IDs when
|
|
536
|
+
`classname` or `file` contains the spec/test path, for example
|
|
537
|
+
`tests/checkout/payment.spec.ts::card payment succeeds`.
|
|
538
|
+
|
|
539
|
+
Generic JUnit XML that only contains a suite name and a testcase name remains
|
|
540
|
+
deterministic, but may not match scanner-generated IDs. Configure the runner's
|
|
541
|
+
JUnit reporter to include the file path or use a manifest with explicit
|
|
542
|
+
`test_id` values for custom runners.
|
|
543
|
+
|
|
544
|
+
### `qmind status`
|
|
545
|
+
|
|
546
|
+
Shows project configuration, API connectivity, signal readiness, selection
|
|
547
|
+
readiness, and subscription usage.
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
qmind status
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### `qmind agent init`
|
|
554
|
+
|
|
555
|
+
Validates local Prometheus connectivity, checks expected metric names, and
|
|
556
|
+
writes agent configuration into `qmind.yaml`.
|
|
557
|
+
|
|
558
|
+
```bash
|
|
559
|
+
qmind agent init --prometheus-url http://localhost:9090 --push-interval 30
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### `qmind agent start`
|
|
563
|
+
|
|
564
|
+
Starts the foreground metrics push loop.
|
|
565
|
+
|
|
566
|
+
```bash
|
|
567
|
+
qmind agent start
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
For a single collect-and-push cycle:
|
|
571
|
+
|
|
572
|
+
```bash
|
|
573
|
+
qmind agent start --once
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### `qmind agent status`
|
|
577
|
+
|
|
578
|
+
Shows local agent configuration and the last successful push recorded by the
|
|
579
|
+
CLI.
|
|
580
|
+
|
|
581
|
+
```bash
|
|
582
|
+
qmind agent status
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### `qmind agent stop`
|
|
586
|
+
|
|
587
|
+
`qmind agent stop` is present but does not manage a real daemon yet. Stop a
|
|
588
|
+
foreground `qmind agent start` process with `Ctrl+C` or through the external
|
|
589
|
+
process supervisor you used to launch it.
|
|
590
|
+
|
|
591
|
+
## Framework Support Matrix
|
|
592
|
+
|
|
593
|
+
| Capability | Current support |
|
|
594
|
+
| --- | --- |
|
|
595
|
+
| Test library scanner | `pytest`, `jest`, `maven`, `gradle`, `cypress`, `playwright`, `robot` |
|
|
596
|
+
| Subset argument formatting | `pytest`, `jest`, `maven`, `gradle`, `cypress`, `playwright`, `rspec`, `cucumber`, `robot` |
|
|
597
|
+
| Result import | JUnit XML with scanner-compatible IDs for pytest, Maven/Gradle Surefire, and path-preserving JS/Robot reporters; deterministic fallback for generic JUnit XML |
|
|
598
|
+
|
|
599
|
+
Selenium and Appium suites are typically covered through pytest, Maven, Gradle,
|
|
600
|
+
JUnit, or TestNG-style runners rather than native Selenium/Appium scanning.
|
|
601
|
+
TestComplete, proprietary runners, and non-discoverable enterprise tools should
|
|
602
|
+
use manifest import or JUnit-compatible reports; native scanners are not
|
|
603
|
+
implemented for those tools today.
|
|
604
|
+
|
|
605
|
+
## Security Notes
|
|
606
|
+
|
|
607
|
+
- API keys are stored in `~/.qmind/credentials.yaml`.
|
|
608
|
+
- API keys are not stored in `qmind.yaml`.
|
|
609
|
+
- `qmind.yaml` is repository-safe project configuration.
|
|
610
|
+
- The agent uses outbound HTTPS to push metrics to Quantik Mind.
|
|
611
|
+
- The agent flow does not require inbound access to the customer network.
|
|
612
|
+
- Tenant and project isolation is enforced server-side.
|
|
613
|
+
|
|
614
|
+
## Current Limitations
|
|
615
|
+
|
|
616
|
+
- Package publishing is not available yet; use `pip install -e .`.
|
|
617
|
+
- `qmind sync library` scans pytest, jest, Maven, Gradle, Cypress, Playwright,
|
|
618
|
+
and Robot Framework projects.
|
|
619
|
+
- JUnit XML is the current result import format.
|
|
620
|
+
- `qmind agent start` runs in the foreground and is not a service installer.
|
|
621
|
+
- `qmind agent stop` does not stop a managed daemon.
|
|
622
|
+
- Native TestComplete, Appium, Selenium, and proprietary runner scanners are not
|
|
623
|
+
implemented by this CLI release; use manifest import for those suites.
|
|
624
|
+
- Direct Prometheus fallback requires a separately configured direct path; the
|
|
625
|
+
local agent itself uses outbound HTTPS only.
|
|
626
|
+
|
|
627
|
+
## Troubleshooting
|
|
628
|
+
|
|
629
|
+
### Missing `qmind.yaml`
|
|
630
|
+
|
|
631
|
+
Run commands from the repository root after initialization:
|
|
632
|
+
|
|
633
|
+
```bash
|
|
634
|
+
qmind init
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### Missing Credentials
|
|
638
|
+
|
|
639
|
+
If credentials are missing or invalid, rerun initialization with a valid API
|
|
640
|
+
key:
|
|
641
|
+
|
|
642
|
+
```bash
|
|
643
|
+
qmind init --api-key "$QMIND_API_KEY"
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
Credentials are stored in `~/.qmind/credentials.yaml`.
|
|
647
|
+
|
|
648
|
+
### No Tests Found
|
|
649
|
+
|
|
650
|
+
Check that `framework` and `test_dir` in `qmind.yaml` match the repository:
|
|
651
|
+
|
|
652
|
+
```bash
|
|
653
|
+
qmind sync library --framework pytest --test-dir tests
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
Only pytest, jest, Maven, and Gradle scanning are implemented today.
|
|
657
|
+
|
|
658
|
+
### No Selected Tests
|
|
659
|
+
|
|
660
|
+
`qmind subset` exits with an error when Quantik Mind returns no selected tests.
|
|
661
|
+
Check `qmind status` for library and signal readiness. In CI, use an explicit
|
|
662
|
+
fallback to the full suite if that is your rollout policy.
|
|
663
|
+
|
|
664
|
+
### No JUnit Results Found
|
|
665
|
+
|
|
666
|
+
Confirm the runner writes JUnit XML into the directory passed to
|
|
667
|
+
`qmind record tests`:
|
|
668
|
+
|
|
669
|
+
```bash
|
|
670
|
+
pytest $(qmind subset) --junitxml=test-results/junit.xml
|
|
671
|
+
qmind record tests --results-dir test-results
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### Prometheus Unavailable
|
|
675
|
+
|
|
676
|
+
Verify Prometheus is reachable from the machine running the agent:
|
|
677
|
+
|
|
678
|
+
```bash
|
|
679
|
+
qmind agent init --prometheus-url http://localhost:9090 --push-interval 30
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
The command validates connectivity before saving agent settings.
|
|
683
|
+
|
|
684
|
+
### Agent Metrics Endpoint Unavailable
|
|
685
|
+
|
|
686
|
+
`qmind agent start` logs endpoint errors and backs off between retries. Confirm
|
|
687
|
+
the API URL, credentials, and backend deployment expose
|
|
688
|
+
`POST /api/v1/agent/metrics`.
|
|
689
|
+
|
|
690
|
+
### Weak Signal Readiness
|
|
691
|
+
|
|
692
|
+
`qmind status` may report partial or not-ready selection readiness when the
|
|
693
|
+
project has little historical or runtime signal. Sync the test library, record
|
|
694
|
+
builds, import JUnit XML results, and start the Prometheus agent to improve
|
|
695
|
+
signal coverage.
|