@bigbinary/neeto-playwright-commons 1.4.6 → 1.5.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
@@ -1,5 +1,6 @@
1
1
  import * as _playwright_test from '@playwright/test';
2
2
  import { Page, APIRequestContext, Response, APIResponse, Fixtures, PlaywrightWorkerArgs, PlaywrightWorkerOptions, PlaywrightTestArgs, PlaywrightTestOptions } from '@playwright/test';
3
+ import MailosaurClient from 'mailosaur';
3
4
  import { I18nPlaywrightFixture } from 'playwright-i18next-fixture';
4
5
 
5
6
  interface InterceptMultipleResponsesParams {
@@ -49,9 +50,26 @@ declare class CustomCommands {
49
50
  verifyFieldValue: VerifyFieldValue;
50
51
  }
51
52
 
53
+ interface FetchOtpFromEmailFilterParameters {
54
+ email: string;
55
+ subjectSubstring?: string;
56
+ timeout?: number;
57
+ receivedAfter?: Date;
58
+ }
59
+ type FetchOtpFromEmail = (props: FetchOtpFromEmailFilterParameters) => Promise<string | undefined>;
60
+ declare class MailosaurUtils {
61
+ mailosaur: MailosaurClient;
62
+ serverId: string;
63
+ constructor(mailosaur: MailosaurClient);
64
+ fetchOtpFromEmail: FetchOtpFromEmail;
65
+ generateRandomMailosaurEmail: () => string;
66
+ }
67
+
52
68
  interface CustomFixture {
53
69
  neetoPlaywrightUtilities: CustomCommands;
54
70
  page: Page;
71
+ mailosaur: MailosaurClient;
72
+ mailosaurUtils: MailosaurUtils;
55
73
  }
56
74
  type Commands = Fixtures<CustomFixture, PlaywrightWorkerArgs & PlaywrightWorkerOptions, PlaywrightTestArgs & PlaywrightTestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
57
75
  declare const commands: Commands;
@@ -100,6 +118,7 @@ declare const CREDENTIALS: {
100
118
  email: string;
101
119
  password: string;
102
120
  };
121
+ declare const OTP_EMAIL_PATTERN = "is your login code";
103
122
 
104
123
  declare const BASE_URL = "/api/v1";
105
124
  declare const ROUTES: {
@@ -350,6 +369,11 @@ declare const updateCredentials: UpdateCredentials;
350
369
  declare const clearCredentials: ClearCredentials;
351
370
  declare const hyphenize: Hyphenize;
352
371
  declare const joinHyphenCase: JoinHyphenCase;
372
+ declare const skipTest: {
373
+ forDevelopmentEnv: () => void;
374
+ forReviewEnv: () => void;
375
+ forAllExceptStagingEnv: () => void;
376
+ };
353
377
 
354
378
  interface LoginProps {
355
379
  page: Page;
@@ -373,4 +397,4 @@ interface Overrides {
373
397
  }
374
398
  declare const definePlaywrightConfig: (overrides: Overrides) => _playwright_test.PlaywrightTestConfig<{}, {}>;
375
399
 
376
- export { BASE_URL, CHAT_WIDGET_SELECTORS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, type CustomFixture, ENVIRONMENT, GLOBAL_TRANSLATIONS_PATTERN, HELP_CENTER_SELECTORS, IS_STAGING_ENV, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MERGE_TAGS_SELECTORS, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, OrganizationPage, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SIGNUP_SELECTORS, STORAGE_STATE, TAGS_SELECTORS, clearCredentials, commands, definePlaywrightConfig, extractSubdomainFromError, generateStagingData, hyphenize, i18nFixture, initializeCredentials, joinHyphenCase, joinString, login, loginWithoutSSO, readFileSyncIfExists, updateCredentials, writeDataToFile };
400
+ export { BASE_URL, CHAT_WIDGET_SELECTORS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, type CustomFixture, ENVIRONMENT, GLOBAL_TRANSLATIONS_PATTERN, HELP_CENTER_SELECTORS, IS_STAGING_ENV, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MERGE_TAGS_SELECTORS, MailosaurUtils, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SIGNUP_SELECTORS, STORAGE_STATE, TAGS_SELECTORS, clearCredentials, commands, definePlaywrightConfig, extractSubdomainFromError, generateStagingData, hyphenize, i18nFixture, initializeCredentials, joinHyphenCase, joinString, login, loginWithoutSSO, readFileSyncIfExists, skipTest, updateCredentials, writeDataToFile };
package/index.js CHANGED
@@ -1,6 +1,9 @@
1
- import { expect, defineConfig, devices } from '@playwright/test';
1
+ import test, { expect, defineConfig, devices } from '@playwright/test';
2
2
  import * as require$$0 from 'fs';
3
3
  import require$$0__default from 'fs';
4
+ import { faker } from '@faker-js/faker';
5
+ import { isNil, isNotNil, mergeDeepLeft, mergeAll } from 'ramda';
6
+ import MailosaurClient from 'mailosaur';
4
7
  import dayjs from 'dayjs';
5
8
  import { getI18nInstance, initI18n } from 'playwright-i18next-fixture';
6
9
  import require$$2 from 'os';
@@ -8,7 +11,6 @@ import require$$0$1 from 'path';
8
11
  import require$$0$2 from 'util';
9
12
  import require$$0$3 from 'stream';
10
13
  import require$$0$4 from 'events';
11
- import { mergeDeepLeft, mergeAll } from 'ramda';
12
14
  import require$$3 from 'crypto';
13
15
 
14
16
  const ENVIRONMENT = {
@@ -25,7 +27,9 @@ const CREDENTIALS = {
25
27
  email: "oliver@example.com",
26
28
  password: "welcome",
27
29
  };
30
+ const OTP_EMAIL_PATTERN = "is your login code";
28
31
 
32
+ /* eslint-disable playwright/no-skipped-test */
29
33
  const joinString = (string1, string2, string3 = "", separator = " ") => {
30
34
  if (string3 === "") {
31
35
  return string1 + separator + string2;
@@ -75,6 +79,11 @@ const hyphenize = input => {
75
79
  return fallbackString;
76
80
  };
77
81
  const joinHyphenCase = (...args) => args.join(" ").replace(/\s+/g, "-").toLowerCase();
82
+ const skipTest = {
83
+ forDevelopmentEnv: () => test.skip(process.env.TEST_ENV === ENVIRONMENT.development),
84
+ forReviewEnv: () => test.skip(process.env.TEST_ENV === ENVIRONMENT.review),
85
+ forAllExceptStagingEnv: () => test.skip(process.env.TEST_ENV !== ENVIRONMENT.staging),
86
+ };
78
87
 
79
88
  const COMMON_SELECTORS = {
80
89
  spinner: ".neeto-ui-spinner",
@@ -208,16 +217,53 @@ class CustomCommands {
208
217
  }
209
218
  }
210
219
 
220
+ class MailosaurUtils {
221
+ constructor(mailosaur) {
222
+ this.fetchOtpFromEmail = async ({ email, subjectSubstring = OTP_EMAIL_PATTERN, timeout = 2 * 60 * 1000, receivedAfter = new Date(), }) => {
223
+ var _a, _b, _c;
224
+ const receivedEmail = await this.mailosaur.messages.get(this.serverId, { sentTo: email, subject: subjectSubstring }, { timeout, receivedAfter });
225
+ const otp = (_c = (_b = (_a = receivedEmail === null || receivedEmail === void 0 ? void 0 : receivedEmail.text) === null || _a === void 0 ? void 0 : _a.codes) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.value;
226
+ if (isNil(otp)) {
227
+ throw new Error(`No codes found in the email with subject: ${receivedEmail.subject}. Please re-evaluate the filtering parameters.`);
228
+ }
229
+ return otp;
230
+ };
231
+ this.generateRandomMailosaurEmail = () => faker.internet.email({ provider: `${this.serverId}.mailosaur.net` });
232
+ this.mailosaur = mailosaur;
233
+ if (isNotNil(process.env.MAILOSAUR_SERVER_ID)) {
234
+ this.serverId = process.env.MAILOSAUR_SERVER_ID;
235
+ }
236
+ else {
237
+ throw new Error("ENV variable MAILOSAUR_SERVER_ID is not defined. Please add the Server ID to use this method. Please visit https://mailosaur.com/app/servers to find the Server ID.");
238
+ }
239
+ }
240
+ }
241
+
211
242
  const commands = {
212
243
  neetoPlaywrightUtilities: async ({ page, request }, use) => {
213
244
  const commands = new CustomCommands(page, request);
214
245
  await use(commands);
215
246
  },
247
+ mailosaur: async ({}, use) => {
248
+ skipTest.forAllExceptStagingEnv();
249
+ if (isNotNil(process.env.MAILOSAUR_API_KEY)) {
250
+ const mailosaur = new MailosaurClient(process.env.MAILOSAUR_API_KEY);
251
+ await use(mailosaur);
252
+ }
253
+ else {
254
+ throw new Error("ENV variable MAILOSAUR_API_KEY is not defined. Please add the API key to use this fixture. Please visit https://mailosaur.com/app/account/keys to find the API key.");
255
+ }
256
+ },
216
257
  page: async ({ page }, use) => {
217
258
  await page.goto("/");
218
259
  await page.waitForLoadState();
219
260
  await use(page);
220
261
  },
262
+ mailosaurUtils: async ({ mailosaur }, use) => {
263
+ skipTest.forAllExceptStagingEnv();
264
+ const mailosaurUtils = new MailosaurUtils(mailosaur);
265
+ await use(mailosaurUtils);
266
+ },
221
267
  };
222
268
 
223
269
  const generateStagingData = (product = "invoice") => {
@@ -1427,7 +1473,7 @@ const append = (queue = '', stash = '', enclose = false) => {
1427
1473
  return utils$g.flatten(result);
1428
1474
  };
1429
1475
 
1430
- const expand$1 = (ast, options = {}) => {
1476
+ const expand$2 = (ast, options = {}) => {
1431
1477
  let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit;
1432
1478
 
1433
1479
  let walk = (node, parent = {}) => {
@@ -1507,7 +1553,7 @@ const expand$1 = (ast, options = {}) => {
1507
1553
  return utils$g.flatten(walk(ast));
1508
1554
  };
1509
1555
 
1510
- var expand_1 = expand$1;
1556
+ var expand_1 = expand$2;
1511
1557
 
1512
1558
  var constants$4 = {
1513
1559
  MAX_LENGTH: 1024 * 64,
@@ -1896,7 +1942,7 @@ var parse_1$1 = parse$4;
1896
1942
 
1897
1943
  const stringify = stringify$4;
1898
1944
  const compile = compile_1;
1899
- const expand = expand_1;
1945
+ const expand$1 = expand_1;
1900
1946
  const parse$3 = parse_1$1;
1901
1947
 
1902
1948
  /**
@@ -2016,7 +2062,7 @@ braces$1.expand = (input, options = {}) => {
2016
2062
  input = braces$1.parse(input, options);
2017
2063
  }
2018
2064
 
2019
- let result = expand(input, options);
2065
+ let result = expand$1(input, options);
2020
2066
 
2021
2067
  // filter out empty strings if specified
2022
2068
  if (options.noempty === true) {
@@ -7407,12 +7453,12 @@ const loginWithoutSSO = async ({ page, neetoPlaywrightUtilities, loginPath = "/"
7407
7453
  const login = async ({ page, neetoPlaywrightUtilities, loginPath, }) => !IS_STAGING_ENV &&
7408
7454
  (await loginWithoutSSO({ page, neetoPlaywrightUtilities, loginPath }));
7409
7455
 
7410
- var main$1 = {exports: {}};
7456
+ var main$2 = {exports: {}};
7411
7457
 
7412
7458
  var name = "dotenv";
7413
7459
  var version$1 = "16.3.1";
7414
7460
  var description = "Loads environment variables from .env file";
7415
- var main = "lib/main.js";
7461
+ var main$1 = "lib/main.js";
7416
7462
  var types = "lib/main.d.ts";
7417
7463
  var exports = {
7418
7464
  ".": {
@@ -7475,7 +7521,7 @@ var require$$4 = {
7475
7521
  name: name,
7476
7522
  version: version$1,
7477
7523
  description: description,
7478
- main: main,
7524
+ main: main$1,
7479
7525
  types: types,
7480
7526
  exports: exports,
7481
7527
  scripts: scripts,
@@ -7794,21 +7840,108 @@ const DotenvModule = {
7794
7840
  populate
7795
7841
  };
7796
7842
 
7797
- main$1.exports.configDotenv = DotenvModule.configDotenv;
7798
- main$1.exports._configVault = DotenvModule._configVault;
7799
- main$1.exports._parseVault = DotenvModule._parseVault;
7800
- main$1.exports.config = DotenvModule.config;
7801
- main$1.exports.decrypt = DotenvModule.decrypt;
7802
- main$1.exports.parse = DotenvModule.parse;
7803
- main$1.exports.populate = DotenvModule.populate;
7843
+ main$2.exports.configDotenv = DotenvModule.configDotenv;
7844
+ main$2.exports._configVault = DotenvModule._configVault;
7845
+ main$2.exports._parseVault = DotenvModule._parseVault;
7846
+ main$2.exports.config = DotenvModule.config;
7847
+ main$2.exports.decrypt = DotenvModule.decrypt;
7848
+ main$2.exports.parse = DotenvModule.parse;
7849
+ main$2.exports.populate = DotenvModule.populate;
7850
+
7851
+ main$2.exports = DotenvModule;
7852
+
7853
+ var main = {};
7854
+
7855
+ // like String.prototype.search but returns the last index
7856
+ function _searchLast (str, rgx) {
7857
+ const matches = Array.from(str.matchAll(rgx));
7858
+ return matches.length > 0 ? matches.slice(-1)[0].index : -1
7859
+ }
7860
+
7861
+ function _interpolate (envValue, environment, config) {
7862
+ // find the last unescaped dollar sign in the
7863
+ // value so that we can evaluate it
7864
+ const lastUnescapedDollarSignIndex = _searchLast(envValue, /(?!(?<=\\))\$/g);
7865
+
7866
+ // If we couldn't match any unescaped dollar sign
7867
+ // let's return the string as is
7868
+ if (lastUnescapedDollarSignIndex === -1) return envValue
7804
7869
 
7805
- main$1.exports = DotenvModule;
7870
+ // This is the right-most group of variables in the string
7871
+ const rightMostGroup = envValue.slice(lastUnescapedDollarSignIndex);
7872
+
7873
+ /**
7874
+ * This finds the inner most variable/group divided
7875
+ * by variable name and default value (if present)
7876
+ * (
7877
+ * (?!(?<=\\))\$ // only match dollar signs that are not escaped
7878
+ * {? // optional opening curly brace
7879
+ * ([\w]+) // match the variable name
7880
+ * (?::-([^}\\]*))? // match an optional default value
7881
+ * }? // optional closing curly brace
7882
+ * )
7883
+ */
7884
+ const matchGroup = /((?!(?<=\\))\${?([\w]+)(?::-([^}\\]*))?}?)/;
7885
+ const match = rightMostGroup.match(matchGroup);
7886
+
7887
+ if (match != null) {
7888
+ const [, group, variableName, defaultValue] = match;
7889
+
7890
+ return _interpolate(
7891
+ envValue.replace(
7892
+ group,
7893
+ environment[variableName] ||
7894
+ defaultValue ||
7895
+ config.parsed[variableName] ||
7896
+ ''
7897
+ ),
7898
+ environment,
7899
+ config
7900
+ )
7901
+ }
7902
+
7903
+ return envValue
7904
+ }
7905
+
7906
+ function _resolveEscapeSequences (value) {
7907
+ return value.replace(/\\\$/g, '$')
7908
+ }
7909
+
7910
+ function expand (config) {
7911
+ // if ignoring process.env, use a blank object
7912
+ const environment = config.ignoreProcessEnv ? {} : process.env;
7913
+
7914
+ for (const configKey in config.parsed) {
7915
+ const value = Object.prototype.hasOwnProperty.call(environment, configKey)
7916
+ ? environment[configKey]
7917
+ : config.parsed[configKey];
7918
+
7919
+ config.parsed[configKey] = _resolveEscapeSequences(
7920
+ _interpolate(value, environment, config)
7921
+ );
7922
+ }
7923
+
7924
+ for (const processKey in config.parsed) {
7925
+ environment[processKey] = config.parsed[processKey];
7926
+ }
7927
+
7928
+ return config
7929
+ }
7930
+
7931
+ main.expand = expand;
7806
7932
 
7807
7933
  // @ts-check
7808
7934
  var _a, _b;
7809
- main$1.exports.config({
7935
+ const env = main$2.exports.config({
7810
7936
  path: `./e2e/config/.env.${(_a = process.env.TEST_ENV) !== null && _a !== void 0 ? _a : "development"}`,
7811
7937
  });
7938
+ main.expand(env);
7939
+ if (require$$0.existsSync("./e2e/config/.env.local")) {
7940
+ const localEnv = main$2.exports.config({
7941
+ path: "./e2e/config/.env.local",
7942
+ });
7943
+ main.expand(localEnv);
7944
+ }
7812
7945
  const currentsConfig = {
7813
7946
  ciBuildId: process.env.NEETO_CI_JOB_ID,
7814
7947
  recordKey: "PVHNwxEOySsdAeTc",
@@ -7822,7 +7955,7 @@ const definePlaywrightConfig = (overrides) => {
7822
7955
  fullyParallel: true,
7823
7956
  forbidOnly: isCI,
7824
7957
  retries: isCI ? 1 : 0,
7825
- timeout: 0,
7958
+ timeout: 5 * 60 * 1000,
7826
7959
  reporter: isCI
7827
7960
  ? [["@currents/playwright", { ...currentsConfig, ...currentsOverrides }]]
7828
7961
  : [["line"]],
@@ -7854,5 +7987,5 @@ const definePlaywrightConfig = (overrides) => {
7854
7987
  });
7855
7988
  };
7856
7989
 
7857
- export { BASE_URL, CHAT_WIDGET_SELECTORS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, ENVIRONMENT, GLOBAL_TRANSLATIONS_PATTERN, HELP_CENTER_SELECTORS, IS_STAGING_ENV, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MERGE_TAGS_SELECTORS, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, OrganizationPage, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SIGNUP_SELECTORS, STORAGE_STATE, TAGS_SELECTORS, clearCredentials, commands, definePlaywrightConfig, extractSubdomainFromError, generateStagingData, hyphenize, i18nFixture, initializeCredentials, joinHyphenCase, joinString, login, loginWithoutSSO, readFileSyncIfExists, updateCredentials, writeDataToFile };
7990
+ export { BASE_URL, CHAT_WIDGET_SELECTORS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, ENVIRONMENT, GLOBAL_TRANSLATIONS_PATTERN, HELP_CENTER_SELECTORS, IS_STAGING_ENV, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MERGE_TAGS_SELECTORS, MailosaurUtils, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SIGNUP_SELECTORS, STORAGE_STATE, TAGS_SELECTORS, clearCredentials, commands, definePlaywrightConfig, extractSubdomainFromError, generateStagingData, hyphenize, i18nFixture, initializeCredentials, joinHyphenCase, joinString, login, loginWithoutSSO, readFileSyncIfExists, skipTest, updateCredentials, writeDataToFile };
7858
7991
  //# sourceMappingURL=index.js.map