@bernierllc/email-test-orchestrator 0.1.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/LICENSE ADDED
@@ -0,0 +1,5 @@
1
+ Copyright (c) 2025 Bernier LLC
2
+
3
+ This file is licensed to the client under a limited-use license.
4
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
5
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
package/README.md ADDED
@@ -0,0 +1,273 @@
1
+ # @bernierllc/email-test-orchestrator
2
+
3
+ Service package that orchestrates comprehensive email testing workflows. This package coordinates email sending and receiving for tests, manages test email addresses and routing, executes validation workflows across multiple aspects, and generates comprehensive test reports.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @bernierllc/email-test-orchestrator
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - **Complete Test Orchestration** - End-to-end email testing workflows
14
+ - **Multi-Validator Coordination** - Use multiple validation packages
15
+ - **Comprehensive Reporting** - Detailed test results and analytics
16
+ - **Test Lifecycle Management** - Setup, execution, cleanup
17
+ - **Async Test Coordination** - Handle asynchronous email delivery testing
18
+ - **Flexible Configuration** - Customize SMTP, capture, validation, and reporting
19
+
20
+ ## Usage
21
+
22
+ ### Basic Example
23
+
24
+ ```typescript
25
+ import { EmailTestOrchestrator } from '@bernierllc/email-test-orchestrator';
26
+
27
+ const orchestrator = new EmailTestOrchestrator({
28
+ smtp: {
29
+ host: 'localhost',
30
+ port: 2525,
31
+ },
32
+ validation: {
33
+ enabledValidators: ['content', 'delivery', 'compliance'],
34
+ },
35
+ });
36
+
37
+ // Run a single test
38
+ const result = await orchestrator.runEmailTest({
39
+ name: 'Welcome Email Test',
40
+ description: 'Test welcome email delivery and content',
41
+ sender: { email: 'noreply@example.com' },
42
+ recipients: [{ email: 'user@example.com' }],
43
+ expectations: [
44
+ {
45
+ type: 'delivery',
46
+ criteria: { delivered: true },
47
+ weight: 2,
48
+ },
49
+ {
50
+ type: 'content',
51
+ criteria: { hasSubject: true, hasBody: true },
52
+ weight: 1,
53
+ },
54
+ ],
55
+ });
56
+
57
+ console.log(`Test ${result.success ? 'passed' : 'failed'} with score: ${result.score}`);
58
+ ```
59
+
60
+ ### Send and Capture Email
61
+
62
+ ```typescript
63
+ const email = await orchestrator.sendAndCapture({
64
+ from: { email: 'sender@example.com', name: 'Sender' },
65
+ to: [{ email: 'recipient@example.com', name: 'Recipient' }],
66
+ subject: 'Test Email',
67
+ text: 'This is a test email',
68
+ });
69
+
70
+ console.log('Captured email:', email.subject);
71
+ ```
72
+
73
+ ### Execute Test Suite
74
+
75
+ ```typescript
76
+ const tests = [
77
+ {
78
+ name: 'Welcome Email',
79
+ description: 'Test welcome email',
80
+ sender: { email: 'noreply@example.com' },
81
+ recipients: [{ email: 'user1@example.com' }],
82
+ expectations: [
83
+ { type: 'delivery', criteria: { delivered: true } },
84
+ ],
85
+ },
86
+ {
87
+ name: 'Password Reset',
88
+ description: 'Test password reset email',
89
+ sender: { email: 'noreply@example.com' },
90
+ recipients: [{ email: 'user2@example.com' }],
91
+ expectations: [
92
+ { type: 'content', criteria: { hasResetLink: true } },
93
+ ],
94
+ },
95
+ ];
96
+
97
+ const suiteResult = await orchestrator.executeTestSuite(tests);
98
+
99
+ console.log(`Suite: ${suiteResult.report.summary.passed}/${suiteResult.report.summary.totalTests} passed`);
100
+ ```
101
+
102
+ ### Validate Captured Email
103
+
104
+ ```typescript
105
+ const validationResults = await orchestrator.validateEmail(capturedEmail, [
106
+ {
107
+ type: 'content',
108
+ criteria: { hasSubject: true, hasBody: true },
109
+ },
110
+ {
111
+ type: 'compliance',
112
+ criteria: { hasUnsubscribeLink: true },
113
+ },
114
+ {
115
+ type: 'template',
116
+ criteria: { templateName: 'welcome' },
117
+ },
118
+ ]);
119
+
120
+ for (const result of validationResults) {
121
+ console.log(`${result.type}: ${result.success ? 'PASS' : 'FAIL'} (score: ${result.score})`);
122
+ }
123
+ ```
124
+
125
+ ### Test Environment Setup
126
+
127
+ ```typescript
128
+ const context = await orchestrator.setupTestEnvironment({
129
+ mockServer: { port: 2525 },
130
+ session: { name: 'integration-test' },
131
+ cleanup: { retention: '1h' },
132
+ });
133
+
134
+ try {
135
+ // Run tests...
136
+ await orchestrator.runEmailTest(testSpec);
137
+ } finally {
138
+ // Clean up
139
+ await context.cleanup();
140
+ }
141
+ ```
142
+
143
+ ### Generate Report
144
+
145
+ ```typescript
146
+ const results = [testResult1, testResult2, testResult3];
147
+ const report = await orchestrator.generateReport(results);
148
+
149
+ console.log('Report Summary:');
150
+ console.log(`Total: ${report.summary.totalTests}`);
151
+ console.log(`Passed: ${report.summary.passed}`);
152
+ console.log(`Failed: ${report.summary.failed}`);
153
+ console.log(`Score: ${report.summary.score}%`);
154
+ console.log(`Duration: ${report.summary.duration}ms`);
155
+ ```
156
+
157
+ ### Wait for Email Delivery
158
+
159
+ ```typescript
160
+ const email = await orchestrator.waitForDelivery('email-123', 30000);
161
+
162
+ if (email) {
163
+ console.log('Email delivered:', email.subject);
164
+ } else {
165
+ console.log('Email not delivered within timeout');
166
+ }
167
+ ```
168
+
169
+ ## Configuration
170
+
171
+ ### OrchestratorConfig
172
+
173
+ ```typescript
174
+ interface OrchestratorConfig {
175
+ smtp?: {
176
+ host?: string; // Default: 'localhost'
177
+ port?: number; // Default: 2525
178
+ secure?: boolean; // Default: false
179
+ auth?: {
180
+ user: string;
181
+ pass: string;
182
+ };
183
+ };
184
+ capture?: {
185
+ sessionTimeout?: number; // Default: 300000 (5 minutes)
186
+ retentionPolicy?: string; // Default: '1h'
187
+ };
188
+ validation?: {
189
+ enabledValidators?: ValidatorType[]; // Default: all validators
190
+ parallelValidation?: boolean; // Default: true
191
+ validationTimeout?: number; // Default: 30000
192
+ };
193
+ reporting?: {
194
+ formats?: ReportFormat[]; // Default: ['json']
195
+ includeRawEmails?: boolean; // Default: false
196
+ includeScreenshots?: boolean; // Default: false
197
+ };
198
+ logger?: any; // Custom logger (default: console)
199
+ }
200
+ ```
201
+
202
+ ### Validator Types
203
+
204
+ - `content` - Validate email content (subject, body, etc.)
205
+ - `template` - Validate template processing
206
+ - `compliance` - Validate compliance (CAN-SPAM, GDPR, etc.)
207
+ - `smtp` - Validate SMTP delivery information
208
+ - `delivery` - Validate email delivery status
209
+
210
+ ### Report Formats
211
+
212
+ - `json` - JSON format for programmatic access
213
+ - `html` - HTML format for web viewing
214
+ - `pdf` - PDF format for sharing and archiving
215
+ - `csv` - CSV format for data analysis
216
+
217
+ ## API Reference
218
+
219
+ ### EmailTestOrchestrator
220
+
221
+ #### Methods
222
+
223
+ - `sendAndCapture(options: SendEmailOptions): Promise<CapturedEmail>`
224
+ - Send an email and capture it for testing
225
+
226
+ - `executeTestSuite(tests: EmailTestSpec[]): Promise<EmailTestSuiteResult>`
227
+ - Execute multiple tests and return suite result
228
+
229
+ - `runEmailTest(testSpec: EmailTestSpec): Promise<EmailTestResult>`
230
+ - Run a single email test
231
+
232
+ - `validateEmail(email: CapturedEmail, expectations: EmailExpectation[]): Promise<ValidationResult[]>`
233
+ - Validate email against expectations
234
+
235
+ - `generateReport(results: EmailTestResult[]): Promise<TestReport>`
236
+ - Generate comprehensive test report
237
+
238
+ - `setupTestEnvironment(config: TestSetupConfig): Promise<TestContext>`
239
+ - Set up test environment
240
+
241
+ - `cleanupTestEnvironment(sessionId: string): Promise<void>`
242
+ - Clean up test environment
243
+
244
+ - `waitForDelivery(emailId: string, timeout?: number): Promise<CapturedEmail | null>`
245
+ - Wait for email delivery with timeout
246
+
247
+ ## Dependencies
248
+
249
+ This package integrates with the following BernierLLC packages:
250
+
251
+ - `@bernierllc/mock-smtp-server` - SMTP server coordination
252
+ - `@bernierllc/email-test-assertions` - Test assertions
253
+ - `@bernierllc/email-sender` - Email sending
254
+ - `@bernierllc/email-parser` - Email parsing
255
+ - `@bernierllc/email-validator` - Email validation
256
+ - `@bernierllc/email-capture` - Email capture
257
+ - `@bernierllc/template-engine` - Template processing
258
+ - `@bernierllc/retry-policy` - Retry logic
259
+ - `@bernierllc/logger` - Logging
260
+
261
+ ## Production Use Cases
262
+
263
+ Beyond testing, this package can be used for:
264
+
265
+ - **Email Quality Assurance** - Pre-send validation workflows
266
+ - **Compliance Auditing** - Automated compliance checking
267
+ - **Template Testing** - Continuous template validation
268
+ - **Deliverability Monitoring** - Email delivery analysis
269
+ - **A/B Testing** - Email variant testing and comparison
270
+
271
+ ## License
272
+
273
+ Copyright (c) 2025 Bernier LLC. This file is licensed to the client under a limited-use license.
@@ -0,0 +1,72 @@
1
+ import type { OrchestratorConfig, EmailTestSpec, EmailTestResult, EmailTestSuiteResult, TestSetupConfig, TestContext, CapturedEmail, SendEmailOptions, ValidationResult, TestReport, EmailExpectation } from './types.js';
2
+ export declare class EmailTestOrchestrator {
3
+ private config;
4
+ private logger;
5
+ private validators;
6
+ constructor(config?: OrchestratorConfig);
7
+ /**
8
+ * Send an email and capture it for testing
9
+ */
10
+ sendAndCapture(options: SendEmailOptions): Promise<CapturedEmail>;
11
+ /**
12
+ * Execute a complete test suite
13
+ */
14
+ executeTestSuite(tests: EmailTestSpec[]): Promise<EmailTestSuiteResult>;
15
+ /**
16
+ * Run a single email test
17
+ */
18
+ runEmailTest(testSpec: EmailTestSpec): Promise<EmailTestResult>;
19
+ /**
20
+ * Validate a captured email against expectations
21
+ */
22
+ validateEmail(email: CapturedEmail, expectations: EmailExpectation[]): Promise<ValidationResult[]>;
23
+ /**
24
+ * Generate a test report
25
+ */
26
+ generateReport(results: EmailTestResult[]): Promise<TestReport>;
27
+ /**
28
+ * Set up test environment
29
+ */
30
+ setupTestEnvironment(config: TestSetupConfig): Promise<TestContext>;
31
+ /**
32
+ * Clean up test environment
33
+ */
34
+ cleanupTestEnvironment(sessionId: string): Promise<void>;
35
+ /**
36
+ * Wait for email delivery with timeout
37
+ */
38
+ waitForDelivery(emailId: string, timeout?: number): Promise<CapturedEmail | null>;
39
+ /**
40
+ * Send an email
41
+ */
42
+ private sendEmail;
43
+ /**
44
+ * Wait for emails to be captured
45
+ */
46
+ private waitForEmails;
47
+ /**
48
+ * Get captured emails
49
+ */
50
+ private getCapturedEmails;
51
+ /**
52
+ * Get validator for a specific type
53
+ */
54
+ private getValidator;
55
+ /**
56
+ * Calculate overall score from validation results
57
+ */
58
+ private calculateScore;
59
+ /**
60
+ * Generate report for a single test
61
+ */
62
+ private generateSingleTestReport;
63
+ /**
64
+ * Create a failed test result
65
+ */
66
+ private createFailedTestResult;
67
+ /**
68
+ * Sleep helper
69
+ */
70
+ private sleep;
71
+ }
72
+ //# sourceMappingURL=EmailTestOrchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailTestOrchestrator.d.ts","sourceRoot":"","sources":["../src/EmailTestOrchestrator.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,aAAa,EACb,gBAAgB,EAEhB,gBAAgB,EAEhB,UAAU,EACV,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAWpB,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAyB;gBAE/B,MAAM,GAAE,kBAAuB;IA+B3C;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC;IA0BvE;;OAEG;IACG,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA8C7E;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC;IAmErE;;OAEG;IACG,aAAa,CACjB,KAAK,EAAE,aAAa,EACpB,YAAY,EAAE,gBAAgB,EAAE,GAC/B,OAAO,CAAC,gBAAgB,EAAE,CAAC;IA4B9B;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAwBrE;;OAEG;IACG,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IAkBzE;;OAEG;IACG,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9D;;OAEG;IACG,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAc,GACtB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAiBhC;;OAEG;YACW,SAAS;IAKvB;;OAEG;YACW,aAAa;IAkB3B;;OAEG;YACW,iBAAiB;IAK/B;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAyBhC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAkC9B;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,390 @@
1
+ /*
2
+ Copyright (c) 2025 Bernier LLC
3
+
4
+ This file is licensed to the client under a limited-use license.
5
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
6
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
+ */
8
+ export class EmailTestOrchestrator {
9
+ config;
10
+ logger;
11
+ validators;
12
+ constructor(config = {}) {
13
+ this.config = {
14
+ smtp: {
15
+ host: 'localhost',
16
+ port: 2525,
17
+ secure: false,
18
+ ...config.smtp,
19
+ },
20
+ capture: {
21
+ sessionTimeout: 300000, // 5 minutes
22
+ retentionPolicy: '1h',
23
+ ...config.capture,
24
+ },
25
+ validation: {
26
+ enabledValidators: ['content', 'template', 'compliance', 'smtp', 'delivery'],
27
+ parallelValidation: true,
28
+ validationTimeout: 30000,
29
+ ...config.validation,
30
+ },
31
+ reporting: {
32
+ formats: ['json'],
33
+ includeRawEmails: false,
34
+ includeScreenshots: false,
35
+ ...config.reporting,
36
+ },
37
+ };
38
+ this.logger = config.logger || console;
39
+ this.validators = new Map();
40
+ }
41
+ /**
42
+ * Send an email and capture it for testing
43
+ */
44
+ async sendAndCapture(options) {
45
+ const startTime = Date.now();
46
+ try {
47
+ // Send email
48
+ await this.sendEmail(options);
49
+ // Wait for email to be captured
50
+ const emails = await this.waitForEmails({
51
+ count: 1,
52
+ timeout: 10000,
53
+ filter: (email) => email.subject === options.subject,
54
+ });
55
+ if (emails.length === 0) {
56
+ throw new Error('Email not captured within timeout period');
57
+ }
58
+ this.logger.info?.(`Email sent and captured in ${Date.now() - startTime}ms`);
59
+ return emails[0];
60
+ }
61
+ catch (error) {
62
+ this.logger.error?.('Failed to send and capture email:', error);
63
+ throw error;
64
+ }
65
+ }
66
+ /**
67
+ * Execute a complete test suite
68
+ */
69
+ async executeTestSuite(tests) {
70
+ const startTime = Date.now();
71
+ const results = [];
72
+ this.logger.info?.(`Executing test suite with ${tests.length} tests`);
73
+ for (const test of tests) {
74
+ try {
75
+ const result = await this.runEmailTest(test);
76
+ results.push(result);
77
+ }
78
+ catch (error) {
79
+ this.logger.error?.(`Test "${test.name}" failed:`, error);
80
+ results.push(this.createFailedTestResult(test, error));
81
+ }
82
+ }
83
+ const duration = Date.now() - startTime;
84
+ const success = results.every((r) => r.success);
85
+ const score = results.reduce((sum, r) => sum + r.score, 0) / results.length;
86
+ const report = {
87
+ summary: {
88
+ totalTests: tests.length,
89
+ passed: results.filter((r) => r.success).length,
90
+ failed: results.filter((r) => !r.success).length,
91
+ score,
92
+ duration,
93
+ },
94
+ tests: results,
95
+ metadata: {
96
+ timestamp: new Date().toISOString(),
97
+ environment: 'test',
98
+ version: '1.0.0',
99
+ },
100
+ };
101
+ return {
102
+ suiteName: 'Email Test Suite',
103
+ success,
104
+ score,
105
+ duration,
106
+ tests: results,
107
+ report,
108
+ };
109
+ }
110
+ /**
111
+ * Run a single email test
112
+ */
113
+ async runEmailTest(testSpec) {
114
+ const startTime = Date.now();
115
+ const issues = [];
116
+ try {
117
+ this.logger.info?.(`Running test: ${testSpec.name}`);
118
+ // Send test email
119
+ const sendOptions = {
120
+ from: testSpec.sender,
121
+ to: testSpec.recipients,
122
+ subject: testSpec.template?.subject || 'Test Email',
123
+ template: testSpec.template,
124
+ data: testSpec.data,
125
+ };
126
+ await this.sendEmail(sendOptions);
127
+ // Wait for emails
128
+ const capturedEmails = await this.waitForEmails({
129
+ count: testSpec.recipients.length,
130
+ timeout: testSpec.timeout || 30000,
131
+ });
132
+ // Validate emails
133
+ const validationResults = [];
134
+ for (const email of capturedEmails) {
135
+ const results = await this.validateEmail(email, testSpec.expectations);
136
+ validationResults.push(...results);
137
+ }
138
+ // Calculate success and score
139
+ const success = validationResults.every((r) => r.success);
140
+ const score = this.calculateScore(validationResults, testSpec.expectations);
141
+ // Collect issues
142
+ for (const result of validationResults) {
143
+ if (!result.success && result.errors) {
144
+ for (const error of result.errors) {
145
+ issues.push({
146
+ severity: 'error',
147
+ type: result.type,
148
+ message: error,
149
+ });
150
+ }
151
+ }
152
+ }
153
+ const duration = Date.now() - startTime;
154
+ return {
155
+ testName: testSpec.name,
156
+ success,
157
+ score,
158
+ duration,
159
+ emailsSent: testSpec.recipients.length,
160
+ emailsCaptured: capturedEmails.length,
161
+ validationResults,
162
+ issues,
163
+ report: this.generateSingleTestReport(testSpec, validationResults, duration),
164
+ };
165
+ }
166
+ catch (error) {
167
+ this.logger.error?.(`Test "${testSpec.name}" failed:`, error);
168
+ return this.createFailedTestResult(testSpec, error);
169
+ }
170
+ }
171
+ /**
172
+ * Validate a captured email against expectations
173
+ */
174
+ async validateEmail(email, expectations) {
175
+ const results = [];
176
+ for (const expectation of expectations) {
177
+ try {
178
+ const validator = this.getValidator(expectation.type);
179
+ const result = await validator.validate(email, expectation.criteria);
180
+ results.push({
181
+ type: expectation.type,
182
+ success: result.success,
183
+ score: result.score || (result.success ? 100 : 0),
184
+ details: result.details || {},
185
+ errors: result.errors,
186
+ });
187
+ }
188
+ catch (error) {
189
+ results.push({
190
+ type: expectation.type,
191
+ success: false,
192
+ score: 0,
193
+ details: {},
194
+ errors: [error.message],
195
+ });
196
+ }
197
+ }
198
+ return results;
199
+ }
200
+ /**
201
+ * Generate a test report
202
+ */
203
+ async generateReport(results) {
204
+ const totalTests = results.length;
205
+ const passed = results.filter((r) => r.success).length;
206
+ const failed = totalTests - passed;
207
+ const score = results.reduce((sum, r) => sum + r.score, 0) / totalTests;
208
+ const duration = results.reduce((sum, r) => sum + r.duration, 0);
209
+ return {
210
+ summary: {
211
+ totalTests,
212
+ passed,
213
+ failed,
214
+ score,
215
+ duration,
216
+ },
217
+ tests: results,
218
+ metadata: {
219
+ timestamp: new Date().toISOString(),
220
+ environment: 'test',
221
+ version: '1.0.0',
222
+ },
223
+ };
224
+ }
225
+ /**
226
+ * Set up test environment
227
+ */
228
+ async setupTestEnvironment(config) {
229
+ const sessionId = `test-${Date.now()}`;
230
+ this.logger.info?.('Setting up test environment:', sessionId);
231
+ // Mock server setup would happen here
232
+ // For now, return a basic context
233
+ return {
234
+ sessionId,
235
+ mockServerPort: config.mockServer?.port || 2525,
236
+ createdAt: new Date(),
237
+ cleanup: async () => {
238
+ await this.cleanupTestEnvironment(sessionId);
239
+ },
240
+ };
241
+ }
242
+ /**
243
+ * Clean up test environment
244
+ */
245
+ async cleanupTestEnvironment(sessionId) {
246
+ this.logger.info?.('Cleaning up test environment:', sessionId);
247
+ // Cleanup logic would be implemented here
248
+ }
249
+ /**
250
+ * Wait for email delivery with timeout
251
+ */
252
+ async waitForDelivery(emailId, timeout = 30000) {
253
+ const startTime = Date.now();
254
+ while (Date.now() - startTime < timeout) {
255
+ const emails = await this.getCapturedEmails();
256
+ const email = emails.find((e) => e.id === emailId);
257
+ if (email) {
258
+ return email;
259
+ }
260
+ await this.sleep(100);
261
+ }
262
+ return null;
263
+ }
264
+ /**
265
+ * Send an email
266
+ */
267
+ async sendEmail(options) {
268
+ // Mock implementation - would use email-sender package
269
+ this.logger.info?.('Sending email:', options.subject);
270
+ }
271
+ /**
272
+ * Wait for emails to be captured
273
+ */
274
+ async waitForEmails(options) {
275
+ const startTime = Date.now();
276
+ const timeout = options.timeout || 30000;
277
+ while (Date.now() - startTime < timeout) {
278
+ const emails = await this.getCapturedEmails();
279
+ const filtered = options.filter ? emails.filter(options.filter) : emails;
280
+ if (filtered.length >= options.count) {
281
+ return filtered.slice(0, options.count);
282
+ }
283
+ await this.sleep(100);
284
+ }
285
+ return [];
286
+ }
287
+ /**
288
+ * Get captured emails
289
+ */
290
+ async getCapturedEmails() {
291
+ // Mock implementation - would use email-capture package
292
+ return [];
293
+ }
294
+ /**
295
+ * Get validator for a specific type
296
+ */
297
+ getValidator(type) {
298
+ if (!this.validators.has(type)) {
299
+ // Create mock validator
300
+ this.validators.set(type, {
301
+ validate: async () => ({
302
+ success: true,
303
+ score: 100,
304
+ details: {},
305
+ }),
306
+ });
307
+ }
308
+ return this.validators.get(type);
309
+ }
310
+ /**
311
+ * Calculate overall score from validation results
312
+ */
313
+ calculateScore(results, expectations) {
314
+ if (results.length === 0)
315
+ return 0;
316
+ let totalWeight = 0;
317
+ let weightedScore = 0;
318
+ for (let i = 0; i < results.length; i++) {
319
+ const weight = expectations[i]?.weight || 1;
320
+ totalWeight += weight;
321
+ weightedScore += results[i].score * weight;
322
+ }
323
+ return totalWeight > 0 ? weightedScore / totalWeight : 0;
324
+ }
325
+ /**
326
+ * Generate report for a single test
327
+ */
328
+ generateSingleTestReport(testSpec, validationResults, duration) {
329
+ const success = validationResults.every((r) => r.success);
330
+ const score = this.calculateScore(validationResults, testSpec.expectations);
331
+ return {
332
+ summary: {
333
+ totalTests: 1,
334
+ passed: success ? 1 : 0,
335
+ failed: success ? 0 : 1,
336
+ score,
337
+ duration,
338
+ },
339
+ tests: [],
340
+ metadata: {
341
+ timestamp: new Date().toISOString(),
342
+ environment: 'test',
343
+ version: '1.0.0',
344
+ },
345
+ };
346
+ }
347
+ /**
348
+ * Create a failed test result
349
+ */
350
+ createFailedTestResult(testSpec, error) {
351
+ return {
352
+ testName: testSpec.name,
353
+ success: false,
354
+ score: 0,
355
+ duration: 0,
356
+ emailsSent: 0,
357
+ emailsCaptured: 0,
358
+ validationResults: [],
359
+ issues: [
360
+ {
361
+ severity: 'error',
362
+ type: 'test_execution',
363
+ message: error.message,
364
+ },
365
+ ],
366
+ report: {
367
+ summary: {
368
+ totalTests: 1,
369
+ passed: 0,
370
+ failed: 1,
371
+ score: 0,
372
+ duration: 0,
373
+ },
374
+ tests: [],
375
+ metadata: {
376
+ timestamp: new Date().toISOString(),
377
+ environment: 'test',
378
+ version: '1.0.0',
379
+ },
380
+ },
381
+ };
382
+ }
383
+ /**
384
+ * Sleep helper
385
+ */
386
+ sleep(ms) {
387
+ return new Promise((resolve) => setTimeout(resolve, ms));
388
+ }
389
+ }
390
+ //# sourceMappingURL=EmailTestOrchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailTestOrchestrator.js","sourceRoot":"","sources":["../src/EmailTestOrchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { EmailTestOrchestrator } from './EmailTestOrchestrator.js';
2
+ export type { Logger, OrchestratorConfig, EmailTestSpec, EmailTestResult, EmailTestSuiteResult, TestSetupConfig, TestContext, CapturedEmail, SendEmailOptions, WaitForEmailsOptions, ValidateEmailsOptions, ValidationResult, TestIssue, TestReport, EmailSender, EmailRecipient, EmailTemplate, EmailExpectation, ExpectationCriteria, ValidatorType, ReportFormat, } from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EACV,MAAM,EACN,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /*
2
+ Copyright (c) 2025 Bernier LLC
3
+
4
+ This file is licensed to the client under a limited-use license.
5
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
6
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
+ */
8
+ export { EmailTestOrchestrator } from './EmailTestOrchestrator.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAEF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,167 @@
1
+ export interface Logger {
2
+ info?: (...args: unknown[]) => void;
3
+ error?: (...args: unknown[]) => void;
4
+ warn?: (...args: unknown[]) => void;
5
+ debug?: (...args: unknown[]) => void;
6
+ }
7
+ export interface OrchestratorConfig {
8
+ smtp?: {
9
+ host?: string;
10
+ port?: number;
11
+ secure?: boolean;
12
+ auth?: {
13
+ user: string;
14
+ pass: string;
15
+ };
16
+ };
17
+ capture?: {
18
+ sessionTimeout?: number;
19
+ retentionPolicy?: string;
20
+ };
21
+ validation?: {
22
+ enabledValidators?: ValidatorType[];
23
+ parallelValidation?: boolean;
24
+ validationTimeout?: number;
25
+ };
26
+ reporting?: {
27
+ formats?: ReportFormat[];
28
+ includeRawEmails?: boolean;
29
+ includeScreenshots?: boolean;
30
+ };
31
+ logger?: Logger;
32
+ }
33
+ export type ValidatorType = 'content' | 'template' | 'compliance' | 'smtp' | 'delivery';
34
+ export type ReportFormat = 'json' | 'html' | 'pdf' | 'csv';
35
+ export interface EmailTestSpec {
36
+ name: string;
37
+ description: string;
38
+ sender: EmailSender;
39
+ recipients: EmailRecipient[];
40
+ template?: EmailTemplate;
41
+ data?: Record<string, unknown>;
42
+ expectations: EmailExpectation[];
43
+ timeout?: number;
44
+ retries?: number;
45
+ }
46
+ export interface EmailSender {
47
+ email: string;
48
+ name?: string;
49
+ }
50
+ export interface EmailRecipient {
51
+ email: string;
52
+ name?: string;
53
+ type?: 'to' | 'cc' | 'bcc';
54
+ }
55
+ export interface EmailTemplate {
56
+ name: string;
57
+ subject: string;
58
+ body: string;
59
+ type?: 'html' | 'text';
60
+ }
61
+ export interface EmailExpectation {
62
+ type: 'delivery' | 'content' | 'compliance' | 'template' | 'smtp';
63
+ criteria: ExpectationCriteria;
64
+ weight?: number;
65
+ }
66
+ export interface ExpectationCriteria {
67
+ [key: string]: unknown;
68
+ }
69
+ export interface EmailTestResult {
70
+ testName: string;
71
+ success: boolean;
72
+ score: number;
73
+ duration: number;
74
+ emailsSent: number;
75
+ emailsCaptured: number;
76
+ validationResults: ValidationResult[];
77
+ issues: TestIssue[];
78
+ report: TestReport;
79
+ }
80
+ export interface ValidationResult {
81
+ type: ValidatorType;
82
+ success: boolean;
83
+ score: number;
84
+ details: Record<string, unknown>;
85
+ errors?: string[];
86
+ }
87
+ export interface TestIssue {
88
+ severity: 'error' | 'warning' | 'info';
89
+ type: string;
90
+ message: string;
91
+ details?: Record<string, unknown>;
92
+ }
93
+ export interface TestReport {
94
+ summary: {
95
+ totalTests: number;
96
+ passed: number;
97
+ failed: number;
98
+ score: number;
99
+ duration: number;
100
+ };
101
+ tests: EmailTestResult[];
102
+ metadata: {
103
+ timestamp: string;
104
+ environment: string;
105
+ version: string;
106
+ };
107
+ }
108
+ export interface EmailTestSuiteResult {
109
+ suiteName: string;
110
+ success: boolean;
111
+ score: number;
112
+ duration: number;
113
+ tests: EmailTestResult[];
114
+ report: TestReport;
115
+ }
116
+ export interface TestSetupConfig {
117
+ mockServer?: {
118
+ port?: number;
119
+ host?: string;
120
+ };
121
+ session?: {
122
+ name: string;
123
+ timeout?: number;
124
+ };
125
+ cleanup?: {
126
+ retention?: string;
127
+ };
128
+ }
129
+ export interface TestContext {
130
+ sessionId: string;
131
+ mockServerPort?: number;
132
+ createdAt: Date;
133
+ cleanup: () => Promise<void>;
134
+ }
135
+ export interface CapturedEmail {
136
+ id: string;
137
+ from: string;
138
+ to: string[];
139
+ subject: string;
140
+ body: string;
141
+ html?: string;
142
+ headers: Record<string, string>;
143
+ receivedAt: Date;
144
+ raw?: string;
145
+ }
146
+ export interface SendEmailOptions {
147
+ from: EmailSender;
148
+ to: EmailRecipient[];
149
+ subject: string;
150
+ text?: string;
151
+ html?: string;
152
+ template?: EmailTemplate;
153
+ data?: Record<string, unknown>;
154
+ }
155
+ export interface WaitForEmailsOptions {
156
+ count: number;
157
+ timeout?: number;
158
+ filter?: (email: CapturedEmail) => boolean;
159
+ }
160
+ export interface ValidateEmailsOptions {
161
+ content?: boolean;
162
+ template?: boolean;
163
+ compliance?: boolean;
164
+ smtp?: boolean;
165
+ delivery?: boolean;
166
+ }
167
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ /*
2
+ Copyright (c) 2025 Bernier LLC
3
+
4
+ This file is licensed to the client under a limited-use license.
5
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
6
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;EAME"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@bernierllc/email-test-orchestrator",
3
+ "version": "0.1.0",
4
+ "description": "Service package that orchestrates comprehensive email testing workflows",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "keywords": [
12
+ "email",
13
+ "testing",
14
+ "orchestrator",
15
+ "validation",
16
+ "smtp",
17
+ "test-automation"
18
+ ],
19
+ "author": "Bernier LLC",
20
+ "license": "SEE LICENSE IN LICENSE",
21
+ "dependencies": {
22
+ "@bernierllc/mock-smtp-server": "1.0.0",
23
+ "@bernierllc/email-test-assertions": "1.0.2",
24
+ "@bernierllc/email-sender": "3.0.3",
25
+ "@bernierllc/email-validator": "1.0.3",
26
+ "@bernierllc/email-capture": "1.0.2",
27
+ "@bernierllc/template-engine": "0.2.1",
28
+ "@bernierllc/retry-policy": "0.1.6",
29
+ "@bernierllc/logger": "1.0.3",
30
+ "@bernierllc/email-parser": "0.1.1"
31
+ },
32
+ "devDependencies": {
33
+ "@types/jest": "^29.5.12",
34
+ "@types/node": "^20.11.19",
35
+ "@typescript-eslint/eslint-plugin": "^7.0.1",
36
+ "@typescript-eslint/parser": "^7.0.1",
37
+ "eslint": "^8.56.0",
38
+ "jest": "^29.7.0",
39
+ "ts-jest": "^29.1.2",
40
+ "typescript": "^5.3.3"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc",
44
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
45
+ "test:run": "node --experimental-vm-modules node_modules/jest/bin/jest.js --passWithNoTests",
46
+ "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --passWithNoTests",
47
+ "lint": "eslint src __tests__",
48
+ "clean": "rm -rf dist"
49
+ }
50
+ }