@bernierllc/email-testing-suite 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 +21 -0
- package/README.md +347 -0
- package/dist/analytics.d.ts +52 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +211 -0
- package/dist/analytics.js.map +1 -0
- package/dist/best-practices.d.ts +34 -0
- package/dist/best-practices.d.ts.map +1 -0
- package/dist/best-practices.js +268 -0
- package/dist/best-practices.js.map +1 -0
- package/dist/email-testing-suite.d.ts +74 -0
- package/dist/email-testing-suite.d.ts.map +1 -0
- package/dist/email-testing-suite.js +424 -0
- package/dist/email-testing-suite.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/test-patterns.d.ts +48 -0
- package/dist/test-patterns.d.ts.map +1 -0
- package/dist/test-patterns.js +132 -0
- package/dist/test-patterns.js.map +1 -0
- package/dist/types.d.ts +258 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.BestPracticesValidator = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Best practices validator for email testing
|
|
13
|
+
*/
|
|
14
|
+
class BestPracticesValidator {
|
|
15
|
+
/**
|
|
16
|
+
* Validate email against best practices
|
|
17
|
+
*/
|
|
18
|
+
static validateEmail(email) {
|
|
19
|
+
const recommendations = [];
|
|
20
|
+
let score = 100;
|
|
21
|
+
// Check subject line
|
|
22
|
+
if (!email.subject || email.subject.length === 0) {
|
|
23
|
+
recommendations.push({
|
|
24
|
+
category: 'Subject Line',
|
|
25
|
+
priority: 'high',
|
|
26
|
+
title: 'Missing subject line',
|
|
27
|
+
description: 'Email should have a subject line',
|
|
28
|
+
action: 'Add a descriptive subject line to the email',
|
|
29
|
+
});
|
|
30
|
+
score -= 20;
|
|
31
|
+
}
|
|
32
|
+
else if (email.subject.length > 60) {
|
|
33
|
+
recommendations.push({
|
|
34
|
+
category: 'Subject Line',
|
|
35
|
+
priority: 'medium',
|
|
36
|
+
title: 'Subject line too long',
|
|
37
|
+
description: 'Subject line should be under 60 characters for optimal display',
|
|
38
|
+
action: 'Shorten the subject line to 60 characters or less',
|
|
39
|
+
});
|
|
40
|
+
score -= 5;
|
|
41
|
+
}
|
|
42
|
+
// Check HTML content
|
|
43
|
+
if (email.html) {
|
|
44
|
+
if (!email.html.includes('<!DOCTYPE') && !email.html.includes('<html')) {
|
|
45
|
+
recommendations.push({
|
|
46
|
+
category: 'HTML Structure',
|
|
47
|
+
priority: 'medium',
|
|
48
|
+
title: 'Missing HTML structure',
|
|
49
|
+
description: 'Email HTML should include proper DOCTYPE and html tags',
|
|
50
|
+
action: 'Add proper HTML structure to the email template',
|
|
51
|
+
});
|
|
52
|
+
score -= 10;
|
|
53
|
+
}
|
|
54
|
+
// Check for alt text on images
|
|
55
|
+
const imgTags = email.html.match(/<img[^>]*>/g) || [];
|
|
56
|
+
const imagesWithoutAlt = imgTags.filter((tag) => !tag.includes('alt=')).length;
|
|
57
|
+
if (imagesWithoutAlt > 0) {
|
|
58
|
+
recommendations.push({
|
|
59
|
+
category: 'Accessibility',
|
|
60
|
+
priority: 'high',
|
|
61
|
+
title: 'Images missing alt text',
|
|
62
|
+
description: `${imagesWithoutAlt} image(s) do not have alt text`,
|
|
63
|
+
action: 'Add descriptive alt text to all images for accessibility',
|
|
64
|
+
});
|
|
65
|
+
score -= 15;
|
|
66
|
+
}
|
|
67
|
+
// Check for responsive design
|
|
68
|
+
if (!email.html.includes('viewport') && !email.html.includes('media query')) {
|
|
69
|
+
recommendations.push({
|
|
70
|
+
category: 'Responsive Design',
|
|
71
|
+
priority: 'medium',
|
|
72
|
+
title: 'Email may not be mobile-friendly',
|
|
73
|
+
description: 'Email does not appear to include responsive design elements',
|
|
74
|
+
action: 'Add viewport meta tag and media queries for mobile support',
|
|
75
|
+
});
|
|
76
|
+
score -= 10;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Check plain text version
|
|
80
|
+
if (!email.text || email.text.length === 0) {
|
|
81
|
+
recommendations.push({
|
|
82
|
+
category: 'Content',
|
|
83
|
+
priority: 'medium',
|
|
84
|
+
title: 'Missing plain text version',
|
|
85
|
+
description: 'Email should include a plain text version for accessibility',
|
|
86
|
+
action: 'Add a plain text version of the email content',
|
|
87
|
+
});
|
|
88
|
+
score -= 10;
|
|
89
|
+
}
|
|
90
|
+
// Check for unsubscribe link (basic check)
|
|
91
|
+
const hasUnsubscribe = (email.html && email.html.toLowerCase().includes('unsubscribe')) ||
|
|
92
|
+
(email.text && email.text.toLowerCase().includes('unsubscribe'));
|
|
93
|
+
if (!hasUnsubscribe) {
|
|
94
|
+
recommendations.push({
|
|
95
|
+
category: 'Compliance',
|
|
96
|
+
priority: 'high',
|
|
97
|
+
title: 'Missing unsubscribe link',
|
|
98
|
+
description: 'Email should include an unsubscribe link for compliance',
|
|
99
|
+
action: 'Add an unsubscribe link to the email footer',
|
|
100
|
+
});
|
|
101
|
+
score -= 20;
|
|
102
|
+
}
|
|
103
|
+
// Check from address
|
|
104
|
+
if (!email.from || !email.from.includes('@')) {
|
|
105
|
+
recommendations.push({
|
|
106
|
+
category: 'Sender Information',
|
|
107
|
+
priority: 'high',
|
|
108
|
+
title: 'Invalid from address',
|
|
109
|
+
description: 'Email must have a valid from address',
|
|
110
|
+
action: 'Ensure the from address is a valid email address',
|
|
111
|
+
});
|
|
112
|
+
score -= 15;
|
|
113
|
+
}
|
|
114
|
+
// Check recipients
|
|
115
|
+
if (!email.to || email.to.length === 0) {
|
|
116
|
+
recommendations.push({
|
|
117
|
+
category: 'Recipients',
|
|
118
|
+
priority: 'high',
|
|
119
|
+
title: 'No recipients specified',
|
|
120
|
+
description: 'Email must have at least one recipient',
|
|
121
|
+
action: 'Add at least one recipient to the email',
|
|
122
|
+
});
|
|
123
|
+
score -= 20;
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
passed: score >= 70,
|
|
127
|
+
score: Math.max(0, score),
|
|
128
|
+
recommendations,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get recommended test coverage for email type
|
|
133
|
+
*/
|
|
134
|
+
static getRecommendedCoverage(emailType) {
|
|
135
|
+
switch (emailType.toLowerCase()) {
|
|
136
|
+
case 'transactional':
|
|
137
|
+
return {
|
|
138
|
+
validators: ['template', 'compliance', 'performance', 'security'],
|
|
139
|
+
description: 'Transactional emails require template accuracy, compliance, fast delivery, and security',
|
|
140
|
+
};
|
|
141
|
+
case 'marketing':
|
|
142
|
+
return {
|
|
143
|
+
validators: ['template', 'compliance', 'accessibility', 'performance'],
|
|
144
|
+
description: 'Marketing emails need full validation including accessibility and compliance',
|
|
145
|
+
};
|
|
146
|
+
case 'notification':
|
|
147
|
+
return {
|
|
148
|
+
validators: ['template', 'performance'],
|
|
149
|
+
description: 'Notification emails prioritize template accuracy and delivery speed',
|
|
150
|
+
};
|
|
151
|
+
case 'newsletter':
|
|
152
|
+
return {
|
|
153
|
+
validators: ['template', 'compliance', 'accessibility', 'performance'],
|
|
154
|
+
description: 'Newsletters require comprehensive validation for broad audience reach',
|
|
155
|
+
};
|
|
156
|
+
default:
|
|
157
|
+
return {
|
|
158
|
+
validators: ['template', 'compliance', 'accessibility', 'performance', 'security'],
|
|
159
|
+
description: 'Default comprehensive validation for all email types',
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Generate compliance checklist
|
|
165
|
+
*/
|
|
166
|
+
static getComplianceChecklist(region) {
|
|
167
|
+
const baseChecklist = [
|
|
168
|
+
'Include valid from address',
|
|
169
|
+
'Include unsubscribe link',
|
|
170
|
+
'Include physical mailing address',
|
|
171
|
+
'Accurate subject line (no deceptive practices)',
|
|
172
|
+
'Honor opt-out requests promptly',
|
|
173
|
+
];
|
|
174
|
+
if (region === 'EU' || region === 'GLOBAL') {
|
|
175
|
+
baseChecklist.push('Obtain explicit consent (GDPR)', 'Provide data privacy information', 'Enable data portability and deletion requests');
|
|
176
|
+
}
|
|
177
|
+
if (region === 'US' || region === 'GLOBAL') {
|
|
178
|
+
baseChecklist.push('Comply with CAN-SPAM Act', 'Include valid postal address', 'Process opt-out within 10 business days');
|
|
179
|
+
}
|
|
180
|
+
return baseChecklist;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get accessibility guidelines
|
|
184
|
+
*/
|
|
185
|
+
static getAccessibilityGuidelines() {
|
|
186
|
+
return [
|
|
187
|
+
{
|
|
188
|
+
category: 'Accessibility',
|
|
189
|
+
priority: 'high',
|
|
190
|
+
title: 'Provide alt text for all images',
|
|
191
|
+
description: 'Screen readers need descriptive alt text to convey image content',
|
|
192
|
+
action: 'Add meaningful alt attributes to all img tags',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
category: 'Accessibility',
|
|
196
|
+
priority: 'high',
|
|
197
|
+
title: 'Use semantic HTML',
|
|
198
|
+
description: 'Proper heading hierarchy and semantic elements improve screen reader navigation',
|
|
199
|
+
action: 'Use h1-h6 tags appropriately and semantic HTML elements',
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
category: 'Accessibility',
|
|
203
|
+
priority: 'medium',
|
|
204
|
+
title: 'Ensure sufficient color contrast',
|
|
205
|
+
description: 'Text should have at least 4.5:1 contrast ratio with background',
|
|
206
|
+
action: 'Use color contrast checker and adjust colors as needed',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
category: 'Accessibility',
|
|
210
|
+
priority: 'medium',
|
|
211
|
+
title: 'Avoid relying solely on color',
|
|
212
|
+
description: 'Important information should not be conveyed by color alone',
|
|
213
|
+
action: 'Use text labels, icons, or patterns in addition to color',
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
category: 'Accessibility',
|
|
217
|
+
priority: 'low',
|
|
218
|
+
title: 'Include plain text version',
|
|
219
|
+
description: 'Plain text version provides fallback for accessibility tools',
|
|
220
|
+
action: 'Generate plain text version of all HTML emails',
|
|
221
|
+
},
|
|
222
|
+
];
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Get performance optimization tips
|
|
226
|
+
*/
|
|
227
|
+
static getPerformanceOptimizationTips() {
|
|
228
|
+
return [
|
|
229
|
+
{
|
|
230
|
+
category: 'Performance',
|
|
231
|
+
priority: 'high',
|
|
232
|
+
title: 'Optimize image sizes',
|
|
233
|
+
description: 'Large images increase email size and load time',
|
|
234
|
+
action: 'Compress images and use appropriate dimensions',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
category: 'Performance',
|
|
238
|
+
priority: 'high',
|
|
239
|
+
title: 'Minimize CSS and inline styles',
|
|
240
|
+
description: 'Excessive CSS increases email size',
|
|
241
|
+
action: 'Inline critical CSS and remove unused styles',
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
category: 'Performance',
|
|
245
|
+
priority: 'medium',
|
|
246
|
+
title: 'Limit external resources',
|
|
247
|
+
description: 'External resources may be blocked or slow to load',
|
|
248
|
+
action: 'Inline images and styles when possible',
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
category: 'Performance',
|
|
252
|
+
priority: 'medium',
|
|
253
|
+
title: 'Keep total size under 102KB',
|
|
254
|
+
description: 'Gmail clips messages over 102KB',
|
|
255
|
+
action: 'Optimize content to stay under size threshold',
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
category: 'Performance',
|
|
259
|
+
priority: 'low',
|
|
260
|
+
title: 'Use web-safe fonts',
|
|
261
|
+
description: 'Custom fonts may not render consistently across clients',
|
|
262
|
+
action: 'Use web-safe fonts with appropriate fallbacks',
|
|
263
|
+
},
|
|
264
|
+
];
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
exports.BestPracticesValidator = BestPracticesValidator;
|
|
268
|
+
//# sourceMappingURL=best-practices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"best-practices.js","sourceRoot":"","sources":["../src/best-practices.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { EmailTestingSuiteConfig, EmailTemplateTest, EmailFlowTest, EmailTest, EmailTestResult, EmailFlowResult, EmailSuiteResult, TestingEnvironment, DataSchema } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Complete email testing solution with opinionated defaults
|
|
4
|
+
*/
|
|
5
|
+
export declare class EmailTestingSuite {
|
|
6
|
+
private config;
|
|
7
|
+
private mockServer;
|
|
8
|
+
private orchestrator;
|
|
9
|
+
private running;
|
|
10
|
+
private capturedEmails;
|
|
11
|
+
private testHistory;
|
|
12
|
+
constructor(config?: EmailTestingSuiteConfig);
|
|
13
|
+
/**
|
|
14
|
+
* Merge user config with opinionated defaults
|
|
15
|
+
*/
|
|
16
|
+
private mergeWithDefaults;
|
|
17
|
+
/**
|
|
18
|
+
* Start the email testing environment
|
|
19
|
+
*/
|
|
20
|
+
start(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Stop the email testing environment
|
|
23
|
+
*/
|
|
24
|
+
stop(): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Reset the testing environment
|
|
27
|
+
*/
|
|
28
|
+
reset(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Test an email template with comprehensive validation
|
|
31
|
+
*/
|
|
32
|
+
testEmailTemplate(spec: EmailTemplateTest): Promise<EmailTestResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Test an email flow with multiple steps
|
|
35
|
+
*/
|
|
36
|
+
testEmailFlow(flow: EmailFlowTest): Promise<EmailFlowResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Run a suite of email tests
|
|
39
|
+
*/
|
|
40
|
+
runTestSuite(tests: EmailTest[]): Promise<EmailSuiteResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Get the current testing environment state
|
|
43
|
+
*/
|
|
44
|
+
getTestingEnvironment(): TestingEnvironment;
|
|
45
|
+
/**
|
|
46
|
+
* Generate test data based on a schema
|
|
47
|
+
*/
|
|
48
|
+
generateTestData(schema: DataSchema): Record<string, any>;
|
|
49
|
+
/**
|
|
50
|
+
* Type guard for EmailTemplateTest
|
|
51
|
+
*/
|
|
52
|
+
private isEmailTemplateTest;
|
|
53
|
+
/**
|
|
54
|
+
* Type guard for EmailFlowTest
|
|
55
|
+
*/
|
|
56
|
+
private isEmailFlowTest;
|
|
57
|
+
/**
|
|
58
|
+
* Generate summary from test results
|
|
59
|
+
*/
|
|
60
|
+
private generateSummary;
|
|
61
|
+
/**
|
|
62
|
+
* Generate a simple UUID
|
|
63
|
+
*/
|
|
64
|
+
private generateUUID;
|
|
65
|
+
/**
|
|
66
|
+
* Get test history
|
|
67
|
+
*/
|
|
68
|
+
getTestHistory(): EmailTestResult[];
|
|
69
|
+
/**
|
|
70
|
+
* Clear test history
|
|
71
|
+
*/
|
|
72
|
+
clearTestHistory(): void;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=email-testing-suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-testing-suite.d.ts","sourceRoot":"","sources":["../src/email-testing-suite.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,uBAAuB,EACvB,iBAAiB,EACjB,aAAa,EACb,SAAS,EACT,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EAQX,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,WAAW,CAAyB;gBAEhC,MAAM,GAAE,uBAA4B;IAIhD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6CzB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;OAEG;IACG,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAoG1E;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC;IAmFlE;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA8CjE;;OAEG;IACH,qBAAqB,IAAI,kBAAkB;IAY3C;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAsCzD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,eAAe;IA0BvB;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;OAEG;IACH,cAAc,IAAI,eAAe,EAAE;IAInC;;OAEG;IACH,gBAAgB,IAAI,IAAI;CAGzB"}
|