@bigbinary/neeto-playwright-commons 1.11.20 → 1.12.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/index.cjs.js CHANGED
@@ -141,6 +141,10 @@ const THIRD_PARTY_ROUTES = {
141
141
  const NEETO_ROUTES = {
142
142
  imageUploader: "/neeto_image_uploader_engine",
143
143
  };
144
+ const FASTMAIL_ROUTES = {
145
+ authorize: "https://api.fastmail.com/.well-known/jmap",
146
+ api: "https://api.fastmail.com/jmap/api/",
147
+ };
144
148
 
145
149
  const ENVIRONMENT = {
146
150
  development: "development",
@@ -3499,6 +3503,7 @@ const getImagePathAndName = (localImagePath) => {
3499
3503
 
3500
3504
  class CustomCommands {
3501
3505
  constructor(page, request, baseURL = process.env.BASE_URL) {
3506
+ this.waitUntilTimeout = (timeout) => new Promise(resolve => setTimeout(resolve, timeout));
3502
3507
  this.interceptMultipleResponses = ({ responseUrl = "", responseStatus = 200, times = 1, baseUrl, customPageContext, timeout = 35000, } = {}) => {
3503
3508
  const pageContext = customPageContext !== null && customPageContext !== void 0 ? customPageContext : this.page;
3504
3509
  return Promise.all([...new Array(times)].map(() => pageContext.waitForResponse((response) => {
@@ -3514,18 +3519,19 @@ class CustomCommands {
3514
3519
  return false;
3515
3520
  }, { timeout })));
3516
3521
  };
3517
- this.recursiveMethod = async (callback, condition, timeout, startTime) => {
3522
+ this.recursiveMethod = async (callback, condition, timeout, startTime, iteration) => {
3518
3523
  if (Date.now() - timeout >= startTime) {
3519
3524
  return false;
3520
3525
  }
3521
3526
  else if (await condition()) {
3522
3527
  return await callback();
3523
3528
  }
3524
- return await this.recursiveMethod(callback, condition, timeout, startTime);
3529
+ await this.waitUntilTimeout(Math.pow(2, iteration) * 1000);
3530
+ return await this.recursiveMethod(callback, condition, timeout, startTime, iteration + 1);
3525
3531
  };
3526
3532
  this.executeRecursively = async ({ callback, condition, timeout = 5000, }) => {
3527
3533
  const startTime = Date.now();
3528
- await this.recursiveMethod(callback, condition, timeout, startTime);
3534
+ return await this.recursiveMethod(callback, condition, timeout, startTime, 1);
3529
3535
  };
3530
3536
  /**
3531
3537
  * @deprecated Use verifyToast instead.
@@ -3680,6 +3686,127 @@ class CustomCommands {
3680
3686
  }
3681
3687
  }
3682
3688
 
3689
+ const dateTimeOneHourAgo = () => new Date(new Date().valueOf() - 60 * 60 * 1000);
3690
+ class MailerUtils {
3691
+ constructor(neetoPlaywrightUtilities) {
3692
+ this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
3693
+ this.authorizeAndSetAccountId = async () => {
3694
+ const response = await this.neetoPlaywrightUtilities.apiRequest({
3695
+ method: "get",
3696
+ url: FASTMAIL_ROUTES.authorize,
3697
+ headers: this.fastmailHeaders,
3698
+ });
3699
+ const { primaryAccounts: { "urn:ietf:params:jmap:mail": accountId }, } = await response.json();
3700
+ this.accountId = accountId;
3701
+ };
3702
+ this.fastmailApiRequest = async (method, body) => {
3703
+ const response = await this.neetoPlaywrightUtilities.apiRequest({
3704
+ method: "post",
3705
+ url: FASTMAIL_ROUTES.api,
3706
+ headers: this.fastmailHeaders,
3707
+ data: {
3708
+ using: ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
3709
+ methodCalls: [[method, { accountId: this.accountId, ...body }, "0"]],
3710
+ },
3711
+ });
3712
+ return response === null || response === void 0 ? void 0 : response.json();
3713
+ };
3714
+ this.queryEmail = async (messageSearchCriteria, { receivedAfter = dateTimeOneHourAgo(), page = 1, itemsPerPage = 50, }) => {
3715
+ const limit = itemsPerPage;
3716
+ const position = (page - 1) * itemsPerPage;
3717
+ if (itemsPerPage > 100 || itemsPerPage < 1)
3718
+ throw new Error("itemsPerPage should be in the range of 1-100");
3719
+ const body = {
3720
+ filter: { ...messageSearchCriteria, after: receivedAfter.toISOString() },
3721
+ sort: [{ property: "receivedAt", isAscending: false }],
3722
+ limit,
3723
+ position,
3724
+ };
3725
+ const { methodResponses: [[, { ids, total }]], } = await this.fastmailApiRequest("Email/query", body);
3726
+ return { ids, total };
3727
+ };
3728
+ this.getEmails = async (ids) => {
3729
+ const messageDetailsBody = {
3730
+ ids,
3731
+ bodyProperties: ["type"],
3732
+ fetchHTMLBodyValues: true,
3733
+ };
3734
+ const { methodResponses: [[, { list }]], } = await this.fastmailApiRequest("Email/get", messageDetailsBody);
3735
+ const formattedList = list.map((listItem) => {
3736
+ const { id, from, to, bodyValues, cc, bcc, receivedAt, subject } = listItem;
3737
+ const emailBody = Object.values(ramda.pluck("value", bodyValues)).join(" ");
3738
+ const emailBodyWithStrippedHead = emailBody.split("</head>").at(-1);
3739
+ const links = emailBodyWithStrippedHead.match(/(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])/g);
3740
+ const codes = emailBodyWithStrippedHead.match(/(?<![#/])\b\d{4,}\b/g);
3741
+ const contentRecognitions = {
3742
+ links: links && [...links],
3743
+ codes: codes && [...codes],
3744
+ };
3745
+ const html = {
3746
+ body: emailBody,
3747
+ ...contentRecognitions,
3748
+ };
3749
+ const text = {
3750
+ body: emailBody.replace(/<\/[^>]+(>|$)/g, ""),
3751
+ ...contentRecognitions,
3752
+ };
3753
+ return {
3754
+ html,
3755
+ text,
3756
+ id,
3757
+ from,
3758
+ to,
3759
+ cc,
3760
+ bcc,
3761
+ received: new Date(receivedAt),
3762
+ subject,
3763
+ };
3764
+ });
3765
+ return formattedList;
3766
+ };
3767
+ this.listMessages = async (messageSearchCriteria = {}, listMessagesFilterCriteria = {}) => {
3768
+ const { ids } = await this.queryEmail(messageSearchCriteria, listMessagesFilterCriteria);
3769
+ return this.getEmails(ids);
3770
+ };
3771
+ this.findMessage = async (messageSearchCriteria = {}, { timeout = 10000, receivedAfter = dateTimeOneHourAgo(), } = {}, shouldThrowErrorOnTimeout = true) => {
3772
+ const ids = (await this.neetoPlaywrightUtilities.executeRecursively({
3773
+ callback: async () => {
3774
+ const { ids } = await this.queryEmail(messageSearchCriteria, {
3775
+ receivedAfter,
3776
+ });
3777
+ return ids;
3778
+ },
3779
+ condition: async () => {
3780
+ const { total } = await this.queryEmail(messageSearchCriteria, {
3781
+ receivedAfter,
3782
+ });
3783
+ return total > 0;
3784
+ },
3785
+ timeout,
3786
+ }));
3787
+ if (!ids) {
3788
+ if (shouldThrowErrorOnTimeout)
3789
+ throw new Error("Timed out waiting for matching message");
3790
+ return {};
3791
+ }
3792
+ return (await this.getEmails(ids))[0];
3793
+ };
3794
+ this.findOtpFromEmail = async ({ email, subjectSubstring = OTP_EMAIL_PATTERN, timeout = 2 * 60 * 1000, receivedAfter = new Date(), }) => {
3795
+ const { html: { codes }, } = await this.findMessage({ to: email, subject: subjectSubstring }, { timeout, receivedAfter });
3796
+ return codes === null || codes === void 0 ? void 0 : codes[0];
3797
+ };
3798
+ this.generateRandomEmail = () => faker.faker.internet.email({
3799
+ provider: process.env.FASTMAIL_DOMAIN_NAME,
3800
+ });
3801
+ if (!process.env.NEETO_AUTOMATION_FASTMAIL_API_KEY)
3802
+ throw new Error("Please set the environment variable NEETO_AUTOMATION_FASTMAIL_API_KEYS. Credentials can be found in the Automation Credentials vault in the BigBinary 1Password account.");
3803
+ this.fastmailHeaders = {
3804
+ "Content-Type": "application/json",
3805
+ Authorization: `Bearer ${process.env.NEETO_AUTOMATION_FASTMAIL_API_KEY}`,
3806
+ };
3807
+ }
3808
+ }
3809
+
3683
3810
  class MailosaurUtils {
3684
3811
  constructor(mailosaur) {
3685
3812
  this.getEmailContent = ({ email, subjectSubstring = "", timeout = 2 * 60 * 1000, receivedAfter = new Date(), }) => this.mailosaur.messages.get(this.serverId, { sentTo: email, subject: subjectSubstring }, { timeout, receivedAfter });
@@ -3733,6 +3860,11 @@ const commands = {
3733
3860
  const mailosaurUtils = new MailosaurUtils(mailosaur);
3734
3861
  await use(mailosaurUtils);
3735
3862
  },
3863
+ mailerUtils: async ({ neetoPlaywrightUtilities }, use) => {
3864
+ const mailerUtils = new MailerUtils(neetoPlaywrightUtilities);
3865
+ await mailerUtils.authorizeAndSetAccountId();
3866
+ await use(mailerUtils);
3867
+ },
3736
3868
  };
3737
3869
 
3738
3870
  const generateStagingData = (product = "invoice") => {
@@ -149256,6 +149388,7 @@ exports.ENVIRONMENT = ENVIRONMENT;
149256
149388
  exports.EXPANDED_FONT_SIZE = EXPANDED_FONT_SIZE;
149257
149389
  exports.EditorPage = EditorPage;
149258
149390
  exports.EmbedBase = EmbedBase;
149391
+ exports.FASTMAIL_ROUTES = FASTMAIL_ROUTES;
149259
149392
  exports.FONT_SIZE_SELECTORS = FONT_SIZE_SELECTORS;
149260
149393
  exports.GLOBAL_TRANSLATIONS_PATTERN = GLOBAL_TRANSLATIONS_PATTERN;
149261
149394
  exports.GOOGLE_CALENDAR_DATE_FORMAT = GOOGLE_CALENDAR_DATE_FORMAT;
@@ -149276,6 +149409,7 @@ exports.MEMBER_FORM_SELECTORS = MEMBER_FORM_SELECTORS;
149276
149409
  exports.MEMBER_SELECTORS = MEMBER_SELECTORS;
149277
149410
  exports.MEMBER_TEXTS = MEMBER_TEXTS;
149278
149411
  exports.MERGE_TAGS_SELECTORS = MERGE_TAGS_SELECTORS;
149412
+ exports.MailerUtils = MailerUtils;
149279
149413
  exports.MailosaurUtils = MailosaurUtils;
149280
149414
  exports.NEETO_AUTH_BASE_URL = NEETO_AUTH_BASE_URL;
149281
149415
  exports.NEETO_EDITOR_SELECTORS = NEETO_EDITOR_SELECTORS;