@bigbinary/neeto-playwright-commons 1.12.10 → 1.13.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.d.ts CHANGED
@@ -85,9 +85,10 @@ declare class CustomCommands {
85
85
  responses: string[];
86
86
  request: APIRequestContext;
87
87
  baseURL: string | undefined;
88
- csrfToken: string | null;
88
+ csrfToken: string | null | undefined;
89
89
  constructor(page: Page, request: APIRequestContext, baseURL?: string | undefined);
90
90
  private waitUntilTimeout;
91
+ private initializeCsrfToken;
91
92
  /**
92
93
  *
93
94
  * Command to wait until a response with URL responseUrl is found. Optionally,
@@ -719,7 +720,7 @@ declare const generateStagingData: (product?: string) => {
719
720
  email: string;
720
721
  };
721
722
  declare const _default: _playwright_test.TestType<_playwright_test.PlaywrightTestArgs & _playwright_test.PlaywrightTestOptions & Browser, _playwright_test.PlaywrightWorkerArgs & _playwright_test.PlaywrightWorkerOptions>;
722
- declare const i18nFixture: Fixtures<I18nPlaywrightFixture, PlaywrightWorkerArgs & PlaywrightWorkerOptions, PlaywrightTestArgs & PlaywrightTestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
723
+ declare const i18nFixture: Fixtures<PlaywrightTestArgs & PlaywrightTestOptions, I18nPlaywrightFixture, PlaywrightTestArgs & PlaywrightTestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
723
724
  declare class ThankYouPage {
724
725
  page: Page;
725
726
  neetoPlaywrightUtilities: CustomCommands;
@@ -1683,19 +1684,22 @@ declare class WebhooksPage {
1683
1684
  ...fieldsToBeVerified
1684
1685
  }: VerifyWebhookDeliveryByEventParams) => Promise<void>;
1685
1686
  }
1687
+ interface ZapierPageInitializer {
1688
+ page: Page;
1689
+ neetoPlaywrightUtilities: CustomCommands;
1690
+ integrationRouteIndex?: string;
1691
+ mailerUtils: MailerUtils;
1692
+ }
1686
1693
  declare class ZapierPage extends IntegrationBase {
1687
1694
  zapierWebPage: Page;
1688
- mailosaur: MailosaurClient;
1689
1695
  continueButton: Locator;
1696
+ mailerUtils: MailerUtils;
1690
1697
  constructor({
1691
1698
  page,
1692
1699
  neetoPlaywrightUtilities,
1693
- integrationRouteIndex
1694
- }: {
1695
- page: Page;
1696
- neetoPlaywrightUtilities: CustomCommands;
1697
- integrationRouteIndex?: string;
1698
- });
1700
+ integrationRouteIndex,
1701
+ mailerUtils
1702
+ }: ZapierPageInitializer);
1699
1703
  /**
1700
1704
  *
1701
1705
  * Logs into zapier web app. It takes the following parameters:
@@ -1771,7 +1775,7 @@ declare class ZapierPage extends IntegrationBase {
1771
1775
  submittedEmail: string;
1772
1776
  zapTriggeredAfter: Date;
1773
1777
  productName: string;
1774
- }) => Promise<mailosaur_lib_models.Message>;
1778
+ }) => Promise<FormattedList | Record<string, never>>;
1775
1779
  /**
1776
1780
  *
1777
1781
  * Skips test if Zapier task limit is exhausted.
package/index.js CHANGED
@@ -3,7 +3,7 @@ import fs__default, { readFileSync, writeFileSync as writeFileSync$1, unlinkSync
3
3
  import * as Path from 'path';
4
4
  import Path__default from 'path';
5
5
  import { execSync } from 'child_process';
6
- import test$1, { expect, test as test$2, defineConfig, devices } from '@playwright/test';
6
+ import test$1, { expect, test as test$2, chromium as chromium$1, defineConfig, devices } from '@playwright/test';
7
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';
@@ -111,7 +111,7 @@ const CREDENTIALS = {
111
111
  };
112
112
  const OTP_EMAIL_PATTERN = "is your login code";
113
113
  const SLACK_DEFAULT_CHANNEL = "general";
114
- const ZAPIER_TEST_EMAIL = (product) => `neeto-${product}-zapier-test@${process.env.INTEGRATION_MAILOSAUR_SERVER_ID}.mailosaur.net`;
114
+ const ZAPIER_TEST_EMAIL = (product) => `neeto-${product}-zapier-test@${process.env.FASTMAIL_DOMAIN_NAME}`;
115
115
  // constants for translation
116
116
  const SINGULAR = { count: 1 };
117
117
  const PLURAL = { count: 2 };
@@ -3451,6 +3451,12 @@ const getImagePathAndName = (localImagePath) => {
3451
3451
  class CustomCommands {
3452
3452
  constructor(page, request, baseURL = process.env.BASE_URL) {
3453
3453
  this.waitUntilTimeout = (timeout) => new Promise(resolve => setTimeout(resolve, timeout));
3454
+ this.initializeCsrfToken = async () => {
3455
+ this.csrfToken = await this.page
3456
+ .locator("[name='csrf-token']")
3457
+ .getAttribute("content");
3458
+ return this.csrfToken;
3459
+ };
3454
3460
  this.interceptMultipleResponses = ({ responseUrl = "", responseStatus = 200, times = 1, baseUrl, customPageContext, timeout = 35000, } = {}) => {
3455
3461
  const pageContext = customPageContext !== null && customPageContext !== void 0 ? customPageContext : this.page;
3456
3462
  return Promise.all([...new Array(times)].map(() => pageContext.waitForResponse((response) => {
@@ -3533,12 +3539,13 @@ class CustomCommands {
3533
3539
  };
3534
3540
  this.apiRequest = async ({ url, failOnStatusCode = true, headers: additionalHeaders, body: data, method = "get", params = {}, ...otherOptions }) => {
3535
3541
  var _a;
3542
+ const csrfToken = (_a = this.csrfToken) !== null && _a !== void 0 ? _a : (await this.initializeCsrfToken());
3536
3543
  const requestOptions = {
3537
3544
  failOnStatusCode,
3538
3545
  headers: {
3539
3546
  ...additionalHeaders,
3540
3547
  "accept-encoding": "gzip",
3541
- "x-csrf-token": (_a = this.csrfToken) !== null && _a !== void 0 ? _a : "",
3548
+ "x-csrf-token": csrfToken !== null && csrfToken !== void 0 ? csrfToken : "",
3542
3549
  },
3543
3550
  data,
3544
3551
  ...otherOptions,
@@ -3628,13 +3635,6 @@ class CustomCommands {
3628
3635
  this.responses = [];
3629
3636
  this.request = request;
3630
3637
  this.baseURL = baseURL;
3631
- this.page
3632
- .locator("[name='csrf-token']")
3633
- .getAttribute("content")
3634
- .then(csrfToken => {
3635
- this.csrfToken = csrfToken;
3636
- }, reason => console.error(reason) // eslint-disable-line
3637
- );
3638
3638
  }
3639
3639
  }
3640
3640
 
@@ -11621,6 +11621,32 @@ class FastmailApi {
11621
11621
  }
11622
11622
  }
11623
11623
 
11624
+ const basicHTMLContent = (content) => `
11625
+ <!DOCTYPE html>
11626
+ <html lang="en">
11627
+ <head>
11628
+ <meta charset="UTF-8" />
11629
+ <meta name="viewport" content="width=device-width" />
11630
+ </head>
11631
+ <body>
11632
+ ${content}
11633
+ </body>
11634
+ </html>`;
11635
+ const hexToRGB = (hex) => {
11636
+ let r = "", g = "", b = "";
11637
+ if (hex.length === 4) {
11638
+ r = `0x${hex[1]}${hex[1]}`;
11639
+ g = `0x${hex[2]}${hex[2]}`;
11640
+ b = `0x${hex[3]}${hex[3]}`;
11641
+ }
11642
+ else if (hex.length === 7) {
11643
+ r = `0x${hex[1]}${hex[2]}`;
11644
+ g = `0x${hex[3]}${hex[4]}`;
11645
+ b = `0x${hex[5]}${hex[6]}`;
11646
+ }
11647
+ return `rgb(${Number(r)}, ${Number(g)}, ${Number(b)})`;
11648
+ };
11649
+
11624
11650
  const dateTimeOneHourAgo = () => new Date(new Date().valueOf() - 60 * 60 * 1000);
11625
11651
  class MailerUtils {
11626
11652
  constructor(neetoPlaywrightUtilities) {
@@ -11661,7 +11687,10 @@ class MailerUtils {
11661
11687
  body: emailBody,
11662
11688
  ...contentRecognitions,
11663
11689
  };
11664
- const document = new DOMParser().parseFromString(emailBody, "text/html").documentElement;
11690
+ const wrappedHtml = /<html[\s>]/i.test(emailBody)
11691
+ ? emailBody
11692
+ : basicHTMLContent(emailBody);
11693
+ const document = new DOMParser().parseFromString(wrappedHtml, "text/html").documentElement;
11665
11694
  const text = {
11666
11695
  body: ((_a = document === null || document === void 0 ? void 0 : document.getElementsByTagName("body")[0].textContent) === null || _a === void 0 ? void 0 : _a.trim()) || "",
11667
11696
  ...contentRecognitions,
@@ -20689,8 +20718,9 @@ const mergeTaxonomies = async (translations, page) => {
20689
20718
 
20690
20719
  const i18nFixture = {
20691
20720
  i18n: [
20692
- async ({ page }, use) => {
20721
+ async ({}, use) => {
20693
20722
  const translation = readTranslations();
20723
+ const page = await (await chromium$1.launch()).newPage();
20694
20724
  const taxonomies = await mergeTaxonomies(translation, page);
20695
20725
  const options = {
20696
20726
  debug: false,
@@ -20720,17 +20750,19 @@ const i18nFixture = {
20720
20750
  const i18nInitialized = await initI18n({
20721
20751
  plugins: [removeTagsProcessor, sentenceCaseProcessor],
20722
20752
  options,
20723
- // Fetch translations in every test or fetch once
20724
20753
  cache: true,
20725
20754
  });
20755
+ await page.close();
20726
20756
  await use(i18nInitialized);
20727
20757
  },
20728
- // Run as auto fixture to be available through all tests by getI18nInstance()
20729
- { auto: true },
20758
+ { auto: true, scope: "worker" },
20759
+ ],
20760
+ t: [
20761
+ async ({ i18n }, use) => {
20762
+ await use(i18n.t);
20763
+ },
20764
+ { scope: "worker" },
20730
20765
  ],
20731
- t: async ({ i18n }, use) => {
20732
- await use(i18n.t);
20733
- },
20734
20766
  };
20735
20767
 
20736
20768
  const THANK_YOU_SELECTORS = {
@@ -20923,32 +20955,6 @@ const EMBED_SELECTORS = {
20923
20955
  previewElementPopupButton: "preview-element-popup-button",
20924
20956
  };
20925
20957
 
20926
- const basicHTMLContent = (content) => `
20927
- <!DOCTYPE html>
20928
- <html lang="en">
20929
- <head>
20930
- <meta charset="UTF-8" />
20931
- <meta name="viewport" content="width=device-width" />
20932
- </head>
20933
- <body>
20934
- ${content}
20935
- </body>
20936
- </html>`;
20937
- const hexToRGB = (hex) => {
20938
- let r = "", g = "", b = "";
20939
- if (hex.length === 4) {
20940
- r = `0x${hex[1]}${hex[1]}`;
20941
- g = `0x${hex[2]}${hex[2]}`;
20942
- b = `0x${hex[3]}${hex[3]}`;
20943
- }
20944
- else if (hex.length === 7) {
20945
- r = `0x${hex[1]}${hex[2]}`;
20946
- g = `0x${hex[3]}${hex[4]}`;
20947
- b = `0x${hex[5]}${hex[6]}`;
20948
- }
20949
- return `rgb(${Number(r)}, ${Number(g)}, ${Number(b)})`;
20950
- };
20951
-
20952
20958
  class EmbedBase {
20953
20959
  constructor({ context, page, neetoPlaywrightUtilities, appName, }) {
20954
20960
  this.initializeEmbedPage = async ({ embedType, embedCode, customElementText = "Click here", }) => {
@@ -23769,7 +23775,7 @@ const ZAPIER_SELECTORS = {
23769
23775
  };
23770
23776
 
23771
23777
  class ZapierPage extends IntegrationBase {
23772
- constructor({ page, neetoPlaywrightUtilities, integrationRouteIndex, }) {
23778
+ constructor({ page, neetoPlaywrightUtilities, integrationRouteIndex, mailerUtils, }) {
23773
23779
  super({
23774
23780
  page,
23775
23781
  integration: "zapier",
@@ -23910,7 +23916,7 @@ class ZapierPage extends IntegrationBase {
23910
23916
  timeout: 10000,
23911
23917
  });
23912
23918
  };
23913
- this.verifyZapIsTriggered = ({ productName, submittedEmail, zapTriggeredAfter, }) => this.mailosaur.messages.get(process.env.INTEGRATION_MAILOSAUR_SERVER_ID, { sentTo: ZAPIER_TEST_EMAIL(productName), body: submittedEmail }, { timeout: 5 * 60000, receivedAfter: zapTriggeredAfter });
23919
+ this.verifyZapIsTriggered = ({ productName, submittedEmail, zapTriggeredAfter, }) => this.mailerUtils.findMessage({ to: ZAPIER_TEST_EMAIL(productName), body: submittedEmail }, { timeout: 2 * 60000, receivedAfter: zapTriggeredAfter });
23914
23920
  this.skipIfTaskLimitIsExhausted = async () => {
23915
23921
  var _a;
23916
23922
  // Zapier provides 100 free task limit for free account; skip test if it's exhausted
@@ -23962,16 +23968,12 @@ class ZapierPage extends IntegrationBase {
23962
23968
  });
23963
23969
  await this.verifyIntegrationStatus("disconnected");
23964
23970
  };
23965
- if (isNil(process.env.INTEGRATION_MAILOSAUR_API_KEY) ||
23966
- isNil(process.env.INTEGRATION_MAILOSAUR_SERVER_ID)) {
23967
- throw new Error("ENV variable INTEGRATION_MAILOSAUR_API_KEY or INTEGRATION_MAILOSAUR_SERVER_ID is not properly configured");
23968
- }
23969
23971
  if (isNil(process.env.ZAPIER_LOGIN_PASSWORD) ||
23970
23972
  isNil(process.env.ZAPIER_LOGIN_EMAIL) ||
23971
23973
  isNil(process.env.ZAP_ID)) {
23972
23974
  throw new Error("ENV variable ZAPIER_LOGIN_PASSWORD or ZAPIER_LOGIN_EMAIL or ZAP_ID is not properly configured");
23973
23975
  }
23974
- this.mailosaur = new MailosaurClient(process.env.INTEGRATION_MAILOSAUR_API_KEY);
23976
+ this.mailerUtils = mailerUtils;
23975
23977
  }
23976
23978
  }
23977
23979