@bigbinary/neeto-playwright-commons 1.11.20 → 1.12.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
@@ -22,7 +22,6 @@ interface ExecuteRecursivelyParams {
22
22
  condition: GenericCallback;
23
23
  timeout: number;
24
24
  }
25
- type ExecuteRecursively = (params: ExecuteRecursivelyParams) => Promise<void>;
26
25
  interface VerifySuccessToastParams {
27
26
  message: string;
28
27
  closeAfterVerification: boolean;
@@ -85,6 +84,7 @@ declare class CustomCommands {
85
84
  request: APIRequestContext;
86
85
  baseURL: string | undefined;
87
86
  constructor(page: Page, request: APIRequestContext, baseURL?: string | undefined);
87
+ private waitUntilTimeout;
88
88
  /**
89
89
  *
90
90
  * Command to wait until a response with URL responseUrl is found. Optionally,
@@ -130,7 +130,11 @@ declare class CustomCommands {
130
130
  * });
131
131
  * @endexample
132
132
  */
133
- executeRecursively: ExecuteRecursively;
133
+ executeRecursively: ({
134
+ callback,
135
+ condition,
136
+ timeout
137
+ }: ExecuteRecursivelyParams) => Promise<unknown>;
134
138
  /**
135
139
  * @deprecated Use verifyToast instead.
136
140
  */
@@ -362,6 +366,223 @@ declare class CustomCommands {
362
366
  content: string;
363
367
  }) => Promise<void>;
364
368
  }
