qa360 2.2.20 → 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
@@ -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
  }
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
package/core/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qa360-core",
3
- "version": "2.2.6",
3
+ "version": "2.3.0",
4
4
  "description": "QA360 Core Engine - Proof generation, signatures, and evidence vault",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -39,7 +39,13 @@
39
39
  "test:coverage": "vitest run --coverage",
40
40
  "test:watch": "vitest",
41
41
  "test:schema": "node src/proof/__tests__/schema-validation-manual.mjs",
42
- "clean": "rimraf dist"
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"
43
49
  },
44
50
  "dependencies": {
45
51
  "ajv": "^8.17.1",
@@ -55,9 +61,12 @@
55
61
  "devDependencies": {
56
62
  "@types/js-yaml": "^4.0.9",
57
63
  "@types/node": "^20.0.0",
64
+ "@types/pngjs": "^6.0.5",
58
65
  "@vitest/coverage-v8": "1.6.0",
66
+ "commander": "^12.0.0",
59
67
  "msw": "1",
60
68
  "playwright": "^1.57.0",
69
+ "pngjs": "^7.0.0",
61
70
  "vitest": "1.6.0"
62
71
  },
63
72
  "keywords": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qa360",
3
- "version": "2.2.20",
3
+ "version": "2.3.0",
4
4
  "description": "Transform software testing into verifiable, signed, and traceable proofs",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@9.12.2",