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 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
@@ -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
- * Crawls a website and generates a complete pack.yml with E2E tests
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
- * Crawls a website and generates a complete pack.yml with E2E tests
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('Crawl website and generate E2E test pack')
16
- .argument('<url>', 'Website URL to crawl')
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
- const spinner = ora('Initializing crawler...').start();
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('Crawling website...');
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. Run tests: ${chalk.cyan('qa360 run ' + (options.output || 'pack.yml'))}`));
104
- console.log(chalk.gray(` 3. Run in headed mode: ${chalk.cyan('qa360 run --headed ' + (options.output || 'pack.yml'))}`));
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
  }
@@ -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.2.18",
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.4"
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
+ }