qa360 2.2.18 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -0
- package/cli/CHANGELOG.md +84 -0
- package/cli/LICENSE +24 -0
- package/cli/dist/commands/crawl.d.ts +12 -1
- package/cli/dist/commands/crawl.js +69 -8
- package/cli/package.json +76 -0
- package/core/LICENSE +24 -0
- package/core/README.md +41 -0
- package/core/package.json +90 -0
- package/package.json +30 -23
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,74 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
## [2.3.0] - 2026-01-26
|
|
22
|
+
|
|
23
|
+
### 🎉 Enterprise Crawler Edition - P1 Complete (100%)
|
|
24
|
+
|
|
25
|
+
This release marks the completion of all P0 (Critical) and P1 (Important) features for the universal crawler. QA360 now provides enterprise-grade web testing capabilities with 50,000+ lines of production code.
|
|
26
|
+
|
|
27
|
+
### Added - Authentication (13 providers)
|
|
28
|
+
- **SAML 2.0 SSO**: Enterprise single sign-on with ForceAuthn/IsPassive support
|
|
29
|
+
- **WebAuthn / Passkeys**: FIDO2 passwordless authentication with platform authenticator
|
|
30
|
+
- **Remember Me**: Persistent session management with credential rotation
|
|
31
|
+
- **Digest Auth**: RFC 2617 digest authentication provider
|
|
32
|
+
- **OTP Provider**: SMS/Email OTP and Magic Links handling
|
|
33
|
+
- **Backup Codes**: Recovery codes for two-factor authentication
|
|
34
|
+
- **CAPTCHA Handlers**: reCAPTCHA v2/v3 and hCaptcha automation
|
|
35
|
+
- **OAuth2 Enhanced**: Implicit Flow, OpenID Connect, Refresh Token
|
|
36
|
+
- **TOTP**: Google Authenticator compatible time-based OTP
|
|
37
|
+
|
|
38
|
+
### Added - Crawler Core (15 new handlers)
|
|
39
|
+
- **Framework Wait Handler**: React, Vue, Angular, Svelte, SolidJS detection and smart waiting
|
|
40
|
+
- **Stacked Modals Handler**: Nested modal detection with z-index hierarchy analysis
|
|
41
|
+
- **REPL Debug Handler**: Interactive JavaScript REPL for test development
|
|
42
|
+
- **Blob URL Download Handler**: Handle downloads via createObjectURL
|
|
43
|
+
- **Email Testing Handler**: Mailhog, Mailtrap, Mailgun, SendGrid integration
|
|
44
|
+
- **Cookie Manager**: Cookie CRUD with security validation
|
|
45
|
+
- **CSP Handler**: Content Security Policy parsing and violation detection
|
|
46
|
+
- **COOP/COEP Handler**: Cross-origin isolation for SharedArrayBuffer
|
|
47
|
+
- **Permissions Policy Handler**: Feature policy and iframe allowlist management
|
|
48
|
+
- **Trusted Types Handler**: XSS prevention with Trusted Types API
|
|
49
|
+
- **Source Maps Handler**: Source map parsing and error mapping
|
|
50
|
+
- **Error Tracking Handler**: Global error capture and reporting
|
|
51
|
+
- **Reporting API Handler**: Reporting Observer for CSP violations
|
|
52
|
+
- **Geolocation Handler**: Geolocation API mocking and testing
|
|
53
|
+
- **Permissions Handler**: Browser permissions management
|
|
54
|
+
|
|
55
|
+
### Added - Upload & Network
|
|
56
|
+
- **Chunked Uploader**: Resumable chunked file uploads with progress tracking
|
|
57
|
+
- **Presigned URL Uploader**: S3/Azure cloud upload support
|
|
58
|
+
- **MIME Validator**: File type validation with magic number detection
|
|
59
|
+
- **Network Manager**: Advanced network control and monitoring
|
|
60
|
+
- **Network Simulator**: Offline, latency, and failure simulation
|
|
61
|
+
|
|
62
|
+
### Added - Test Infrastructure
|
|
63
|
+
- **Test Sharding**: Consistent hashing for parallel CI execution
|
|
64
|
+
- **Smart Retry Engine**: Fixed, linear, exponential, and adaptive strategies
|
|
65
|
+
- **Fixtures & Factories**: Test data generation with seeded random
|
|
66
|
+
- **State Reset**: Complete test isolation helpers
|
|
67
|
+
- **E2E Test Suite**: 32 comprehensive E2E tests on real websites
|
|
68
|
+
|
|
69
|
+
### Added - Security & Monitoring
|
|
70
|
+
- **Consent Handler**: GDPR/CCPA consent banner detection and handling
|
|
71
|
+
- **Advanced Interactions**: Shadow DOM piercing, iframes, multi-tab
|
|
72
|
+
- **Site Profiler**: Framework and CSS detection with adaptive strategies
|
|
73
|
+
- **Universal Presets**: 50+ platform-specific login presets
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
- **Test Coverage**: 2,439 tests passing (55 skipped) on Node 18, 20, 22
|
|
77
|
+
- **Documentation**: Complete crawler reference documentation
|
|
78
|
+
- **Type Safety**: Full TypeScript coverage with strict mode
|
|
79
|
+
|
|
80
|
+
### Metrics
|
|
81
|
+
- **P0 Features**: 75/75 (100% ✅)
|
|
82
|
+
- **P1 Features**: 118/118 (100% ✅)
|
|
83
|
+
- **Total Progress**: 185/278 (67%)
|
|
84
|
+
- **Code Lines**: ~50,000 lines of production code
|
|
85
|
+
- **Test Lines**: ~22,000 lines of E2E tests
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
21
89
|
## [2.2.6] - 2025-01-18
|
|
22
90
|
|
|
23
91
|
### Fixed
|
package/cli/CHANGELOG.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to QA360 Proof CLI will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.1.0] - 2025-10-26
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **AJV 2020-12 Support**: Full JSON Schema Draft 2020-12 validation (RFC-compliant)
|
|
12
|
+
- **CI Matrix**: 9-job validation matrix (3 OS × 3 Node versions)
|
|
13
|
+
- **Comprehensive Tests**: 11 unit tests + 3 smoke tests
|
|
14
|
+
- **Cross-platform Build**: Automated build script with OS detection
|
|
15
|
+
- **Dependency Lock**: Frozen AJV versions (anti-regression)
|
|
16
|
+
- **CI Badges**: Status badges in README
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- **Schema Validation**: Migrated from draft-07 to draft-2020-12
|
|
20
|
+
- **Build System**: Idempotent cross-platform build script
|
|
21
|
+
- **prepublishOnly**: Added doctor --strict validation before publish
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- **ESM Imports**: Fixed AJV 2020 import for Node.js ESM compatibility
|
|
25
|
+
- **Schema Path**: Corrected import paths in test files
|
|
26
|
+
|
|
27
|
+
### Security
|
|
28
|
+
- **Provenance**: Added npm provenance for supply chain security
|
|
29
|
+
- **Dependency Freeze**: Locked ajv@8.17.1, ajv-formats@2.1.1, ajv-draft-04@1.0.0
|
|
30
|
+
|
|
31
|
+
## [1.1.0-rc] - 2025-10-25
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **Initial Release Candidate**: First public release
|
|
35
|
+
- **Commands**: `doctor`, `verify`
|
|
36
|
+
- **Flags**: `--json`, `--strict`, `--verbose`
|
|
37
|
+
- **Documentation**: Complete guides and examples
|
|
38
|
+
|
|
39
|
+
### Features
|
|
40
|
+
- 🔒 **Local-first**: 100% offline, no network dependencies
|
|
41
|
+
- 🔐 **Cryptographic trust**: Ed25519 signatures, SHA-256 hashing
|
|
42
|
+
- 🌍 **Cross-OS**: Windows, macOS, Linux validated
|
|
43
|
+
- ⚡ **Zero friction**: Auto-generates keys
|
|
44
|
+
-
|
|
45
|
+
|
|
46
|
+
## [Unreleased]
|
|
47
|
+
|
|
48
|
+
### Planned
|
|
49
|
+
- RFC 3161 TSA timestamp support (Phase 6)
|
|
50
|
+
- W3C DID / Sigstore identity (Phase 6)
|
|
51
|
+
- Revocation mechanism (Phase 6)
|
|
52
|
+
- Compliance metadata (Phase 6)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Version History
|
|
57
|
+
|
|
58
|
+
- **1.1.0** (2025-10-26): Stable release with AJV 2020-12 + CI lockdown
|
|
59
|
+
- **1.1.0-rc** (2025-10-25): Release candidate
|
|
60
|
+
- **0.9.0-core** (2025-10-24): Internal development version
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Quick Validation
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Install
|
|
68
|
+
npm i -g @qa360/cli@1.1.0
|
|
69
|
+
|
|
70
|
+
# Verify version
|
|
71
|
+
qa360 --version
|
|
72
|
+
|
|
73
|
+
# System check
|
|
74
|
+
qa360 doctor --strict
|
|
75
|
+
|
|
76
|
+
# Verify proof
|
|
77
|
+
qa360 verify examples/proofs/httpbin-proof.json --json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Expected**: All commands succeed, proof validates correctly.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
For detailed changes, see [GitHub Releases](https://github.com/qa360/qa360/releases).
|
package/cli/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Licensor: XyqoTech
|
|
4
|
+
Licensed Work: QA360 Cloud Preview
|
|
5
|
+
Change Date: 2027-10-01
|
|
6
|
+
Change License: MIT
|
|
7
|
+
|
|
8
|
+
Terms
|
|
9
|
+
|
|
10
|
+
The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use.
|
|
11
|
+
|
|
12
|
+
Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the terms of the Change License, and the rights granted in the paragraph above terminate.
|
|
13
|
+
|
|
14
|
+
If your use of the Licensed Work does not comply with the requirements currently in effect as described in this License, you must purchase a commercial license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed Work.
|
|
15
|
+
|
|
16
|
+
All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for each version of the Licensed Work released by Licensor.
|
|
17
|
+
|
|
18
|
+
You must conspicuously display this License on each original or modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party, the terms and conditions set forth in this License apply to your use of that work.
|
|
19
|
+
|
|
20
|
+
Any use of the Licensed Work in violation of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Work.
|
|
21
|
+
|
|
22
|
+
This License does not grant you any right in any trademark or logo of Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License).
|
|
23
|
+
|
|
24
|
+
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* QA360 Crawl Command
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Universal crawler for all types of web applications.
|
|
5
|
+
* Supports presets for different platform types and custom auth/test data.
|
|
5
6
|
*/
|
|
6
7
|
import { Command } from 'commander';
|
|
7
8
|
/**
|
|
@@ -14,11 +15,21 @@ export declare function createCrawlCommand(): Command;
|
|
|
14
15
|
export declare function crawlCommand(url: string, options?: {
|
|
15
16
|
output?: string;
|
|
16
17
|
name?: string;
|
|
18
|
+
preset?: string;
|
|
19
|
+
listPresets?: boolean;
|
|
17
20
|
maxDepth?: string;
|
|
18
21
|
maxPages?: string;
|
|
19
22
|
headed?: boolean;
|
|
20
23
|
a11y?: boolean;
|
|
21
24
|
exclude?: string[];
|
|
25
|
+
only?: string[];
|
|
26
|
+
scenario?: string;
|
|
27
|
+
authEmail?: string;
|
|
28
|
+
authPassword?: string;
|
|
29
|
+
authUrl?: string;
|
|
30
|
+
testData?: string;
|
|
31
|
+
viewport?: string;
|
|
32
|
+
slowMo?: string;
|
|
22
33
|
quick?: boolean;
|
|
23
34
|
}): Promise<void>;
|
|
24
35
|
export default createCrawlCommand;
|
|
@@ -1,26 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* QA360 Crawl Command
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Universal crawler for all types of web applications.
|
|
5
|
+
* Supports presets for different platform types and custom auth/test data.
|
|
5
6
|
*/
|
|
6
7
|
import { Command } from 'commander';
|
|
7
8
|
import chalk from 'chalk';
|
|
8
9
|
import ora from 'ora';
|
|
9
10
|
import { generatePackFromCrawl, quickCrawl } from 'qa360-core';
|
|
11
|
+
import { detectPresetFromUrl, getAllPresets, getPreset, getPresetList } from 'qa360-core';
|
|
10
12
|
/**
|
|
11
13
|
* Create crawl command
|
|
12
14
|
*/
|
|
13
15
|
export function createCrawlCommand() {
|
|
14
16
|
const cmd = new Command('crawl')
|
|
15
|
-
.description('
|
|
16
|
-
.argument('
|
|
17
|
+
.description('Universal crawler - Generate E2E tests for ANY website')
|
|
18
|
+
.argument('[url]', 'Website URL to crawl (required unless --list-presets)')
|
|
17
19
|
.option('-o, --output <file>', 'Output pack file path', 'pack.yml')
|
|
18
20
|
.option('--name <name>', 'Pack name')
|
|
21
|
+
.option('--preset <type>', 'Platform preset (ecommerce, saas, social, booking, job, etc.)')
|
|
22
|
+
.option('--list-presets', 'List all available presets')
|
|
19
23
|
.option('--max-depth <number>', 'Maximum crawl depth', '2')
|
|
20
24
|
.option('--max-pages <number>', 'Maximum pages to crawl', '20')
|
|
21
25
|
.option('--headed', 'Run crawler in headed mode (visible browser)')
|
|
22
26
|
.option('--a11y', 'Include accessibility tests')
|
|
23
27
|
.option('--exclude <patterns...>', 'URL patterns to exclude')
|
|
28
|
+
.option('--only <patterns...>', 'Only crawl URLs matching these patterns')
|
|
29
|
+
.option('--scenario <type>', 'Focus on specific scenario (login, checkout, etc.)')
|
|
30
|
+
.option('--auth-email <email>', 'Email for auto-authentication')
|
|
31
|
+
.option('--auth-password <password>', 'Password for auto-authentication')
|
|
32
|
+
.option('--auth-url <path>', 'Login page URL (default: auto-detect)')
|
|
33
|
+
.option('--test-data <json>', 'Test data as JSON string')
|
|
34
|
+
.option('--viewport <size>', 'Browser viewport size (default: 1280x720)')
|
|
35
|
+
.option('--slow-mo <ms>', 'Slow down actions by ms (for debugging)')
|
|
24
36
|
.option('--quick', 'Quick crawl (depth=1, max-pages=10)')
|
|
25
37
|
.action(async (url, options) => {
|
|
26
38
|
await crawlCommand(url, options);
|
|
@@ -31,10 +43,36 @@ export function createCrawlCommand() {
|
|
|
31
43
|
* Crawl command handler
|
|
32
44
|
*/
|
|
33
45
|
export async function crawlCommand(url, options = {}) {
|
|
34
|
-
|
|
46
|
+
// Handle --list-presets
|
|
47
|
+
if (options.listPresets) {
|
|
48
|
+
console.log(getPresetList());
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Validate URL is provided when not listing presets
|
|
52
|
+
if (!url) {
|
|
53
|
+
console.error(chalk.red('Error: URL is required when not using --list-presets'));
|
|
54
|
+
console.log(chalk.yellow('\nUsage: qa360 crawl <url> [options]'));
|
|
55
|
+
console.log(chalk.gray('Example: qa360 crawl https://example.com'));
|
|
56
|
+
console.log(chalk.gray('\nRun "qa360 crawl --list-presets" to see all platform types'));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const spinner = ora('Initializing universal crawler...').start();
|
|
35
60
|
try {
|
|
36
61
|
// Validate URL
|
|
37
62
|
new URL(url);
|
|
63
|
+
// Determine preset
|
|
64
|
+
let preset = options.preset ? getPreset(options.preset) : detectPresetFromUrl(url);
|
|
65
|
+
if (!preset && !options.preset) {
|
|
66
|
+
spinner.info('No preset specified, using generic preset');
|
|
67
|
+
preset = getAllPresets().find(p => p.id === 'generic');
|
|
68
|
+
}
|
|
69
|
+
else if (options.preset && !preset) {
|
|
70
|
+
spinner.warn(`Preset "${options.preset}" not found, using generic`);
|
|
71
|
+
preset = getAllPresets().find(p => p.id === 'generic');
|
|
72
|
+
}
|
|
73
|
+
if (preset) {
|
|
74
|
+
spinner.text = `Crawling with preset: ${preset.name}`;
|
|
75
|
+
}
|
|
38
76
|
if (options.quick) {
|
|
39
77
|
spinner.info('Running quick crawl...');
|
|
40
78
|
const result = await quickCrawl(url, options.output);
|
|
@@ -51,19 +89,32 @@ export async function crawlCommand(url, options = {}) {
|
|
|
51
89
|
console.error(chalk.red(result.error));
|
|
52
90
|
return;
|
|
53
91
|
}
|
|
54
|
-
// Full crawl
|
|
55
|
-
spinner.info(
|
|
92
|
+
// Full crawl with preset support
|
|
93
|
+
spinner.info(`Crawling ${url}...`);
|
|
94
|
+
if (preset) {
|
|
95
|
+
spinner.text = `Using preset: ${preset.name}`;
|
|
96
|
+
}
|
|
97
|
+
// Build crawl options with preset data
|
|
56
98
|
const crawlOptions = {
|
|
57
99
|
baseUrl: url,
|
|
58
100
|
output: options.output,
|
|
59
101
|
packName: options.name,
|
|
60
102
|
includeA11y: options.a11y,
|
|
103
|
+
preset,
|
|
61
104
|
crawl: {
|
|
62
105
|
maxDepth: options.quick ? 1 : parseInt(options.maxDepth || '2', 10),
|
|
63
106
|
maxPages: options.quick ? 10 : parseInt(options.maxPages || '20', 10),
|
|
64
107
|
headless: !options.headed,
|
|
65
108
|
excludePatterns: options.exclude,
|
|
109
|
+
onlyPatterns: options.only,
|
|
66
110
|
},
|
|
111
|
+
auth: (options.authEmail || options.authPassword) ? {
|
|
112
|
+
email: options.authEmail,
|
|
113
|
+
password: options.authPassword,
|
|
114
|
+
// Only set URL if explicitly provided - otherwise let crawler intelligently detect the login page
|
|
115
|
+
...(options.authUrl && { url: options.authUrl })
|
|
116
|
+
} : undefined,
|
|
117
|
+
scenario: options.scenario,
|
|
67
118
|
};
|
|
68
119
|
const result = await generatePackFromCrawl(crawlOptions);
|
|
69
120
|
if (result.success) {
|
|
@@ -79,6 +130,14 @@ export async function crawlCommand(url, options = {}) {
|
|
|
79
130
|
if (siteMap.metadata.avgLoadTime) {
|
|
80
131
|
console.log(` Avg page load: ${chalk.gray(siteMap.metadata.avgLoadTime + 'ms')}`);
|
|
81
132
|
}
|
|
133
|
+
// Show preset info
|
|
134
|
+
if (preset) {
|
|
135
|
+
console.log(chalk.bold('\n Platform Type:'));
|
|
136
|
+
console.log(` ${chalk.cyan(preset.name)} - ${preset.description}`);
|
|
137
|
+
if (preset.scenarios && preset.scenarios.length > 0) {
|
|
138
|
+
console.log(chalk.gray(' Scenarios:'), preset.scenarios.slice(0, 4).join(', '));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
82
141
|
// Show journeys
|
|
83
142
|
if (userJourneys.length > 0) {
|
|
84
143
|
console.log(chalk.bold('\n Generated Journeys:'));
|
|
@@ -100,8 +159,9 @@ export async function crawlCommand(url, options = {}) {
|
|
|
100
159
|
console.log(chalk.bold('\n✅ Crawl complete!'));
|
|
101
160
|
console.log(chalk.gray(`\nNext steps:`));
|
|
102
161
|
console.log(chalk.gray(` 1. Review the generated pack: ${chalk.cyan(options.output || 'pack.yml')}`));
|
|
103
|
-
console.log(chalk.gray(` 2.
|
|
104
|
-
console.log(chalk.gray(` 3. Run
|
|
162
|
+
console.log(chalk.gray(` 2. Edit test data if needed (credentials, payment info, etc.)`));
|
|
163
|
+
console.log(chalk.gray(` 3. Run tests: ${chalk.cyan('qa360 run ' + (options.output || 'pack.yml'))}`));
|
|
164
|
+
console.log(chalk.gray(` 4. Run in headed mode: ${chalk.cyan('qa360 run --headed ' + (options.output || 'pack.yml'))}`));
|
|
105
165
|
}
|
|
106
166
|
else {
|
|
107
167
|
spinner.fail('Crawl failed');
|
|
@@ -115,6 +175,7 @@ export async function crawlCommand(url, options = {}) {
|
|
|
115
175
|
if (error instanceof Error && error.message.includes('URL')) {
|
|
116
176
|
console.log(chalk.yellow('\nUsage: qa360 crawl <url> [options]'));
|
|
117
177
|
console.log(chalk.gray('Example: qa360 crawl https://example.com'));
|
|
178
|
+
console.log(chalk.gray('\nRun "qa360 crawl --list-presets" to see all platform types'));
|
|
118
179
|
}
|
|
119
180
|
}
|
|
120
181
|
}
|
package/cli/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "qa360",
|
|
3
|
+
"version": "2.2.15",
|
|
4
|
+
"description": "QA360 Proof CLI - Quality as Cryptographic Proof",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"qa360": "bin/qa360.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"bin",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
"examples"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc --project tsconfig.bundle.json",
|
|
20
|
+
"build:pkg": "tsc",
|
|
21
|
+
"build:bundle": "bash scripts/bundle-for-npm.sh",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:coverage": "vitest run --coverage",
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"dev": "tsx watch src/index.ts",
|
|
26
|
+
"clean": "rimraf dist src/core",
|
|
27
|
+
"prepack": "node scripts/validate-package.js",
|
|
28
|
+
"prepublishOnly": "npm run build:bundle && sed -i.bak 's/\"qa360-core\": \"workspace:\\*\",//g' package.json && rm -f package.json.bak",
|
|
29
|
+
"postpublish": "git checkout package.json 2>/dev/null || true",
|
|
30
|
+
"publish:dry": "npm run build:bundle && sed -i.bak 's/\"qa360-core\": \"workspace:\\*\",//g' package.json && npm publish --dry-run; git checkout package.json",
|
|
31
|
+
"publish:real": "npm run build:bundle && npm publish --access public --provenance"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@playwright/test": "^1.49.0",
|
|
35
|
+
"adm-zip": "^0.5.16",
|
|
36
|
+
"ajv": "^8.17.1",
|
|
37
|
+
"ajv-draft-04": "^1.0.0",
|
|
38
|
+
"ajv-formats": "^2.1.1",
|
|
39
|
+
"chalk": "^4.1.2",
|
|
40
|
+
"cli-table3": "^0.6.5",
|
|
41
|
+
"commander": "^11.0.0",
|
|
42
|
+
"glob": "^10.4.5",
|
|
43
|
+
"inquirer": "^8.2.7",
|
|
44
|
+
"js-yaml": "^4.1.0",
|
|
45
|
+
"ollama": "^0.5.1",
|
|
46
|
+
"ora": "^5.4.1",
|
|
47
|
+
"playwright": "^1.57.0",
|
|
48
|
+
"qa360-core": "workspace:*",
|
|
49
|
+
"sqlite3": "^5.1.6",
|
|
50
|
+
"tweetnacl": "^1.0.3"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/adm-zip": "^0.5.7",
|
|
54
|
+
"@types/inquirer": "^9.0.9",
|
|
55
|
+
"@vitest/coverage-v8": "1.6.0",
|
|
56
|
+
"tsx": "^4.0.0",
|
|
57
|
+
"vitest": "1.6.0"
|
|
58
|
+
},
|
|
59
|
+
"keywords": [
|
|
60
|
+
"qa360",
|
|
61
|
+
"cli",
|
|
62
|
+
"testing",
|
|
63
|
+
"proof"
|
|
64
|
+
],
|
|
65
|
+
"author": "QA360 Core Team",
|
|
66
|
+
"license": "MIT",
|
|
67
|
+
"repository": {
|
|
68
|
+
"type": "git",
|
|
69
|
+
"url": "https://github.com/xyqotech/qa360.git",
|
|
70
|
+
"directory": "cli"
|
|
71
|
+
},
|
|
72
|
+
"homepage": "https://github.com/xyqotech/qa360",
|
|
73
|
+
"bugs": {
|
|
74
|
+
"url": "https://github.com/xyqotech/qa360/issues"
|
|
75
|
+
}
|
|
76
|
+
}
|
package/core/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Licensor: XyqoTech
|
|
4
|
+
Licensed Work: QA360 Cloud Preview
|
|
5
|
+
Change Date: 2027-10-01
|
|
6
|
+
Change License: MIT
|
|
7
|
+
|
|
8
|
+
Terms
|
|
9
|
+
|
|
10
|
+
The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use.
|
|
11
|
+
|
|
12
|
+
Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the terms of the Change License, and the rights granted in the paragraph above terminate.
|
|
13
|
+
|
|
14
|
+
If your use of the Licensed Work does not comply with the requirements currently in effect as described in this License, you must purchase a commercial license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed Work.
|
|
15
|
+
|
|
16
|
+
All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for each version of the Licensed Work released by Licensor.
|
|
17
|
+
|
|
18
|
+
You must conspicuously display this License on each original or modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party, the terms and conditions set forth in this License apply to your use of that work.
|
|
19
|
+
|
|
20
|
+
Any use of the Licensed Work in violation of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Work.
|
|
21
|
+
|
|
22
|
+
This License does not grant you any right in any trademark or logo of Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License).
|
|
23
|
+
|
|
24
|
+
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
|
package/core/README.md
CHANGED
|
@@ -62,3 +62,44 @@ npm install
|
|
|
62
62
|
npm run build
|
|
63
63
|
npm test
|
|
64
64
|
```
|
|
65
|
+
|
|
66
|
+
## Browser Management
|
|
67
|
+
|
|
68
|
+
QA360 uses Playwright for browser automation. By default, Chromium is bundled and ready to use.
|
|
69
|
+
|
|
70
|
+
### Check Browser Availability
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pnpm browsers:check
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Install Browsers
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Install Chromium (usually pre-installed)
|
|
80
|
+
pnpm browsers:install:chromium
|
|
81
|
+
|
|
82
|
+
# Install Firefox
|
|
83
|
+
pnpm browsers:install:firefox
|
|
84
|
+
|
|
85
|
+
# Install WebKit
|
|
86
|
+
pnpm browsers:install:webkit
|
|
87
|
+
|
|
88
|
+
# Install all browsers
|
|
89
|
+
pnpm browsers:install:all
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Graceful Test Skipping
|
|
93
|
+
|
|
94
|
+
Tests automatically skip if a required browser is not installed:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
⚠️ firefox is optional and not installed. Install with: npx playwright install firefox
|
|
98
|
+
⊘ Firefox Browser E2E > should launch Firefox browser ... Skipped
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Documentation
|
|
102
|
+
|
|
103
|
+
- [Browser Support](../docs/reference/BROWSER_SUPPORT.md) - Complete browser management guide
|
|
104
|
+
- [Multi-Browser Strategy](../docs/reference/MULTI_BROWSER_STRATEGY.md) - Cross-browser testing approach
|
|
105
|
+
- [CHECKLIST_VALIDATION](../docs/strategy/CHECKLIST_VALIDATION.md) - Feature coverage matrix
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "qa360-core",
|
|
3
|
+
"version": "2.3.0",
|
|
4
|
+
"description": "QA360 Core Engine - Proof generation, signatures, and evidence vault",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./proof": {
|
|
14
|
+
"types": "./dist/proof/index.d.ts",
|
|
15
|
+
"import": "./dist/proof/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./pack/validator": {
|
|
18
|
+
"types": "./dist/pack/validator.d.ts",
|
|
19
|
+
"import": "./dist/pack/validator.js"
|
|
20
|
+
},
|
|
21
|
+
"./pack/migrator": {
|
|
22
|
+
"types": "./dist/pack/migrator.d.ts",
|
|
23
|
+
"import": "./dist/pack/migrator.js"
|
|
24
|
+
},
|
|
25
|
+
"./types/pack-v1": {
|
|
26
|
+
"types": "./dist/types/pack-v1.d.ts",
|
|
27
|
+
"import": "./dist/types/pack-v1.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -b",
|
|
37
|
+
"build:pkg": "tsc",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"test:coverage": "vitest run --coverage",
|
|
40
|
+
"test:watch": "vitest",
|
|
41
|
+
"test:schema": "node src/proof/__tests__/schema-validation-manual.mjs",
|
|
42
|
+
"clean": "rimraf dist",
|
|
43
|
+
"browsers:install": "node scripts/install-browsers.ts",
|
|
44
|
+
"browsers:install:chromium": "node scripts/install-browsers.ts chromium",
|
|
45
|
+
"browsers:install:firefox": "node scripts/install-browsers.ts firefox",
|
|
46
|
+
"browsers:install:webkit": "node scripts/install-browsers.ts webkit",
|
|
47
|
+
"browsers:install:all": "node scripts/install-browsers.ts all",
|
|
48
|
+
"browsers:check": "node scripts/install-browsers.ts --check"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"ajv": "^8.17.1",
|
|
52
|
+
"ajv-draft-04": "^1.0.0",
|
|
53
|
+
"ajv-formats": "^2.1.1",
|
|
54
|
+
"chalk": "^4.1.2",
|
|
55
|
+
"glob": "^10.4.5",
|
|
56
|
+
"js-yaml": "^4.1.0",
|
|
57
|
+
"ollama": "^0.5.1",
|
|
58
|
+
"sqlite3": "^5.1.6",
|
|
59
|
+
"tweetnacl": "^1.0.3"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/js-yaml": "^4.0.9",
|
|
63
|
+
"@types/node": "^20.0.0",
|
|
64
|
+
"@types/pngjs": "^6.0.5",
|
|
65
|
+
"@vitest/coverage-v8": "1.6.0",
|
|
66
|
+
"commander": "^12.0.0",
|
|
67
|
+
"msw": "1",
|
|
68
|
+
"playwright": "^1.57.0",
|
|
69
|
+
"pngjs": "^7.0.0",
|
|
70
|
+
"vitest": "1.6.0"
|
|
71
|
+
},
|
|
72
|
+
"keywords": [
|
|
73
|
+
"qa360",
|
|
74
|
+
"core",
|
|
75
|
+
"proof",
|
|
76
|
+
"signature",
|
|
77
|
+
"vault"
|
|
78
|
+
],
|
|
79
|
+
"author": "QA360 Core Team",
|
|
80
|
+
"license": "MIT",
|
|
81
|
+
"repository": {
|
|
82
|
+
"type": "git",
|
|
83
|
+
"url": "https://github.com/xyqotech/qa360.git",
|
|
84
|
+
"directory": "core"
|
|
85
|
+
},
|
|
86
|
+
"homepage": "https://github.com/xyqotech/qa360",
|
|
87
|
+
"bugs": {
|
|
88
|
+
"url": "https://github.com/xyqotech/qa360/issues"
|
|
89
|
+
}
|
|
90
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qa360",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Transform software testing into verifiable, signed, and traceable proofs",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"packageManager": "pnpm@9.12.2",
|
|
6
7
|
"engines": {
|
|
7
8
|
"node": ">=18.20.0"
|
|
8
9
|
},
|
|
@@ -23,11 +24,37 @@
|
|
|
23
24
|
"QUICK_START.md",
|
|
24
25
|
"package.json"
|
|
25
26
|
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc --build tsconfig.build.json",
|
|
29
|
+
"build:pkg": "tsc",
|
|
30
|
+
"docs": "typedoc --skipErrorChecking",
|
|
31
|
+
"docs:serve": "typedoc --skipErrorChecking --serve",
|
|
32
|
+
"test": "pnpm -r run test",
|
|
33
|
+
"test:core": "cd core && pnpm test",
|
|
34
|
+
"test:cli": "cd cli && pnpm test",
|
|
35
|
+
"test:e2e": "vitest run --config e2e/vitest.config.ts",
|
|
36
|
+
"test:examples": "node scripts/validate-examples.mjs",
|
|
37
|
+
"test:all": "npm run type-check && npm run test && npm run test:examples",
|
|
38
|
+
"lint": "eslint . --ext .ts,.js",
|
|
39
|
+
"lint:fix": "eslint . --ext .ts,.js --fix",
|
|
40
|
+
"type-check": "tsc --build tsconfig.build.json --force",
|
|
41
|
+
"dev": "tsx watch cli/src/index.ts",
|
|
42
|
+
"clean": "rm -rf dist/ */dist/ **/dist/",
|
|
43
|
+
"clean:all": "pnpm clean && find . -name '.tmp-test-*' -type d -exec rm -rf {} + 2>/dev/null; find . -name '.qa360' -type d -exec rm -rf {} + 2>/dev/null; find . -name '*.tsbuildinfo' -delete 2>/dev/null; echo 'All artifacts cleaned'",
|
|
44
|
+
"version:sync": "node scripts/sync-version.mjs",
|
|
45
|
+
"prepare": "husky install",
|
|
46
|
+
"install:mcp": "bash scripts/install-mcp.sh"
|
|
47
|
+
},
|
|
26
48
|
"workspaces": [
|
|
27
49
|
"cli",
|
|
28
50
|
"core",
|
|
29
51
|
"packages/*"
|
|
30
52
|
],
|
|
53
|
+
"pnpm": {
|
|
54
|
+
"overrides": {
|
|
55
|
+
"ajv": "^8.17.1"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
31
58
|
"dependencies": {
|
|
32
59
|
"@playwright/test": "^1.49.0",
|
|
33
60
|
"adm-zip": "^0.5.16",
|
|
@@ -46,7 +73,7 @@
|
|
|
46
73
|
"sqlite3": "^5.1.6",
|
|
47
74
|
"table": "^6.9.0",
|
|
48
75
|
"tweetnacl": "^1.0.3",
|
|
49
|
-
"qa360-core": "^2.2.
|
|
76
|
+
"qa360-core": "^2.2.6"
|
|
50
77
|
},
|
|
51
78
|
"devDependencies": {
|
|
52
79
|
"@playwright/test": "^1.56.1",
|
|
@@ -81,25 +108,5 @@
|
|
|
81
108
|
"homepage": "https://qa360.dev",
|
|
82
109
|
"bugs": {
|
|
83
110
|
"url": "https://github.com/xyqotech/qa360/issues"
|
|
84
|
-
},
|
|
85
|
-
"scripts": {
|
|
86
|
-
"build": "tsc --build tsconfig.build.json",
|
|
87
|
-
"build:pkg": "tsc",
|
|
88
|
-
"docs": "typedoc --skipErrorChecking",
|
|
89
|
-
"docs:serve": "typedoc --skipErrorChecking --serve",
|
|
90
|
-
"test": "pnpm -r run test",
|
|
91
|
-
"test:core": "cd core && pnpm test",
|
|
92
|
-
"test:cli": "cd cli && pnpm test",
|
|
93
|
-
"test:e2e": "vitest run --config e2e/vitest.config.ts",
|
|
94
|
-
"test:examples": "node scripts/validate-examples.mjs",
|
|
95
|
-
"test:all": "npm run type-check && npm run test && npm run test:examples",
|
|
96
|
-
"lint": "eslint . --ext .ts,.js",
|
|
97
|
-
"lint:fix": "eslint . --ext .ts,.js --fix",
|
|
98
|
-
"type-check": "tsc --build tsconfig.build.json --force",
|
|
99
|
-
"dev": "tsx watch cli/src/index.ts",
|
|
100
|
-
"clean": "rm -rf dist/ */dist/ **/dist/",
|
|
101
|
-
"clean:all": "pnpm clean && find . -name '.tmp-test-*' -type d -exec rm -rf {} + 2>/dev/null; find . -name '.qa360' -type d -exec rm -rf {} + 2>/dev/null; find . -name '*.tsbuildinfo' -delete 2>/dev/null; echo 'All artifacts cleaned'",
|
|
102
|
-
"version:sync": "node scripts/sync-version.mjs",
|
|
103
|
-
"install:mcp": "bash scripts/install-mcp.sh"
|
|
104
111
|
}
|
|
105
|
-
}
|
|
112
|
+
}
|