369
+ type Range<N extends number, Acc extends number[] = []> = Acc["length"] extends N ? Exclude<Acc[number], 0 | Acc["length"]> | N : Range<N, [...Acc, Acc["length"]]>;
370
+ interface MessageSearchCriteria {
371
+ from: string;
372
+ to: string;
373
+ subject: string;
374
+ body: string;
375
+ }
376
+ interface FindMessageFilterOptions {
377
+ receivedAfter: Date;
378
+ timeout: number;
379
+ }
380
+ interface Identifier {
381
+ name: string;
382
+ email: string;
383
+ }
384
+ interface FindOtpFromEmailParams {
385
+ email: string;
386
+ subjectSubstring?: string;
387
+ timeout?: number;
388
+ receivedAfter?: Date;
389
+ }
390
+ interface ListMessagesFilterCriteria {
391
+ receivedAfter: Date;
392
+ page: number;
393
+ itemsPerPage: Range<100>;
394
+ }
395
+ interface MessageInferredData {
396
+ links: string[] | null;
397
+ codes: string[] | null;
398
+ body: string;
399
+ }
400
+ interface FormattedList {
401
+ html: MessageInferredData;
402
+ text: MessageInferredData;
403
+ id: string;
404
+ from: Identifier[];
405
+ to: Identifier[];
406
+ cc: Identifier[];
407
+ bcc: Identifier[];
408
+ replyTo: Identifier[];
409
+ received: string;
410
+ subject: string;
411
+ }
412
+ declare class MailerUtils {
413
+ private neetoPlaywrightUtilities;
414
+ private fastmailHeaders;
415
+ accountId: string | undefined;
416
+ constructor(neetoPlaywrightUtilities: CustomCommands);
417
+ /**
418
+ *
419
+ * Used to authorize the Fastmail API and get the account details. There is usually no need to call this method since this is invoked when the fixture is setup and will save the credentials for all the future callback of mailerUtils methods.
420
+ *
421
+ * This method doesn't accept any arguments and doesn't return anything.
422
+ *
423
+ */
424
+ authorizeAndSetAccountId: () => Promise<void>;
425
+ private fastmailApiRequest;
426
+ private queryEmail;
427
+ private getEmails;
428
+ /**
429
+ *
430
+ * This method is used to list a set of messages matching a specific search criteria. It immediately returns the available list of messages matching the search criteria and doesn't wait until a matching message is found. Due to this reason delays in email deliveries should be accounted while using this method. This method is useful in asserting negative test cases and asserting a list of emails matching a certain pattern.
431
+ *
432
+ * Note: If the intention is to find a matching message within a certain time frame, prefer using the findMessage method.
433
+ *
434
+ * 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:
435
+ *
436
+ * from: The complete email address from which the email was sent.
437
+ *
438
+ * to: The complete email address to which the email was sent to.
439
+ *
440
+ * subject: A complete string or a substring used to match the subject of the email.
441
+ *
442
+ * body: A complete string or a substring used to match the body of the email.
443
+ *
444
+ * messageFilterCriteria (optional): An object containing the criteria which are used to filter the messages that match the search criteria. The object can contain the keys receivedAfter, page and itemsPerPage. The following key-value pairs can be used:
445
+ *
446
+ * receivedAfter: A JavaScript Date object used to filter the matching messages on the date-time of email delivery. Defaults to one hour before the method call.
447
+ *
448
+ * page: A number specifying the page number for paginating the results. Starts from 1 (default value). If a page number greater than the total number of matching emails is specified, an empty array will be returned.
449
+ *
450
+ * itemsPerPage: A number specifying the number of results per page. Default value is 50. The value can range from 1 to 100.
451
+ *
452
+ * Returns an array of objects with details about the emails matching the search and filter criteria. The object will have the following shape.
453
+ *
454
+ * html: Contains an object with the codes (Array of number strings having length greater than or equal to 4 in the email), links (Array of links in the email) and the body of the email with the HTML tags intact.
455
+ *
456
+ * text: Contains an object with the codes (Array of number strings having length greater than or equal to 4 in the email), links (Array of links in the email) and the body of the email with the HTML tags stripped off.
457
+ *
458
+ * id: A unique identifier string used to identify the email.
459
+ *
460
+ * from: An array of objects containing the name and email of the sender of the email.
461
+ *
462
+ * to: An array of objects containing the name and email of the receiver of the email.
463
+ *
464
+ * cc: An array of objects containing the name and email of the sender of the email as part of the cc list.
465
+ *
466
+ * replyTo: An array of objects containing the name and email of the individuals to whom replies should be directed.
467
+ *
468
+ * bcc: An array of objects containing the name and email of the recipients of the email as part of the bcc list.
469
+ *
470
+ * received: A JavaScript Date object containing the date-time of the email delivery.
471
+ *
472
+ * subject: A string containing the subject of the email.
473
+ *
474
+ * @example
475
+ *
476
+ * test("sample test", async ({ mailerUtils }) => {
477
+ * const message = await mailerUtils.listMessages({
478
+ * to: fastmailEmailId,
479
+ * from: senderEmailId,
480
+ * subject: "login code",
481
+ * body: "neeto",
482
+ * }, {
483
+ * receivedAfter: new Date(),
484
+ * page: 1,
485
+ * itemsPerPage: 50,
486
+ * });
487
+ * });
488
+ * @endexample
489
+ */
490
+ listMessages: (messageSearchCriteria?: Partial<MessageSearchCriteria> | undefined, listMessagesFilterCriteria?: Partial<ListMessagesFilterCriteria> | undefined) => Promise<FormattedList[]>;
491
+ /**
492
+ *
493
+ * This method is used to find a first email matching the search criteria. On top of the listMessage method, this method waits until a specific mail is received or the timeout is exceeded. This method is useful for fetching an email once an action is triggered since it waits for the message delivery and can be customized according to delays in email deliveries.
494
+ *
495
+ * 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:
496
+ *
497
+ * from: The complete email address from which the email was sent.
498
+ *
499
+ * to: The complete email address to which the email was sent to.
500
+ *
501
+ * subject: A complete string or a substring used to match the subject of the email.
502
+ *
503
+ * body: A complete string or a substring used to match the body of the email.
504
+ *
505
+ * messageFilterCriteria (optional): An object containing the criteria which are used to filter the messages that match the search criteria. The object can contain the keys receivedAfter, page and itemsPerPage. The following key-value pairs can be used:
506
+ *
507
+ * receivedAfter: A JavaScript Date object used to filter the matching messages on the date-time of email delivery. Defaults to one hour before the method call.
508
+ *
509
+ * timeout: A number indicating the number of milliseconds to retry fetching the message before timing out. Defaults to 10 seconds.
510
+ *
511
+ * shouldThrowErrorOnTimeout (optional): A boolean value indicating whether the method show throw an error if a matching message is not found within the timeout time. If set to false, no error is thrown if the timeout is exceeded and just returns an empty object. Defaults to true.
512
+ *
513
+ * Returns an object with details about the first email matching the search and filter criteria. The object will have the following shape.
514
+ *
515
+ * html: Contains an object with the codes (Array of number strings having length greater than or equal to 4 in the email), links (Array of links in the email) and the body of the email with the HTML tags intact.
516
+ *
517
+ * text: Contains an object with the codes (Array of number strings having length greater than or equal to 4 in the email), links (Array of links in the email) and the body of the email with the HTML tags stripped off.
518
+ *
519
+ * id: A unique identifier string used to identify the email.
520
+ *
521
+ * from: An array of objects containing the name and email of the sender of the email.
522
+ *
523
+ * to: An array of objects containing the name and email of the receiver of the email.
524
+ *
525
+ * cc: An array of objects containing the name and email of the sender of the email as part of the cc list.
526
+ *
527
+ * replyTo: An array of objects containing the name and email of the individuals to whom replies should be directed.
528
+ *
529
+ * bcc: An array of objects containing the name and email of the recipients of the email as part of the bcc list.
530
+ *
531
+ * received: A JavaScript Date object containing the date-time of the email delivery.
532
+ *
533
+ * subject: A string containing the subject of the email.
534
+ *
535
+ * @example
536
+ *
537
+ * test("sample test", async ({ mailerUtils }) => {
538
+ * const message = await mailerUtils.listMessages({
539
+ * to: fastmailEmailId,
540
+ * from: senderEmailId,
541
+ * subject: "login code",
542
+ * body: "neeto",
543
+ * }, {
544
+ * receivedAfter: new Date(),
545
+ * timeout: 60 * 1000,
546
+ * }, false);
547
+ * });
548
+ * @endexample
549
+ */
550
+ findMessage: (messageSearchCriteria?: Partial<MessageSearchCriteria>, {
551
+ timeout,
552
+ receivedAfter
553
+ }?: Partial<FindMessageFilterOptions> | undefined, shouldThrowErrorOnTimeout?: boolean) => Promise<FormattedList | Record<string, never>>;
554
+ /**
555
+ *
556
+ * A helper method that is used to find the first code value from the matching email body. This method has been built to match the Neeto OTP emails.
557
+ *
558
+ * The method accepts the following named arguments:
559
+ *
560
+ * email: The recipient email address used to find the email
561
+ *
562
+ * subjectSubstring: The subject of the email used to match it. Defaults to the string is your login code to match Neeto OTP emails
563
+ *
564
+ * timeout: The timeout duration number in milliseconds, which when exceeded without finding matching emails, the method throws an error. Default to 2 minutes.
565
+ *
566
+ * receivedAfter: = A JavaScript Date object used to filter the matching messages on the date-time of email delivery. Defaults to the time of method call.
567
+ *
568
+ * The method returns the OTP as a string from the matching email.
569
+ *
570
+ */
571
+ findOtpFromEmail: ({
572
+ email,
573
+ subjectSubstring,
574
+ timeout,
575
+ receivedAfter
576
+ }: FindOtpFromEmailParams) => Promise<string | undefined>;
577
+ /**
578
+ *
579
+ * Generates a random Fastmail email based on the value of the FASTMAIL_DOMAIN_NAME environment variable.
580
+ *
581
+ * Returns a random mixed-cased email ending with the FASTMAIL_DOMAIN_NAME.
582
+ *
583
+ */
584
+ generateRandomEmail: () => string;
585
+ }
365
586
  interface EmailContentParams {
366
587
  email: string;
367
588
  subjectSubstring?: string;
@@ -460,6 +681,7 @@ interface CustomFixture {
460
681
  page: Page;
461
682
  mailosaur: MailosaurClient;
462
683
  mailosaurUtils: MailosaurUtils;
684
+ mailerUtils: MailerUtils;
463
685
  }
464
686
  type Commands = Fixtures<CustomFixture, PlaywrightWorkerArgs & PlaywrightWorkerOptions, PlaywrightTestArgs & PlaywrightTestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
465
687
  declare const commands: Commands;
@@ -2971,6 +3193,10 @@ declare const THIRD_PARTY_ROUTES: {
2971
3193
  declare const NEETO_ROUTES: {
2972
3194
  imageUploader: string;
2973
3195
  };
3196
+ declare const FASTMAIL_ROUTES: {
3197
+ authorize: string;
3198
+ api: string;
3199
+ };
2974
3200
  declare const networkConditions: Record<"Slow 3G" | "Fast 3G" | "No Throttling", Protocol.Network.emulateNetworkConditionsParameters>;
2975
3201
  /**
2976
3202
  *
@@ -5444,4 +5670,4 @@ interface Overrides {
5444
5670
  * @endexample
5445
5671
  */
5446
5672
  declare const definePlaywrightConfig: (overrides: Overrides) => _playwright_test.PlaywrightTestConfig<{}, {}>;
5447
- export { API_ROUTES, BASE_URL, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, CHAT_WIDGET_TEXTS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, type CustomFixture, DESCRIPTION_EDITOR_TEXTS, EMBED_SELECTORS, EMOJI_LABEL, ENVIRONMENT, EXPANDED_FONT_SIZE, EditorPage, EmbedBase, FONT_SIZE_SELECTORS, GLOBAL_TRANSLATIONS_PATTERN, GOOGLE_CALENDAR_DATE_FORMAT, GOOGLE_LOGIN_TEXTS, GooglePage, HELP_CENTER_SELECTORS, HelpAndProfilePage, INTEGRATIONS_TEXTS, INTEGRATION_SELECTORS, IS_STAGING_ENV, ImageUploader, IntegrationBase, KEYBOARD_SHORTCUTS_SELECTORS, LIST_MODIFIER_SELECTORS, LIST_MODIFIER_TAGS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MEMBER_TEXTS, MERGE_TAGS_SELECTORS, MailosaurUtils, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, NEETO_IMAGE_UPLOADER_SELECTORS, NEETO_ROUTES, NEETO_TEXT_MODIFIER_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PLURAL, PROFILE_SECTION_SELECTORS, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SELECT_COUNTRY, SIGNUP_SELECTORS, SINGULAR, SLACK_DATA_QA_SELECTORS, SLACK_DEFAULT_CHANNEL, SLACK_SELECTORS, SLACK_WEB_TEXTS, STORAGE_STATE, SidebarSection, SlackPage, TAB_SELECTORS, TAGS_SELECTORS, TEXT_MODIFIER_ROLES, TEXT_MODIFIER_SELECTORS, TEXT_MODIFIER_TAGS, THANK_YOU_SELECTORS, THIRD_PARTY_ROUTES, TOASTR_MESSAGES, TagsPage, TeamMembers, ThankYouPage, USER_AGENTS, WebhooksPage, ZAPIER_LIMIT_EXHAUSTED_MESSAGE, ZAPIER_SELECTORS, ZAPIER_TEST_EMAIL, ZAPIER_WEB_TEXTS, ZapierPage, basicHTMLContent, clearCredentials, commands, cpuThrottlingUsingCDP, currencyUtils, decodeQRCodeFromFile, definePlaywrightConfig, executeWithThrottledResources, extractSubdomainFromError, filterUtils, generateRandomBypassEmail, generateStagingData, getByDataQA, getGlobalUserState, getImagePathAndName, getListCount, headerUtils, hexToRGB, hyphenize, i18nFixture, initializeCredentials, initializeTotp, joinHyphenCase, joinString, login, loginWithoutSSO, memberUtils, networkConditions, networkThrottlingUsingCDP, readFileSyncIfExists, removeCredentialFile, shouldSkipSetupAndTeardown, skipTest, squish, _default as stealthTest, tableUtils, toCamelCase, updateCredentials, writeDataToFile };
5673
+ export { API_ROUTES, BASE_URL, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, CHAT_WIDGET_TEXTS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, type CustomFixture, DESCRIPTION_EDITOR_TEXTS, EMBED_SELECTORS, EMOJI_LABEL, ENVIRONMENT, EXPANDED_FONT_SIZE, EditorPage, EmbedBase, FASTMAIL_ROUTES, FONT_SIZE_SELECTORS, GLOBAL_TRANSLATIONS_PATTERN, GOOGLE_CALENDAR_DATE_FORMAT, GOOGLE_LOGIN_TEXTS, GooglePage, HELP_CENTER_SELECTORS, HelpAndProfilePage, INTEGRATIONS_TEXTS, INTEGRATION_SELECTORS, IS_STAGING_ENV, ImageUploader, IntegrationBase, KEYBOARD_SHORTCUTS_SELECTORS, LIST_MODIFIER_SELECTORS, LIST_MODIFIER_TAGS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MEMBER_TEXTS, MERGE_TAGS_SELECTORS, MailerUtils, MailosaurUtils, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, NEETO_IMAGE_UPLOADER_SELECTORS, NEETO_ROUTES, NEETO_TEXT_MODIFIER_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PLURAL, PROFILE_SECTION_SELECTORS, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SELECT_COUNTRY, SIGNUP_SELECTORS, SINGULAR, SLACK_DATA_QA_SELECTORS, SLACK_DEFAULT_CHANNEL, SLACK_SELECTORS, SLACK_WEB_TEXTS, STORAGE_STATE, SidebarSection, SlackPage, TAB_SELECTORS, TAGS_SELECTORS, TEXT_MODIFIER_ROLES, TEXT_MODIFIER_SELECTORS, TEXT_MODIFIER_TAGS, THANK_YOU_SELECTORS, THIRD_PARTY_ROUTES, TOASTR_MESSAGES, TagsPage, TeamMembers, ThankYouPage, USER_AGENTS, WebhooksPage, ZAPIER_LIMIT_EXHAUSTED_MESSAGE, ZAPIER_SELECTORS, ZAPIER_TEST_EMAIL, ZAPIER_WEB_TEXTS, ZapierPage, basicHTMLContent, clearCredentials, commands, cpuThrottlingUsingCDP, currencyUtils, decodeQRCodeFromFile, definePlaywrightConfig, executeWithThrottledResources, extractSubdomainFromError, filterUtils, generateRandomBypassEmail, generateStagingData, getByDataQA, getGlobalUserState, getImagePathAndName, getListCount, headerUtils, hexToRGB, hyphenize, i18nFixture, initializeCredentials, initializeTotp, joinHyphenCase, joinString, login, loginWithoutSSO, memberUtils, networkConditions, networkThrottlingUsingCDP, readFileSyncIfExists, removeCredentialFile, shouldSkipSetupAndTeardown, skipTest, squish, _default as stealthTest, tableUtils, toCamelCase, updateCredentials, writeDataToFile };
package/index.js CHANGED
@@ -4,7 +4,7 @@ import * as Path from 'path';
4
4
  import Path__default from 'path';
5
5
  import { execSync } from 'child_process';
6
6
  import test$1, { expect, test as test$2, defineConfig, devices } from '@playwright/test';
7
- import { curry, not, isEmpty as isEmpty$1, isNil, isNotNil, mergeDeepLeft, mergeAll } from 'ramda';
7
+ import { curry, not, isEmpty as isEmpty$1, pluck, isNil, isNotNil, mergeDeepLeft, mergeAll } from 'ramda';
8
8
  import require$$0$1 from 'util';
9
9
  import { faker } from '@faker-js/faker';
10
10
  import MailosaurClient from 'mailosaur';
@@ -94,6 +94,10 @@ const THIRD_PARTY_ROUTES = {
94
94
  const NEETO_ROUTES = {
95
95
  imageUploader: "/neeto_image_uploader_engine",
96
96
  };
97
+ const FASTMAIL_ROUTES = {
98
+ authorize: "https://api.fastmail.com/.well-known/jmap",
99
+ api: "https://api.fastmail.com/jmap/api/",
100
+ };
97
101
 
98
102
  const ENVIRONMENT = {
99
103
  development: "development",
@@ -3452,6 +3456,7 @@ const getImagePathAndName = (localImagePath) => {
3452
3456
 
3453
3457
  class CustomCommands {
3454
3458
  constructor(page, request, baseURL = process.env.BASE_URL) {
3459
+ this.waitUntilTimeout = (timeout) => new Promise(resolve => setTimeout(resolve, timeout));
3455
3460
  this.interceptMultipleResponses = ({ responseUrl = "", responseStatus = 200, times = 1, baseUrl, customPageContext, timeout = 35000, } = {}) => {
3456
3461
  const pageContext = customPageContext !== null && customPageContext !== void 0 ? customPageContext : this.page;
3457
3462
  return Promise.all([...new Array(times)].map(() => pageContext.waitForResponse((response) => {
@@ -3467,18 +3472,19 @@ class CustomCommands {
3467
3472
  return false;
3468
3473
  }, { timeout })));
3469
3474
  };
3470
- this.recursiveMethod = async (callback, condition, timeout, startTime) => {
3475
+ this.recursiveMethod = async (callback, condition, timeout, startTime, iteration) => {
3471
3476
  if (Date.now() - timeout >= startTime) {
3472
3477
  return false;
3473
3478
  }
3474
3479
  else if (await condition()) {
3475
3480
  return await callback();
3476
3481
  }
3477
- return await this.recursiveMethod(callback, condition, timeout, startTime);
3482
+ await this.waitUntilTimeout(Math.pow(2, iteration) * 1000);
3483
+ return await this.recursiveMethod(callback, condition, timeout, startTime, iteration + 1);
3478
3484
  };
3479
3485
  this.executeRecursively = async ({ callback, condition, timeout = 5000, }) => {
3480
3486
  const startTime = Date.now();
3481
- await this.recursiveMethod(callback, condition, timeout, startTime);
3487
+ return await this.recursiveMethod(callback, condition, timeout, startTime, 1);
3482
3488
  };
3483
3489
  /**
3484
3490
  * @deprecated Use verifyToast instead.
@@ -3633,6 +3639,128 @@ class CustomCommands {
3633
3639
  }
3634
3640
  }
3635
3641
 
3642
+ const dateTimeOneHourAgo = () => new Date(new Date().valueOf() - 60 * 60 * 1000);
3643
+ class MailerUtils {
3644
+ constructor(neetoPlaywrightUtilities) {
3645
+ this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
3646
+ this.authorizeAndSetAccountId = async () => {
3647
+ const response = await this.neetoPlaywrightUtilities.apiRequest({
3648
+ method: "get",
3649
+ url: FASTMAIL_ROUTES.authorize,
3650
+ headers: this.fastmailHeaders,
3651
+ });
3652
+ const { primaryAccounts: { "urn:ietf:params:jmap:mail": accountId }, } = await response.json();
3653
+ this.accountId = accountId;
3654
+ };
3655
+ this.fastmailApiRequest = async (method, body) => {
3656
+ const response = await this.neetoPlaywrightUtilities.apiRequest({
3657
+ method: "post",
3658
+ url: FASTMAIL_ROUTES.api,
3659
+ headers: this.fastmailHeaders,
3660
+ data: {
3661
+ using: ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
3662
+ methodCalls: [[method, { accountId: this.accountId, ...body }, "0"]],
3663
+ },
3664
+ });
3665
+ return response === null || response === void 0 ? void 0 : response.json();
3666
+ };
3667
+ this.queryEmail = async (messageSearchCriteria, { receivedAfter = dateTimeOneHourAgo(), page = 1, itemsPerPage = 50, }) => {
3668
+ const limit = itemsPerPage;
3669
+ const position = (page - 1) * itemsPerPage;
3670
+ if (itemsPerPage > 100 || itemsPerPage < 1)
3671
+ throw new Error("itemsPerPage should be in the range of 1-100");
3672
+ const body = {
3673
+ filter: { ...messageSearchCriteria, after: receivedAfter.toISOString() },
3674
+ sort: [{ property: "receivedAt", isAscending: false }],
3675
+ limit,
3676
+ position,
3677
+ };
3678
+ const { methodResponses: [[, { ids, total }]], } = await this.fastmailApiRequest("Email/query", body);
3679
+ return { ids, total };
3680
+ };
3681
+ this.getEmails = async (ids) => {
3682
+ const messageDetailsBody = {
3683
+ ids,
3684
+ bodyProperties: ["type"],
3685
+ fetchHTMLBodyValues: true,
3686
+ };
3687
+ const { methodResponses: [[, { list }]], } = await this.fastmailApiRequest("Email/get", messageDetailsBody);
3688
+ const formattedList = list.map((listItem) => {
3689
+ const { id, from, to, bodyValues, cc, bcc, replyTo, receivedAt, subject, } = listItem;
3690
+ const emailBody = Object.values(pluck("value", bodyValues)).join(" ");
3691
+ const emailBodyWithStrippedHead = emailBody.split("</head>").at(-1);
3692
+ const links = emailBodyWithStrippedHead.match(/(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])/g);
3693
+ const codes = emailBodyWithStrippedHead.match(/(?<![#/])\b\d{4,}\b/g);
3694
+ const contentRecognitions = {
3695
+ links: links && [...links],
3696
+ codes: codes && [...codes],
3697
+ };
3698
+ const html = {
3699
+ body: emailBody,
3700
+ ...contentRecognitions,
3701
+ };
3702
+ const text = {
3703
+ body: emailBody.replace(/<\/[^>]+(>|$)/g, ""),
3704
+ ...contentRecognitions,
3705
+ };
3706
+ return {
3707
+ html,
3708
+ text,
3709
+ id,
3710
+ from,
3711
+ to,
3712
+ cc,
3713
+ bcc,
3714
+ replyTo,
3715
+ received: new Date(receivedAt),
3716
+ subject,
3717
+ };
3718
+ });
3719
+ return formattedList;
3720
+ };
3721
+ this.listMessages = async (messageSearchCriteria = {}, listMessagesFilterCriteria = {}) => {
3722
+ const { ids } = await this.queryEmail(messageSearchCriteria, listMessagesFilterCriteria);
3723
+ return this.getEmails(ids);
3724
+ };
3725
+ this.findMessage = async (messageSearchCriteria = {}, { timeout = 10000, receivedAfter = dateTimeOneHourAgo(), } = {}, shouldThrowErrorOnTimeout = true) => {
3726
+ const ids = (await this.neetoPlaywrightUtilities.executeRecursively({
3727
+ callback: async () => {
3728
+ const { ids } = await this.queryEmail(messageSearchCriteria, {
3729
+ receivedAfter,
3730
+ });
3731
+ return ids;
3732
+ },
3733
+ condition: async () => {
3734
+ const { total } = await this.queryEmail(messageSearchCriteria, {
3735
+ receivedAfter,
3736
+ });
3737
+ return total > 0;
3738
+ },
3739
+ timeout,
3740
+ }));
3741
+ if (!ids) {
3742
+ if (shouldThrowErrorOnTimeout)
3743
+ throw new Error("Timed out waiting for matching message");
3744
+ return {};
3745
+ }
3746
+ return (await this.getEmails(ids))[0];
3747
+ };
3748
+ this.findOtpFromEmail = async ({ email, subjectSubstring = OTP_EMAIL_PATTERN, timeout = 2 * 60 * 1000, receivedAfter = new Date(), }) => {
3749
+ const { html: { codes }, } = await this.findMessage({ to: email, subject: subjectSubstring }, { timeout, receivedAfter });
3750
+ return codes === null || codes === void 0 ? void 0 : codes[0];
3751
+ };
3752
+ this.generateRandomEmail = () => faker.internet.email({
3753
+ provider: process.env.FASTMAIL_DOMAIN_NAME,
3754
+ });
3755
+ if (!process.env.NEETO_AUTOMATION_FASTMAIL_API_KEY)
3756
+ 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.");
3757
+ this.fastmailHeaders = {
3758
+ "Content-Type": "application/json",
3759
+ Authorization: `Bearer ${process.env.NEETO_AUTOMATION_FASTMAIL_API_KEY}`,
3760
+ };
3761
+ }
3762
+ }
3763
+
3636
3764
  class MailosaurUtils {
3637
3765
  constructor(mailosaur) {
3638
3766
  this.getEmailContent = ({ email, subjectSubstring = "", timeout = 2 * 60 * 1000, receivedAfter = new Date(), }) => this.mailosaur.messages.get(this.serverId, { sentTo: email, subject: subjectSubstring }, { timeout, receivedAfter });
@@ -3686,6 +3814,11 @@ const commands = {
3686
3814
  const mailosaurUtils = new MailosaurUtils(mailosaur);
3687
3815
  await use(mailosaurUtils);
3688
3816
  },
3817
+ mailerUtils: async ({ neetoPlaywrightUtilities }, use) => {
3818
+ const mailerUtils = new MailerUtils(neetoPlaywrightUtilities);
3819
+ await mailerUtils.authorizeAndSetAccountId();
3820
+ await use(mailerUtils);
3821
+ },
3689
3822
  };
3690
3823
 
3691
3824
  const generateStagingData = (product = "invoice") => {
@@ -149194,5 +149327,5 @@ const definePlaywrightConfig = (overrides) => {
149194
149327
  });
149195
149328
  };
149196
149329
 
149197
- export { API_ROUTES, BASE_URL, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, CHAT_WIDGET_TEXTS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, DESCRIPTION_EDITOR_TEXTS, EMBED_SELECTORS, EMOJI_LABEL, ENVIRONMENT, EXPANDED_FONT_SIZE, EditorPage, EmbedBase, FONT_SIZE_SELECTORS, GLOBAL_TRANSLATIONS_PATTERN, GOOGLE_CALENDAR_DATE_FORMAT, GOOGLE_LOGIN_TEXTS, GooglePage, HELP_CENTER_SELECTORS, HelpAndProfilePage, INTEGRATIONS_TEXTS, INTEGRATION_SELECTORS, IS_STAGING_ENV, ImageUploader, IntegrationBase, KEYBOARD_SHORTCUTS_SELECTORS, LIST_MODIFIER_SELECTORS, LIST_MODIFIER_TAGS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MEMBER_TEXTS, MERGE_TAGS_SELECTORS, MailosaurUtils, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, NEETO_IMAGE_UPLOADER_SELECTORS, NEETO_ROUTES, NEETO_TEXT_MODIFIER_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PLURAL, PROFILE_SECTION_SELECTORS, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SELECT_COUNTRY, SIGNUP_SELECTORS, SINGULAR, SLACK_DATA_QA_SELECTORS, SLACK_DEFAULT_CHANNEL, SLACK_SELECTORS, SLACK_WEB_TEXTS, STORAGE_STATE, SidebarSection, SlackPage, TAB_SELECTORS, TAGS_SELECTORS, TEXT_MODIFIER_ROLES, TEXT_MODIFIER_SELECTORS, TEXT_MODIFIER_TAGS, THANK_YOU_SELECTORS, THIRD_PARTY_ROUTES, TOASTR_MESSAGES, TagsPage, TeamMembers, ThankYouPage, USER_AGENTS, WebhooksPage, ZAPIER_LIMIT_EXHAUSTED_MESSAGE, ZAPIER_SELECTORS, ZAPIER_TEST_EMAIL, ZAPIER_WEB_TEXTS, ZapierPage, basicHTMLContent, clearCredentials, commands, cpuThrottlingUsingCDP, currencyUtils, decodeQRCodeFromFile, definePlaywrightConfig, executeWithThrottledResources, extractSubdomainFromError, filterUtils, generateRandomBypassEmail, generateStagingData, getByDataQA, getGlobalUserState, getImagePathAndName, getListCount, headerUtils, hexToRGB, hyphenize, i18nFixture, initializeCredentials, initializeTotp, joinHyphenCase, joinString, login, loginWithoutSSO, memberUtils, networkConditions, networkThrottlingUsingCDP, readFileSyncIfExists, removeCredentialFile, shouldSkipSetupAndTeardown, skipTest, squish, stealth as stealthTest, tableUtils, toCamelCase, updateCredentials, writeDataToFile };
149330
+ export { API_ROUTES, BASE_URL, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, CHAT_WIDGET_TEXTS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, DESCRIPTION_EDITOR_TEXTS, EMBED_SELECTORS, EMOJI_LABEL, ENVIRONMENT, EXPANDED_FONT_SIZE, EditorPage, EmbedBase, FASTMAIL_ROUTES, FONT_SIZE_SELECTORS, GLOBAL_TRANSLATIONS_PATTERN, GOOGLE_CALENDAR_DATE_FORMAT, GOOGLE_LOGIN_TEXTS, GooglePage, HELP_CENTER_SELECTORS, HelpAndProfilePage, INTEGRATIONS_TEXTS, INTEGRATION_SELECTORS, IS_STAGING_ENV, ImageUploader, IntegrationBase, KEYBOARD_SHORTCUTS_SELECTORS, LIST_MODIFIER_SELECTORS, LIST_MODIFIER_TAGS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MEMBER_TEXTS, MERGE_TAGS_SELECTORS, MailerUtils, MailosaurUtils, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, NEETO_IMAGE_UPLOADER_SELECTORS, NEETO_ROUTES, NEETO_TEXT_MODIFIER_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PLURAL, PROFILE_SECTION_SELECTORS, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SELECT_COUNTRY, SIGNUP_SELECTORS, SINGULAR, SLACK_DATA_QA_SELECTORS, SLACK_DEFAULT_CHANNEL, SLACK_SELECTORS, SLACK_WEB_TEXTS, STORAGE_STATE, SidebarSection, SlackPage, TAB_SELECTORS, TAGS_SELECTORS, TEXT_MODIFIER_ROLES, TEXT_MODIFIER_SELECTORS, TEXT_MODIFIER_TAGS, THANK_YOU_SELECTORS, THIRD_PARTY_ROUTES, TOASTR_MESSAGES, TagsPage, TeamMembers, ThankYouPage, USER_AGENTS, WebhooksPage, ZAPIER_LIMIT_EXHAUSTED_MESSAGE, ZAPIER_SELECTORS, ZAPIER_TEST_EMAIL, ZAPIER_WEB_TEXTS, ZapierPage, basicHTMLContent, clearCredentials, commands, cpuThrottlingUsingCDP, currencyUtils, decodeQRCodeFromFile, definePlaywrightConfig, executeWithThrottledResources, extractSubdomainFromError, filterUtils, generateRandomBypassEmail, generateStagingData, getByDataQA, getGlobalUserState, getImagePathAndName, getListCount, headerUtils, hexToRGB, hyphenize, i18nFixture, initializeCredentials, initializeTotp, joinHyphenCase, joinString, login, loginWithoutSSO, memberUtils, networkConditions, networkThrottlingUsingCDP, readFileSyncIfExists, removeCredentialFile, shouldSkipSetupAndTeardown, skipTest, squish, stealth as stealthTest, tableUtils, toCamelCase, updateCredentials, writeDataToFile };
149198
149331
  //# sourceMappingURL=index.js.map