@memberjunction/react-test-harness 2.70.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/README.md +735 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +250 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/assertion-helpers.d.ts +37 -0
- package/dist/lib/assertion-helpers.d.ts.map +1 -0
- package/dist/lib/assertion-helpers.js +108 -0
- package/dist/lib/assertion-helpers.js.map +1 -0
- package/dist/lib/browser-context.d.ts +33 -0
- package/dist/lib/browser-context.d.ts.map +1 -0
- package/dist/lib/browser-context.js +83 -0
- package/dist/lib/browser-context.js.map +1 -0
- package/dist/lib/component-runner.d.ts +38 -0
- package/dist/lib/component-runner.d.ts.map +1 -0
- package/dist/lib/component-runner.js +177 -0
- package/dist/lib/component-runner.js.map +1 -0
- package/dist/lib/test-harness.d.ts +55 -0
- package/dist/lib/test-harness.d.ts.map +1 -0
- package/dist/lib/test-harness.js +185 -0
- package/dist/lib/test-harness.js.map +1 -0
- package/package.json +32 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
20
|
+
if (mod && mod.__esModule) return mod;
|
|
21
|
+
var result = {};
|
|
22
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
23
|
+
__setModuleDefault(result, mod);
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
27
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
const commander_1 = require("commander");
|
|
31
|
+
const path = __importStar(require("path"));
|
|
32
|
+
const fs = __importStar(require("fs"));
|
|
33
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
34
|
+
const ora_1 = __importDefault(require("ora"));
|
|
35
|
+
const test_harness_1 = require("../lib/test-harness");
|
|
36
|
+
const program = new commander_1.Command();
|
|
37
|
+
program
|
|
38
|
+
.name('mj-react-test')
|
|
39
|
+
.description('React component test harness for MemberJunction')
|
|
40
|
+
.version('2.69.1');
|
|
41
|
+
program
|
|
42
|
+
.command('run <componentFile>')
|
|
43
|
+
.description('Run a React component test')
|
|
44
|
+
.option('-p, --props <json>', 'Component props as JSON string')
|
|
45
|
+
.option('-s, --selector <selector>', 'Wait for selector before capturing')
|
|
46
|
+
.option('-t, --timeout <ms>', 'Timeout in milliseconds', '30000')
|
|
47
|
+
.option('--headless', 'Run in headless mode (default)', true)
|
|
48
|
+
.option('--headed', 'Run in headed mode (visible browser)')
|
|
49
|
+
.option('--screenshot <path>', 'Save screenshot to path')
|
|
50
|
+
.option('--debug', 'Enable debug output')
|
|
51
|
+
.action(async (componentFile, options) => {
|
|
52
|
+
const spinner = (0, ora_1.default)('Initializing test harness...').start();
|
|
53
|
+
try {
|
|
54
|
+
// Parse props if provided
|
|
55
|
+
let props = {};
|
|
56
|
+
if (options.props) {
|
|
57
|
+
try {
|
|
58
|
+
props = JSON.parse(options.props);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
spinner.fail(chalk_1.default.red('Invalid JSON in props parameter'));
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Create test harness
|
|
66
|
+
const harness = new test_harness_1.ReactTestHarness({
|
|
67
|
+
headless: !options.headed,
|
|
68
|
+
debug: options.debug,
|
|
69
|
+
screenshotPath: options.screenshot
|
|
70
|
+
});
|
|
71
|
+
spinner.text = 'Starting browser...';
|
|
72
|
+
await harness.initialize();
|
|
73
|
+
spinner.text = 'Loading component...';
|
|
74
|
+
const result = await harness.testComponentFromFile(componentFile, props, {
|
|
75
|
+
waitForSelector: options.selector,
|
|
76
|
+
timeout: parseInt(options.timeout)
|
|
77
|
+
});
|
|
78
|
+
spinner.stop();
|
|
79
|
+
if (result.success) {
|
|
80
|
+
console.log(chalk_1.default.green('✓ Component rendered successfully'));
|
|
81
|
+
if (options.debug) {
|
|
82
|
+
console.log('\n' + chalk_1.default.bold('Console Output:'));
|
|
83
|
+
result.console.forEach(log => {
|
|
84
|
+
const color = log.type === 'error' ? chalk_1.default.red :
|
|
85
|
+
log.type === 'warning' ? chalk_1.default.yellow :
|
|
86
|
+
chalk_1.default.gray;
|
|
87
|
+
console.log(color(`[${log.type}] ${log.text}`));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (options.screenshot && result.screenshot) {
|
|
91
|
+
fs.writeFileSync(options.screenshot, result.screenshot);
|
|
92
|
+
console.log(chalk_1.default.blue(`Screenshot saved to: ${options.screenshot}`));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
console.log(chalk_1.default.red('✗ Component rendering failed'));
|
|
97
|
+
console.log(chalk_1.default.red('\nErrors:'));
|
|
98
|
+
result.errors.forEach(error => {
|
|
99
|
+
console.log(chalk_1.default.red(` - ${error}`));
|
|
100
|
+
});
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
await harness.close();
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
spinner.fail(chalk_1.default.red('Test execution failed'));
|
|
107
|
+
console.error(error);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
program
|
|
112
|
+
.command('test <testFile>')
|
|
113
|
+
.description('Run a test file with multiple test cases')
|
|
114
|
+
.option('--headless', 'Run in headless mode (default)', true)
|
|
115
|
+
.option('--headed', 'Run in headed mode (visible browser)')
|
|
116
|
+
.option('--debug', 'Enable debug output')
|
|
117
|
+
.action(async (testFile, options) => {
|
|
118
|
+
const spinner = (0, ora_1.default)('Loading test file...').start();
|
|
119
|
+
try {
|
|
120
|
+
const testPath = path.resolve(testFile);
|
|
121
|
+
if (!fs.existsSync(testPath)) {
|
|
122
|
+
spinner.fail(chalk_1.default.red(`Test file not found: ${testPath}`));
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
// Import the test file
|
|
126
|
+
const testModule = await Promise.resolve(`${testPath}`).then(s => __importStar(require(s)));
|
|
127
|
+
if (!testModule.default || typeof testModule.default !== 'function') {
|
|
128
|
+
spinner.fail(chalk_1.default.red('Test file must export a default function'));
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
spinner.text = 'Running tests...';
|
|
132
|
+
// Create harness with options
|
|
133
|
+
const harness = new test_harness_1.ReactTestHarness({
|
|
134
|
+
headless: !options.headed,
|
|
135
|
+
debug: options.debug
|
|
136
|
+
});
|
|
137
|
+
// Run the test function - add AssertionHelpers to harness for test functions
|
|
138
|
+
const harnessWithHelpers = Object.assign(harness, {
|
|
139
|
+
AssertionHelpers: harness.getAssertionHelpers()
|
|
140
|
+
});
|
|
141
|
+
await testModule.default(harnessWithHelpers);
|
|
142
|
+
spinner.succeed(chalk_1.default.green('All tests completed'));
|
|
143
|
+
await harness.close();
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
spinner.fail(chalk_1.default.red('Test execution failed'));
|
|
147
|
+
console.error(error);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
program
|
|
152
|
+
.command('create-example')
|
|
153
|
+
.description('Create an example component and test file')
|
|
154
|
+
.option('-d, --dir <directory>', 'Directory to create files in', './react-test-example')
|
|
155
|
+
.action(async (options) => {
|
|
156
|
+
const dir = path.resolve(options.dir);
|
|
157
|
+
console.log(chalk_1.default.blue(`Creating example files in: ${dir}`));
|
|
158
|
+
// Create directory if it doesn't exist
|
|
159
|
+
if (!fs.existsSync(dir)) {
|
|
160
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
161
|
+
}
|
|
162
|
+
// Create example component
|
|
163
|
+
const componentContent = `// Example React Component
|
|
164
|
+
const Component = ({ name, count, showDetails }) => {
|
|
165
|
+
const [clickCount, setClickCount] = React.useState(0);
|
|
166
|
+
|
|
167
|
+
const handleClick = () => {
|
|
168
|
+
setClickCount(clickCount + 1);
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<div className="example-component">
|
|
173
|
+
<h1>Hello, {name || 'World'}!</h1>
|
|
174
|
+
<p>Count: {count || 0}</p>
|
|
175
|
+
<button onClick={handleClick}>
|
|
176
|
+
Clicked {clickCount} times
|
|
177
|
+
</button>
|
|
178
|
+
{showDetails && (
|
|
179
|
+
<div className="details">
|
|
180
|
+
<p>This is additional detail content.</p>
|
|
181
|
+
</div>
|
|
182
|
+
)}
|
|
183
|
+
</div>
|
|
184
|
+
);
|
|
185
|
+
};`;
|
|
186
|
+
fs.writeFileSync(path.join(dir, 'ExampleComponent.jsx'), componentContent);
|
|
187
|
+
console.log(chalk_1.default.green('✓ Created ExampleComponent.jsx'));
|
|
188
|
+
// Create example test
|
|
189
|
+
const testContent = `// Example test using ReactTestHarness
|
|
190
|
+
export default async function runTests(harness) {
|
|
191
|
+
const { AssertionHelpers } = harness;
|
|
192
|
+
|
|
193
|
+
// Test 1: Basic rendering
|
|
194
|
+
await harness.runTest('Component renders with default props', async () => {
|
|
195
|
+
const result = await harness.testComponentFromFile(
|
|
196
|
+
'./ExampleComponent.jsx'
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
AssertionHelpers.assertSuccess(result);
|
|
200
|
+
AssertionHelpers.assertContainsText(result.html, 'Hello, World!');
|
|
201
|
+
AssertionHelpers.assertContainsText(result.html, 'Count: 0');
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Test 2: Rendering with custom props
|
|
205
|
+
await harness.runTest('Component renders with custom props', async () => {
|
|
206
|
+
const result = await harness.testComponentFromFile(
|
|
207
|
+
'./ExampleComponent.jsx',
|
|
208
|
+
{ name: 'MemberJunction', count: 42, showDetails: true }
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
AssertionHelpers.assertSuccess(result);
|
|
212
|
+
AssertionHelpers.assertContainsText(result.html, 'Hello, MemberJunction!');
|
|
213
|
+
AssertionHelpers.assertContainsText(result.html, 'Count: 42');
|
|
214
|
+
AssertionHelpers.assertHasElement(result.html, '.details');
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Test 3: Check for button element
|
|
218
|
+
await harness.runTest('Component has clickable button', async () => {
|
|
219
|
+
const result = await harness.testComponentFromFile(
|
|
220
|
+
'./ExampleComponent.jsx'
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
const matcher = harness.createMatcher(result.html);
|
|
224
|
+
matcher.toHaveElement('button');
|
|
225
|
+
matcher.toContainText('Clicked 0 times');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Get test summary
|
|
229
|
+
const summary = await harness.runTests([
|
|
230
|
+
{
|
|
231
|
+
name: 'No console errors',
|
|
232
|
+
fn: async () => {
|
|
233
|
+
const result = await harness.testComponentFromFile('./ExampleComponent.jsx');
|
|
234
|
+
AssertionHelpers.assertNoConsoleErrors(result.console);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
]);
|
|
238
|
+
|
|
239
|
+
console.log(\`\\nTest Summary: \${summary.passed}/\${summary.total} passed\`);
|
|
240
|
+
}`;
|
|
241
|
+
fs.writeFileSync(path.join(dir, 'example.test.js'), testContent);
|
|
242
|
+
console.log(chalk_1.default.green('✓ Created example.test.js'));
|
|
243
|
+
console.log(chalk_1.default.blue('\nTo run the example:'));
|
|
244
|
+
console.log(chalk_1.default.gray(` cd ${options.dir}`));
|
|
245
|
+
console.log(chalk_1.default.gray(' mj-react-test run ExampleComponent.jsx'));
|
|
246
|
+
console.log(chalk_1.default.gray(' mj-react-test run ExampleComponent.jsx --props \'{"name":"Test","count":10}\''));
|
|
247
|
+
console.log(chalk_1.default.gray(' mj-react-test test example.test.js'));
|
|
248
|
+
});
|
|
249
|
+
program.parse();
|
|
250
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ReactTestHarness, TestHarnessOptions } from './lib/test-harness';
|
|
2
|
+
export { BrowserManager, BrowserContextOptions } from './lib/browser-context';
|
|
3
|
+
export { ComponentRunner, ComponentExecutionOptions, ComponentExecutionResult, ComponentSpec } from './lib/component-runner';
|
|
4
|
+
export { AssertionHelpers } from './lib/assertion-helpers';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC7H,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AssertionHelpers = exports.ComponentRunner = exports.BrowserManager = exports.ReactTestHarness = void 0;
|
|
4
|
+
var test_harness_1 = require("./lib/test-harness");
|
|
5
|
+
Object.defineProperty(exports, "ReactTestHarness", { enumerable: true, get: function () { return test_harness_1.ReactTestHarness; } });
|
|
6
|
+
var browser_context_1 = require("./lib/browser-context");
|
|
7
|
+
Object.defineProperty(exports, "BrowserManager", { enumerable: true, get: function () { return browser_context_1.BrowserManager; } });
|
|
8
|
+
var component_runner_1 = require("./lib/component-runner");
|
|
9
|
+
Object.defineProperty(exports, "ComponentRunner", { enumerable: true, get: function () { return component_runner_1.ComponentRunner; } });
|
|
10
|
+
var assertion_helpers_1 = require("./lib/assertion-helpers");
|
|
11
|
+
Object.defineProperty(exports, "AssertionHelpers", { enumerable: true, get: function () { return assertion_helpers_1.AssertionHelpers; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAA0E;AAAjE,gHAAA,gBAAgB,OAAA;AACzB,yDAA8E;AAArE,iHAAA,cAAc,OAAA;AACvB,2DAA6H;AAApH,mHAAA,eAAe,OAAA;AACxB,6DAA2D;AAAlD,qHAAA,gBAAgB,OAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare class AssertionHelpers {
|
|
2
|
+
static containsText(html: string, text: string): boolean;
|
|
3
|
+
static hasElement(html: string, selector: string): boolean;
|
|
4
|
+
static countElements(html: string, tagName: string): number;
|
|
5
|
+
static hasAttribute(html: string, selector: string, attribute: string, value?: string): boolean;
|
|
6
|
+
static extractTextContent(html: string): string;
|
|
7
|
+
static assertNoErrors(result: {
|
|
8
|
+
errors: string[];
|
|
9
|
+
}): void;
|
|
10
|
+
static assertSuccess(result: {
|
|
11
|
+
success: boolean;
|
|
12
|
+
errors: string[];
|
|
13
|
+
}): void;
|
|
14
|
+
static findConsoleErrors(consoleLogs: {
|
|
15
|
+
type: string;
|
|
16
|
+
text: string;
|
|
17
|
+
}[]): string[];
|
|
18
|
+
static findConsoleWarnings(consoleLogs: {
|
|
19
|
+
type: string;
|
|
20
|
+
text: string;
|
|
21
|
+
}[]): string[];
|
|
22
|
+
static assertNoConsoleErrors(consoleLogs: {
|
|
23
|
+
type: string;
|
|
24
|
+
text: string;
|
|
25
|
+
}[]): void;
|
|
26
|
+
static assertContainsText(html: string, text: string): void;
|
|
27
|
+
static assertNotContainsText(html: string, text: string): void;
|
|
28
|
+
static assertHasElement(html: string, selector: string): void;
|
|
29
|
+
static assertElementCount(html: string, tagName: string, expectedCount: number): void;
|
|
30
|
+
static createMatcher(html: string): {
|
|
31
|
+
toContainText: (text: string) => void;
|
|
32
|
+
toHaveElement: (selector: string) => void;
|
|
33
|
+
toHaveElementCount: (tagName: string, count: number) => void;
|
|
34
|
+
toHaveAttribute: (selector: string, attribute: string, value?: string) => void;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=assertion-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertion-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/assertion-helpers.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAKxD,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAsB1D,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAM3D,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;IAc/F,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI/C,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI;IAMzD,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI;IAM1E,MAAM,CAAC,iBAAiB,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,MAAM,EAAE;IAMjF,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,MAAM,EAAE;IAMnF,MAAM,CAAC,qBAAqB,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,IAAI;IAOjF,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAM3D,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAM9D,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAM7D,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI;IAOrF,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM;8BAEP,MAAM;kCACF,MAAM;sCACF,MAAM,SAAS,MAAM;oCACvB,MAAM,aAAa,MAAM,UAAU,MAAM;;CAO1E"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AssertionHelpers = void 0;
|
|
4
|
+
class AssertionHelpers {
|
|
5
|
+
static containsText(html, text) {
|
|
6
|
+
const textContent = html.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim();
|
|
7
|
+
return textContent.includes(text);
|
|
8
|
+
}
|
|
9
|
+
static hasElement(html, selector) {
|
|
10
|
+
// Simple selector matching for common cases
|
|
11
|
+
if (selector.startsWith('#')) {
|
|
12
|
+
const id = selector.substring(1);
|
|
13
|
+
return html.includes(`id="${id}"`) || html.includes(`id='${id}'`);
|
|
14
|
+
}
|
|
15
|
+
if (selector.startsWith('.')) {
|
|
16
|
+
const className = selector.substring(1);
|
|
17
|
+
return html.includes(`class="${className}"`) ||
|
|
18
|
+
html.includes(`class='${className}'`) ||
|
|
19
|
+
html.includes(`class="${className} `) ||
|
|
20
|
+
html.includes(`class='${className} `) ||
|
|
21
|
+
html.includes(` ${className}"`) ||
|
|
22
|
+
html.includes(` ${className}'`) ||
|
|
23
|
+
html.includes(` ${className} `);
|
|
24
|
+
}
|
|
25
|
+
// Tag name selector
|
|
26
|
+
return html.includes(`<${selector}`) || html.includes(`<${selector} `) || html.includes(`<${selector}>`);
|
|
27
|
+
}
|
|
28
|
+
static countElements(html, tagName) {
|
|
29
|
+
const regex = new RegExp(`<${tagName}[\\s>]`, 'gi');
|
|
30
|
+
const matches = html.match(regex);
|
|
31
|
+
return matches ? matches.length : 0;
|
|
32
|
+
}
|
|
33
|
+
static hasAttribute(html, selector, attribute, value) {
|
|
34
|
+
if (!this.hasElement(html, selector)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (value === undefined) {
|
|
38
|
+
// Just check if attribute exists
|
|
39
|
+
return html.includes(` ${attribute}=`) || html.includes(` ${attribute} `) || html.includes(` ${attribute}>`);
|
|
40
|
+
}
|
|
41
|
+
// Check for specific attribute value
|
|
42
|
+
return html.includes(`${attribute}="${value}"`) || html.includes(`${attribute}='${value}'`);
|
|
43
|
+
}
|
|
44
|
+
static extractTextContent(html) {
|
|
45
|
+
return html.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim();
|
|
46
|
+
}
|
|
47
|
+
static assertNoErrors(result) {
|
|
48
|
+
if (result.errors.length > 0) {
|
|
49
|
+
throw new Error(`Component execution had errors: ${result.errors.join(', ')}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
static assertSuccess(result) {
|
|
53
|
+
if (!result.success) {
|
|
54
|
+
throw new Error(`Component execution failed: ${result.errors.join(', ')}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
static findConsoleErrors(consoleLogs) {
|
|
58
|
+
return consoleLogs
|
|
59
|
+
.filter(log => log.type === 'error')
|
|
60
|
+
.map(log => log.text);
|
|
61
|
+
}
|
|
62
|
+
static findConsoleWarnings(consoleLogs) {
|
|
63
|
+
return consoleLogs
|
|
64
|
+
.filter(log => log.type === 'warning')
|
|
65
|
+
.map(log => log.text);
|
|
66
|
+
}
|
|
67
|
+
static assertNoConsoleErrors(consoleLogs) {
|
|
68
|
+
const errors = this.findConsoleErrors(consoleLogs);
|
|
69
|
+
if (errors.length > 0) {
|
|
70
|
+
throw new Error(`Console errors found: ${errors.join(', ')}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
static assertContainsText(html, text) {
|
|
74
|
+
if (!this.containsText(html, text)) {
|
|
75
|
+
throw new Error(`Text "${text}" not found in rendered output`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
static assertNotContainsText(html, text) {
|
|
79
|
+
if (this.containsText(html, text)) {
|
|
80
|
+
throw new Error(`Text "${text}" found in rendered output but should not be present`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
static assertHasElement(html, selector) {
|
|
84
|
+
if (!this.hasElement(html, selector)) {
|
|
85
|
+
throw new Error(`Element "${selector}" not found in rendered output`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
static assertElementCount(html, tagName, expectedCount) {
|
|
89
|
+
const actualCount = this.countElements(html, tagName);
|
|
90
|
+
if (actualCount !== expectedCount) {
|
|
91
|
+
throw new Error(`Expected ${expectedCount} "${tagName}" elements but found ${actualCount}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
static createMatcher(html) {
|
|
95
|
+
return {
|
|
96
|
+
toContainText: (text) => this.assertContainsText(html, text),
|
|
97
|
+
toHaveElement: (selector) => this.assertHasElement(html, selector),
|
|
98
|
+
toHaveElementCount: (tagName, count) => this.assertElementCount(html, tagName, count),
|
|
99
|
+
toHaveAttribute: (selector, attribute, value) => {
|
|
100
|
+
if (!this.hasAttribute(html, selector, attribute, value)) {
|
|
101
|
+
throw new Error(`Element "${selector}" does not have attribute "${attribute}"${value ? ` with value "${value}"` : ''}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.AssertionHelpers = AssertionHelpers;
|
|
108
|
+
//# sourceMappingURL=assertion-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertion-helpers.js","sourceRoot":"","sources":["../../src/lib/assertion-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Page } from 'playwright';
|
|
3
|
+
export interface BrowserContextOptions {
|
|
4
|
+
headless?: boolean;
|
|
5
|
+
viewport?: {
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
};
|
|
9
|
+
userAgent?: string;
|
|
10
|
+
deviceScaleFactor?: number;
|
|
11
|
+
locale?: string;
|
|
12
|
+
timezoneId?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class BrowserManager {
|
|
15
|
+
private options;
|
|
16
|
+
private browser;
|
|
17
|
+
private context;
|
|
18
|
+
private page;
|
|
19
|
+
constructor(options?: BrowserContextOptions);
|
|
20
|
+
initialize(): Promise<void>;
|
|
21
|
+
getPage(): Promise<Page>;
|
|
22
|
+
navigateTo(url: string): Promise<void>;
|
|
23
|
+
evaluateInPage<T>(fn: (...args: any[]) => T, ...args: any[]): Promise<T>;
|
|
24
|
+
waitForSelector(selector: string, options?: {
|
|
25
|
+
timeout?: number;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
screenshot(path?: string): Promise<Buffer>;
|
|
28
|
+
getContent(): Promise<string>;
|
|
29
|
+
close(): Promise<void>;
|
|
30
|
+
reload(): Promise<void>;
|
|
31
|
+
waitForLoadState(state?: 'load' | 'domcontentloaded' | 'networkidle'): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=browser-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-context.d.ts","sourceRoot":"","sources":["../../src/lib/browser-context.ts"],"names":[],"mappings":";AAAA,OAAO,EAAqC,IAAI,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,cAAc;IAKb,OAAO,CAAC,OAAO;IAJ3B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,IAAI,CAAqB;gBAEb,OAAO,GAAE,qBAA0B;IAQjD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtC,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAKxE,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhF,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK1C,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAK7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAetB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAKvB,gBAAgB,CAAC,KAAK,GAAE,MAAM,GAAG,kBAAkB,GAAG,aAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;CAInG"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BrowserManager = void 0;
|
|
4
|
+
const playwright_1 = require("playwright");
|
|
5
|
+
class BrowserManager {
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
this.options = options;
|
|
8
|
+
this.browser = null;
|
|
9
|
+
this.context = null;
|
|
10
|
+
this.page = null;
|
|
11
|
+
this.options = {
|
|
12
|
+
headless: true,
|
|
13
|
+
viewport: { width: 1280, height: 720 },
|
|
14
|
+
...options
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
async initialize() {
|
|
18
|
+
if (this.browser) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this.browser = await playwright_1.chromium.launch({
|
|
22
|
+
headless: this.options.headless
|
|
23
|
+
});
|
|
24
|
+
this.context = await this.browser.newContext({
|
|
25
|
+
viewport: this.options.viewport,
|
|
26
|
+
userAgent: this.options.userAgent,
|
|
27
|
+
deviceScaleFactor: this.options.deviceScaleFactor,
|
|
28
|
+
locale: this.options.locale,
|
|
29
|
+
timezoneId: this.options.timezoneId
|
|
30
|
+
});
|
|
31
|
+
this.page = await this.context.newPage();
|
|
32
|
+
}
|
|
33
|
+
async getPage() {
|
|
34
|
+
if (!this.page) {
|
|
35
|
+
await this.initialize();
|
|
36
|
+
}
|
|
37
|
+
return this.page;
|
|
38
|
+
}
|
|
39
|
+
async navigateTo(url) {
|
|
40
|
+
const page = await this.getPage();
|
|
41
|
+
await page.goto(url);
|
|
42
|
+
}
|
|
43
|
+
async evaluateInPage(fn, ...args) {
|
|
44
|
+
const page = await this.getPage();
|
|
45
|
+
return await page.evaluate(fn, ...args);
|
|
46
|
+
}
|
|
47
|
+
async waitForSelector(selector, options) {
|
|
48
|
+
const page = await this.getPage();
|
|
49
|
+
await page.waitForSelector(selector, options);
|
|
50
|
+
}
|
|
51
|
+
async screenshot(path) {
|
|
52
|
+
const page = await this.getPage();
|
|
53
|
+
return await page.screenshot({ path });
|
|
54
|
+
}
|
|
55
|
+
async getContent() {
|
|
56
|
+
const page = await this.getPage();
|
|
57
|
+
return await page.content();
|
|
58
|
+
}
|
|
59
|
+
async close() {
|
|
60
|
+
if (this.page) {
|
|
61
|
+
await this.page.close();
|
|
62
|
+
this.page = null;
|
|
63
|
+
}
|
|
64
|
+
if (this.context) {
|
|
65
|
+
await this.context.close();
|
|
66
|
+
this.context = null;
|
|
67
|
+
}
|
|
68
|
+
if (this.browser) {
|
|
69
|
+
await this.browser.close();
|
|
70
|
+
this.browser = null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async reload() {
|
|
74
|
+
const page = await this.getPage();
|
|
75
|
+
await page.reload();
|
|
76
|
+
}
|
|
77
|
+
async waitForLoadState(state = 'load') {
|
|
78
|
+
const page = await this.getPage();
|
|
79
|
+
await page.waitForLoadState(state);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.BrowserManager = BrowserManager;
|
|
83
|
+
//# sourceMappingURL=browser-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-context.js","sourceRoot":"","sources":["../../src/lib/browser-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { BrowserManager } from './browser-context';
|
|
3
|
+
export interface ComponentExecutionOptions {
|
|
4
|
+
componentCode: string;
|
|
5
|
+
props?: Record<string, any>;
|
|
6
|
+
setupCode?: string;
|
|
7
|
+
timeout?: number;
|
|
8
|
+
waitForSelector?: string;
|
|
9
|
+
waitForLoadState?: 'load' | 'domcontentloaded' | 'networkidle';
|
|
10
|
+
childComponents?: ComponentSpec[];
|
|
11
|
+
registerChildren?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface ComponentSpec {
|
|
14
|
+
componentName: string;
|
|
15
|
+
componentCode?: string;
|
|
16
|
+
childComponents?: ComponentSpec[];
|
|
17
|
+
components?: ComponentSpec[];
|
|
18
|
+
}
|
|
19
|
+
export interface ComponentExecutionResult {
|
|
20
|
+
success: boolean;
|
|
21
|
+
html: string;
|
|
22
|
+
errors: string[];
|
|
23
|
+
console: {
|
|
24
|
+
type: string;
|
|
25
|
+
text: string;
|
|
26
|
+
}[];
|
|
27
|
+
screenshot?: Buffer;
|
|
28
|
+
executionTime: number;
|
|
29
|
+
}
|
|
30
|
+
export declare class ComponentRunner {
|
|
31
|
+
private browserManager;
|
|
32
|
+
constructor(browserManager: BrowserManager);
|
|
33
|
+
executeComponent(options: ComponentExecutionOptions): Promise<ComponentExecutionResult>;
|
|
34
|
+
private createHTMLTemplate;
|
|
35
|
+
private generateChildComponentRegistration;
|
|
36
|
+
executeComponentFromFile(filePath: string, props?: Record<string, any>, options?: Partial<ComponentExecutionOptions>): Promise<ComponentExecutionResult>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=component-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-runner.d.ts","sourceRoot":"","sources":["../../src/lib/component-runner.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAInD,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,aAAa,CAAC;IAC/D,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;IAClC,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAE5C,gBAAgB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAgE7F,OAAO,CAAC,kBAAkB;IAiD1B,OAAO,CAAC,kCAAkC;IAkCpC,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,GAC3C,OAAO,CAAC,wBAAwB,CAAC;CAerC"}
|