@bigbinary/neeto-playwright-commons 3.1.0 → 3.1.1

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/index.d.ts CHANGED
@@ -1136,6 +1136,13 @@ interface BaseMessageSearchCriteria {
1136
1136
  body: string;
1137
1137
  }
1138
1138
  type MessageSearchCriteria$1 = Partial<BaseMessageSearchCriteria>;
1139
+ type AttachmentFilter$1 = {
1140
+ name: string;
1141
+ type?: string;
1142
+ } | {
1143
+ name?: string;
1144
+ type: string;
1145
+ };
1139
1146
  interface FindMessageFilterOptions$1 {
1140
1147
  receivedAfter: Date;
1141
1148
  timeout: number;
@@ -1158,7 +1165,7 @@ interface MessageInferredData$1 {
1158
1165
  body: string;
1159
1166
  }
1160
1167
  interface Attachment$1 {
1161
- name: string;
1168
+ name: string | null;
1162
1169
  type: string;
1163
1170
  }
1164
1171
  interface FormattedList$1 {
@@ -1176,7 +1183,7 @@ interface FormattedList$1 {
1176
1183
  blobId: string;
1177
1184
  }
1178
1185
  interface AttachmentDetails$1 {
1179
- filename: string;
1186
+ filename: string | null;
1180
1187
  type: string;
1181
1188
  content: Buffer;
1182
1189
  contentType: string;
@@ -1358,11 +1365,15 @@ declare class RailsEmailUtils {
1358
1365
  }: FindOtpFromEmailParams$1) => Promise<string | undefined>;
1359
1366
  /**
1360
1367
  *
1361
- * This method is used to return the attachment based on the attachmentName of first email matching the search criteria. On top of the findMessage method, this method matches the attachment name with the attachments associated to the email. If any attachment matches then it will fetch the attachment details and return. If any attachment file name doesn't contain the substring attachmentName then it will throw an error saying No such attachment exists.
1368
+ * This method is used to return an attachment from the first email matching the search criteria. It supports filtering attachments by name, by MIME content-type, or both. If no matching attachment is found, an error is thrown.
1362
1369
  *
1363
1370
  * Note: In development environment, this method uses the Rails testing HTTP API to fetch attachments. In other environments, it uses Fastmail APIs.
1364
1371
  *
1365
- * attachmentName: A substring matching the attachment file name. It can be both with or without extension.
1372
+ * attachmentFilter: An object used to identify the attachment. At least one of the following keys should be provided:
1373
+ *
1374
+ * name (optional): A substring matched against the attachment file name.
1375
+ *
1376
+ * type (optional): A prefix matched against the attachment MIME content-type (e.g. "text/calendar"). Useful when the attachment has no filename, such as calendar invite (.ics) parts that omit Content-Disposition: attachment.
1366
1377
  *
1367
1378
  * messageSearchCriteria: An object containing the search criteria for matching the messages. The object can contain the keys, from, to, subject and body. All the keys of the object are optional. The values of the object are of string type and are case-insensitive. The following key-value pairs can be used:
1368
1379
  *
@@ -1396,22 +1407,41 @@ declare class RailsEmailUtils {
1396
1407
  *
1397
1408
  * @example
1398
1409
  *
1410
+ * // Match attachment by name
1399
1411
  * test("sample test", async ({ mailerUtils }) => {
1400
- * const message = await mailerUtils.getEmailAttachment(
1401
- * "invite",
1412
+ * const attachment = await mailerUtils.getEmailAttachment(
1413
+ * { name: "invite" },
1402
1414
  * {
1403
- * to: fastmailEmailId,
1404
- * from: senderEmailId,
1405
- * subject: "Event details",
1406
- * }, {
1407
- * receivedAfter: new Date(),
1408
- * timeout: 60 * 1000,
1409
- * expectedEmailCount: 1,
1410
- * }, false);
1415
+ * to: fastmailEmailId,
1416
+ * from: senderEmailId,
1417
+ * subject: "Event details",
1418
+ * },
1419
+ * {
1420
+ * receivedAfter: new Date(),
1421
+ * timeout: 60 * 1000,
1422
+ * expectedEmailCount: 1,
1423
+ * },
1424
+ * false
1425
+ * );
1426
+ * });
1427
+ *
1428
+ * // Match attachment by MIME type (e.g. calendar invite with no filename)
1429
+ * test("sample test", async ({ mailerUtils }) => {
1430
+ * const attachment = await mailerUtils.getEmailAttachment(
1431
+ * { type: "text/calendar" },
1432
+ * {
1433
+ * to: fastmailEmailId,
1434
+ * from: senderEmailId,
1435
+ * subject: "Event details",
1436
+ * }
1437
+ * );
1411
1438
  * });
1412
1439
  * @endexample
1413
1440
  */
1414
- getEmailAttachment: (attachmentName: string, messageSearchCriteria?: MessageSearchCriteria$1, {
1441
+ getEmailAttachment: ({
1442
+ name,
1443
+ type
1444
+ }: AttachmentFilter$1, messageSearchCriteria?: MessageSearchCriteria$1, {
1415
1445
  receivedAfter,
1416
1446
  expectedEmailCount,
1417
1447
  timeout
@@ -1461,6 +1491,13 @@ interface MessageSearchCriteria {
1461
1491
  subject: string;
1462
1492
  body: string;
1463
1493
  }
1494
+ type AttachmentFilter = {
1495
+ name: string;
1496
+ type?: string;
1497
+ } | {
1498
+ name?: string;
1499
+ type: string;
1500
+ };
1464
1501
  interface FindMessageFilterOptions {
1465
1502
  receivedAfter: Date;
1466
1503
  timeout: number;
@@ -1471,7 +1508,7 @@ interface Identifier {
1471
1508
  email: string;
1472
1509
  }
1473
1510
  interface Attachment {
1474
- name: string;
1511
+ name: string | null;
1475
1512
  type: string;
1476
1513
  }
1477
1514
  interface FindOtpFromEmailParams {
@@ -1492,7 +1529,7 @@ interface MessageInferredData {
1492
1529
  body: string;
1493
1530
  }
1494
1531
  interface AttachmentDetails {
1495
- filename: string;
1532
+ filename: string | null;
1496
1533
  type: string;
1497
1534
  content: Buffer;
1498
1535
  contentType: string;
@@ -1697,11 +1734,15 @@ declare class MailerUtils {
1697
1734
  generateRandomEmail: () => string;
1698
1735
  /**
1699
1736
  *
1700
- * This method is used to return the attachment based on the attachmentName of first email matching the search criteria. On top of the findMessage method, this method matches the attachment name with the attachments associated to the email. If any attachment matches then it will fetch the attachment details and return. If any attachment file name doesn't contain the substring attachmentName then it will throw an error saying No such attachment exists.
1737
+ * This method is used to return an attachment from the first email matching the search criteria. It supports filtering attachments by name, by MIME content-type, or both. If no matching attachment is found, an error is thrown.
1701
1738
  *
1702
1739
  * Note: In development environment, this method uses the Rails testing HTTP API to fetch attachments. In other environments, it uses Fastmail APIs.
1703
1740
  *
1704
- * attachmentName: A substring matching the attachment file name. It can be both with or without extension.
1741
+ * attachmentFilter: An object used to identify the attachment. At least one of the following keys should be provided:
1742
+ *
1743
+ * name (optional): A substring matched against the attachment file name.
1744
+ *
1745
+ * type (optional): A prefix matched against the attachment MIME content-type (e.g. "text/calendar"). Useful when the attachment has no filename, such as calendar invite (.ics) parts that omit Content-Disposition: attachment.
1705
1746
  *
1706
1747
  * messageSearchCriteria: An object containing the search criteria for matching the messages. The object can contain the keys, from, to, subject and body. All the keys of the object are optional. The values of the object are of string type and are case-insensitive. The following key-value pairs can be used:
1707
1748
  *
@@ -1735,22 +1776,41 @@ declare class MailerUtils {
1735
1776
  *
1736
1777
  * @example
1737
1778
  *
1779
+ * // Match attachment by name
1738
1780
  * test("sample test", async ({ mailerUtils }) => {
1739
- * const message = await mailerUtils.getEmailAttachment(
1740
- * "invite",
1781
+ * const attachment = await mailerUtils.getEmailAttachment(
1782
+ * { name: "invite" },
1741
1783
  * {
1742
- * to: fastmailEmailId,
1743
- * from: senderEmailId,
1744
- * subject: "Event details",
1745
- * }, {
1746
- * receivedAfter: new Date(),
1747
- * timeout: 60 * 1000,
1748
- * expectedEmailCount: 1,
1749
- * }, false);
1784
+ * to: fastmailEmailId,
1785
+ * from: senderEmailId,
1786
+ * subject: "Event details",
1787
+ * },
1788
+ * {
1789
+ * receivedAfter: new Date(),
1790
+ * timeout: 60 * 1000,
1791
+ * expectedEmailCount: 1,
1792
+ * },
1793
+ * false
1794
+ * );
1795
+ * });
1796
+ *
1797
+ * // Match attachment by MIME type (e.g. calendar invite with no filename)
1798
+ * test("sample test", async ({ mailerUtils }) => {
1799
+ * const attachment = await mailerUtils.getEmailAttachment(
1800
+ * { type: "text/calendar" },
1801
+ * {
1802
+ * to: fastmailEmailId,
1803
+ * from: senderEmailId,
1804
+ * subject: "Event details",
1805
+ * }
1806
+ * );
1750
1807
  * });
1751
1808
  * @endexample
1752
1809
  */
1753
- getEmailAttachment: (attachmentName: string, messageSearchCriteria?: Partial<MessageSearchCriteria>, {
1810
+ getEmailAttachment: ({
1811
+ name,
1812
+ type
1813
+ }: AttachmentFilter, messageSearchCriteria?: Partial<MessageSearchCriteria>, {
1754
1814
  timeout,
1755
1815
  receivedAfter,
1756
1816
  expectedEmailCount
package/index.js CHANGED
@@ -60508,7 +60508,7 @@ class RailsEmailUtils {
60508
60508
  });
60509
60509
  return otp || undefined;
60510
60510
  };
60511
- getEmailAttachment = async (attachmentName, messageSearchCriteria = {}, { receivedAfter = new Date(new Date().valueOf() - 60 * 60 * 1000), expectedEmailCount = 1, timeout = 10_000, } = {}, shouldThrowErrorOnTimeout = true) => {
60511
+ getEmailAttachment = async ({ name, type }, messageSearchCriteria = {}, { receivedAfter = new Date(new Date().valueOf() - 60 * 60 * 1000), expectedEmailCount = 1, timeout = 10_000, } = {}, shouldThrowErrorOnTimeout = true) => {
60512
60512
  const attachmentDetails = (await this.neetoPlaywrightUtilities.executeRecursively({
60513
60513
  callback: async () => {
60514
60514
  const railsEmail = await this.railsEmailClient.getLatestEmail({
@@ -60517,7 +60517,11 @@ class RailsEmailUtils {
60517
60517
  });
60518
60518
  if (!railsEmail)
60519
60519
  return null;
60520
- const attachment = railsEmail.attachments?.find(att => att.name.includes(attachmentName));
60520
+ const attachment = railsEmail.attachments?.find(att => {
60521
+ const matchesName = name ? att.name?.includes(name) : true;
60522
+ const matchesType = type ? att.type?.startsWith(type) : true;
60523
+ return matchesName && matchesType;
60524
+ });
60521
60525
  if (!attachment)
60522
60526
  return null;
60523
60527
  return {
@@ -60701,19 +60705,26 @@ class MailerUtils {
60701
60705
  return codes?.[0];
60702
60706
  };
60703
60707
  generateRandomEmail = () => faker.internet.email({ provider: process.env.FASTMAIL_DOMAIN_NAME });
60704
- getEmailAttachment = async (attachmentName, messageSearchCriteria = {}, { timeout = 10_000, receivedAfter = dateTimeOneHourAgo(), expectedEmailCount = 1, } = {}, shouldThrowErrorOnTimeout = true) => {
60705
- if (IS_DEV_ENV) {
60706
- return this.railsEmailUtils.getEmailAttachment(attachmentName, messageSearchCriteria, { receivedAfter, expectedEmailCount, timeout: timeout / 3 }, shouldThrowErrorOnTimeout);
60707
- }
60708
+ getEmailAttachment = async ({ name, type }, messageSearchCriteria = {}, { timeout = 10_000, receivedAfter = dateTimeOneHourAgo(), expectedEmailCount = 1, } = {}, shouldThrowErrorOnTimeout = true) => {
60709
+ if (IS_DEV_ENV)
60710
+ return this.railsEmailUtils.getEmailAttachment({ name, type }, messageSearchCriteria, { receivedAfter, expectedEmailCount, timeout: timeout / 3 }, shouldThrowErrorOnTimeout);
60708
60711
  const { blobId, attachments: attachmentNameAndTypes } = await this.findMessage(messageSearchCriteria, { expectedEmailCount, receivedAfter, timeout }, shouldThrowErrorOnTimeout);
60709
- const attachment = attachmentNameAndTypes.find(attachment => attachment.name.includes(attachmentName));
60712
+ const attachment = attachmentNameAndTypes.find(att => {
60713
+ const matchesName = name ? att.name?.includes(name) : true;
60714
+ const matchesType = type ? att.type?.startsWith(type) : true;
60715
+ return matchesName && matchesType;
60716
+ });
60710
60717
  if (!attachment)
60711
60718
  throw new Error("No such attachment exists");
60712
60719
  const emailAttachment = await this.fastmailApi.fetchAttachments(blobId, attachment.name);
60713
60720
  const buffer = await emailAttachment.body();
60714
60721
  const parsedEmail = await mailparserExports.simpleParser(buffer);
60715
60722
  const attachments = parsedEmail.attachments;
60716
- return attachments.find(attachment => attachment.filename.includes(attachmentName));
60723
+ return attachments.find(att => {
60724
+ const matchesName = name ? att.filename?.includes(name) : true;
60725
+ const matchesType = type ? att.contentType?.startsWith(type) : true;
60726
+ return matchesName && matchesType;
60727
+ });
60717
60728
  };
60718
60729
  }
60719
60730