@bigbinary/neeto-playwright-commons 1.1.2 → 1.2.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
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var test = require('@playwright/test');
6
+ var dayjs = require('dayjs');
6
7
  var require$$0$3 = require('fs');
7
8
  var require$$2 = require('os');
8
9
  var require$$0 = require('path');
@@ -10,7 +11,6 @@ var require$$0$1 = require('util');
10
11
  var require$$0$2 = require('stream');
11
12
  var require$$0$4 = require('events');
12
13
  var ramda = require('ramda');
13
- var dayjs = require('dayjs');
14
14
  var require$$3 = require('crypto');
15
15
 
16
16
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -33,6 +33,7 @@ function _interopNamespace(e) {
33
33
  return Object.freeze(n);
34
34
  }
35
35
 
36
+ var dayjs__default = /*#__PURE__*/_interopDefaultLegacy(dayjs);
36
37
  var require$$0__default$3 = /*#__PURE__*/_interopDefaultLegacy(require$$0$3);
37
38
  var require$$0__namespace = /*#__PURE__*/_interopNamespace(require$$0$3);
38
39
  var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2);
@@ -40,7 +41,6 @@ var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
40
41
  var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
41
42
  var require$$0__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$0$2);
42
43
  var require$$0__default$4 = /*#__PURE__*/_interopDefaultLegacy(require$$0$4);
43
- var dayjs__default = /*#__PURE__*/_interopDefaultLegacy(dayjs);
44
44
  var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3);
45
45
 
46
46
  const COMMON_SELECTORS = {
@@ -56,6 +56,115 @@ const COMMON_SELECTORS = {
56
56
  subheaderText: "subheader-left",
57
57
  };
58
58
 
59
+ class CustomCommands {
60
+ constructor(page, request) {
61
+ this.interceptMultipleResponses = ({ responseUrl = "", times = 1, baseUrl, }) => Promise.all([...new Array(times)].map(() => this.page.waitForResponse((response) => {
62
+ var _a, _b, _c;
63
+ if (response.request().resourceType() === "xhr" &&
64
+ response.status() === 200 &&
65
+ response.url().includes(responseUrl) &&
66
+ response
67
+ .url()
68
+ .startsWith((_a = baseUrl !== null && baseUrl !== void 0 ? baseUrl : process.env.BASE_URL) !== null && _a !== void 0 ? _a : "") &&
69
+ !this.responses.includes((_b = response.headers()) === null || _b === void 0 ? void 0 : _b["x-request-id"])) {
70
+ this.responses.push((_c = response.headers()) === null || _c === void 0 ? void 0 : _c["x-request-id"]);
71
+ return true;
72
+ }
73
+ return false;
74
+ }, { timeout: 10000 })));
75
+ this.recursiveMethod = async (callback, condition, timeout, startTime) => {
76
+ if (Date.now() - timeout >= startTime) {
77
+ return false;
78
+ }
79
+ else if (await condition()) {
80
+ return await callback();
81
+ }
82
+ return await this.recursiveMethod(callback, condition, timeout, startTime);
83
+ };
84
+ this.executeRecursively = async ({ callback, condition, timeout = 5000, }) => {
85
+ const startTime = Date.now();
86
+ await this.recursiveMethod(callback, condition, timeout, startTime);
87
+ };
88
+ this.verifySuccessToast = async ({ message, closeAfterVerification = true, }) => {
89
+ if (message) {
90
+ await test.expect(this.page.getByTestId(COMMON_SELECTORS.toastMessage)).toHaveValue(message);
91
+ }
92
+ else {
93
+ await test.expect(this.page.locator(COMMON_SELECTORS.toastIcon)).toHaveValue("👍");
94
+ closeAfterVerification &&
95
+ (await this.page
96
+ .getByTestId(COMMON_SELECTORS.toastCloseButton)
97
+ .click());
98
+ }
99
+ };
100
+ this.reloadAndWait = async (requestCount) => {
101
+ const reloadRequests = this.interceptMultipleResponses({
102
+ times: requestCount,
103
+ });
104
+ await this.page.reload();
105
+ await reloadRequests;
106
+ };
107
+ this.apiRequest = async ({ url, headers: additionalHeaders, body: data, method = "get", params = {}, ...otherOptions }) => {
108
+ const csrfToken = await this.page
109
+ .locator("[name='csrf-token']")
110
+ .getAttribute("content");
111
+ const requestOptions = {
112
+ headers: {
113
+ ...additionalHeaders,
114
+ "accept-encoding": "gzip",
115
+ "x-csrf-token": csrfToken !== null && csrfToken !== void 0 ? csrfToken : "",
116
+ },
117
+ data,
118
+ params,
119
+ ...otherOptions,
120
+ };
121
+ const httpMethodsHandlers = {
122
+ get: () => this.request.get(url, requestOptions),
123
+ post: () => this.request.post(url, requestOptions),
124
+ put: () => this.request.put(url, requestOptions),
125
+ delete: () => this.request.delete(url, requestOptions),
126
+ };
127
+ return await httpMethodsHandlers[method]();
128
+ };
129
+ this.verifyFieldValue = values => {
130
+ const verifyEachFieldValue = ({ field, value, }) => test.expect(this.page.getByTestId(field)).toHaveValue(value);
131
+ return Array.isArray(values)
132
+ ? Promise.all(values.map(value => verifyEachFieldValue(value)))
133
+ : verifyEachFieldValue(values);
134
+ };
135
+ this.page = page;
136
+ this.responses = [];
137
+ this.request = request;
138
+ }
139
+ }
140
+
141
+ const commands = {
142
+ neetoPlaywrightUtilities: async ({ page, request }, use) => {
143
+ const commands = new CustomCommands(page, request);
144
+ await use(commands);
145
+ },
146
+ page: async ({ page }, use) => {
147
+ await page.goto("/");
148
+ await page.waitForLoadState();
149
+ await use(page);
150
+ },
151
+ };
152
+
153
+ const ENVIRONMENT = {
154
+ development: "development",
155
+ staging: "staging",
156
+ review: "review",
157
+ };
158
+ const IS_STAGING_ENV = process.env.TEST_ENV === "staging";
159
+ const STORAGE_STATE = "./e2e/auth/user.json";
160
+ const GLOBAL_TRANSLATIONS_PATTERN = "../node_modules/@bigbinary/**/translations/en.json";
161
+ const PROJECT_TRANSLATIONS_PATH = "../app/javascript/src/translations/en.json";
162
+ const CREDENTIALS = {
163
+ name: "Oliver Smith",
164
+ email: "oliver@example.com",
165
+ password: "welcome",
166
+ };
167
+
59
168
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
60
169
 
61
170
  var tasks = {};
@@ -6754,17 +6863,6 @@ function assertPatternsInput(input) {
6754
6863
  }
6755
6864
  var out = FastGlob;
6756
6865
 
6757
- const ENVIRONMENT = {
6758
- development: "development",
6759
- staging: "staging",
6760
- review: "review",
6761
- };
6762
- const IS_STAGING_ENV = process.env.TEST_ENV === "staging";
6763
- const STORAGE_STATE = "./e2e/auth/user.json";
6764
- const GLOBAL_TRANSLATIONS_PATTERN = "../node_modules/@bigbinary/**/translations/en.json";
6765
- const PROJECT_TRANSLATIONS_PATH = "../app/javascript/src/translations/en.json";
6766
- const CREDENTIALS = { email: "oliver@example.com", password: "welcome" };
6767
-
6768
6866
  const joinString = (string1, string2, string3 = "", separator = " ") => {
6769
6867
  if (string3 === "") {
6770
6868
  return string1 + separator + string2;
@@ -6810,111 +6908,26 @@ const readTranslations = () => {
6810
6908
  return translations;
6811
6909
  };
6812
6910
 
6813
- class CustomCommands {
6814
- constructor(page, request) {
6815
- this.interceptMultipleResponses = ({ responseUrl = "", times = 1, baseUrl, }) => Promise.all([...new Array(times)].map(() => this.page.waitForResponse(response => {
6816
- var _a, _b, _c;
6817
- if (response.request().resourceType() === "xhr" &&
6818
- response.status() === 200 &&
6819
- response.url().includes(responseUrl) &&
6820
- response
6821
- .url()
6822
- .startsWith((_a = baseUrl !== null && baseUrl !== void 0 ? baseUrl : process.env.BASE_URL) !== null && _a !== void 0 ? _a : "") &&
6823
- !this.responses.includes((_b = response.headers()) === null || _b === void 0 ? void 0 : _b["x-request-id"])) {
6824
- this.responses.push((_c = response.headers()) === null || _c === void 0 ? void 0 : _c["x-request-id"]);
6825
- return true;
6826
- }
6827
- return false;
6828
- }, { timeout: 10000 })));
6829
- this.recursiveMethod = async (callback, condition, timeout, startTime) => {
6830
- if (Date.now() - timeout >= startTime) {
6831
- return false;
6832
- }
6833
- else if (await condition()) {
6834
- return await callback();
6835
- }
6836
- return await this.recursiveMethod(callback, condition, timeout, startTime);
6837
- };
6838
- this.executeRecursively = async ({ callback, condition, timeout = 5000, }) => {
6839
- const startTime = Date.now();
6840
- await this.recursiveMethod(callback, condition, timeout, startTime);
6841
- };
6842
- this.verifySuccessToast = async ({ message, closeAfterVerification = true, }) => {
6843
- if (message) {
6844
- await test.expect(this.page.getByTestId(COMMON_SELECTORS.toastMessage)).toHaveValue(message);
6845
- }
6846
- else {
6847
- await test.expect(this.page.locator(COMMON_SELECTORS.toastIcon)).toHaveValue("👍");
6848
- closeAfterVerification &&
6849
- (await this.page
6850
- .getByTestId(COMMON_SELECTORS.toastCloseButton)
6851
- .click());
6852
- }
6853
- };
6854
- this.reloadAndWait = async (requestCount) => {
6855
- const reloadRequests = this.interceptMultipleResponses({
6856
- times: requestCount,
6857
- });
6858
- await this.page.reload();
6859
- await reloadRequests;
6860
- };
6861
- this.apiRequest = async ({ url, headers: additionalHeaders, body: data, method = "get", params = {}, ...otherOptions }) => {
6862
- const { headers } = readFileSyncIfExists();
6863
- const requestOptions = {
6864
- headers: { ...headers, ...additionalHeaders, "accept-encoding": "gzip" },
6865
- data,
6866
- params,
6867
- ...otherOptions,
6868
- };
6869
- return await {
6870
- get: this.request.get(url, requestOptions),
6871
- post: this.request.post(url, requestOptions),
6872
- put: this.request.put(url, requestOptions),
6873
- delete: this.request.delete(url, requestOptions),
6874
- }[method.toLowerCase()];
6875
- };
6876
- this.verifyFieldValue = values => {
6877
- const verifyEachFieldValue = ({ field, value, }) => test.expect(this.page.getByTestId(field)).toHaveValue(value);
6878
- return Array.isArray(values)
6879
- ? Promise.all(values.map(value => verifyEachFieldValue(value)))
6880
- : verifyEachFieldValue(values);
6881
- };
6882
- this.page = page;
6883
- this.responses = [];
6884
- this.request = request;
6885
- }
6886
- }
6887
-
6888
- const commands = {
6889
- neetoPlaywrightUtilities: async ({ page, request }, use) => {
6890
- const commands = new CustomCommands(page, request);
6891
- await use(commands);
6892
- },
6893
- page: async ({ page }, use) => {
6894
- await page.goto("/");
6895
- await page.waitForLoadState();
6896
- await use(page);
6897
- },
6898
- };
6899
-
6900
- const timestamp = dayjs__default["default"]().format("YYYYMMDDHH");
6901
- const firstName = "André";
6902
- const lastName = "O'Reilly";
6903
- const stagingOrganization = `cypresstest-invoice-${timestamp}`;
6904
- const otpBypassKey = process.env.OTP_BYPASS_KEY;
6905
- const stagingData = {
6906
- firstName,
6907
- lastName,
6908
- otp: 111111,
6909
- domain: "neetoinvoice.net",
6910
- currentUserName: IS_STAGING_ENV
6911
- ? joinString(firstName, lastName)
6912
- : "Oliver Smith",
6913
- businessName: stagingOrganization,
6914
- subdomainName: IS_STAGING_ENV ? stagingOrganization : "spinkart",
6915
- email: IS_STAGING_ENV
6916
- ? `cypresstest${otpBypassKey}+invoice+${timestamp}-playwright@bigbinary.com`
6917
- : "oliver@example.com",
6911
+ const generateStagingData = (product = "invoice") => {
6912
+ const timestamp = dayjs__default["default"]().format("YYYYMMDDHH");
6913
+ const firstName = "André";
6914
+ const lastName = "O'Reilly";
6915
+ const otpBypassKey = process.env.OTP_BYPASS_KEY;
6916
+ const stagingOrganization = `cypresstest-${product}-${timestamp}`;
6917
+ return {
6918
+ firstName,
6919
+ lastName,
6920
+ otp: 111111,
6921
+ domain: `neeto${product}.net`,
6922
+ currentUserName: IS_STAGING_ENV
6923
+ ? joinString(firstName, lastName)
6924
+ : CREDENTIALS.name,
6925
+ businessName: stagingOrganization,
6926
+ subdomainName: IS_STAGING_ENV ? stagingOrganization : "spinkart",
6927
+ email: IS_STAGING_ENV
6928
+ ? `cypresstest${otpBypassKey}+${product}+${timestamp}-playwright@bigbinary.com`
6929
+ : "oliver@example.com",
6930
+ };
6918
6931
  };
6919
6932
 
6920
6933
  const i18n = {
@@ -6940,7 +6953,7 @@ const ROUTES = {
6940
6953
  signup: `${BASE_URL}/signups`,
6941
6954
  subdomainAvailability: `${BASE_URL}/subdomain_availability`,
6942
6955
  countries: `${BASE_URL}/countries`,
6943
- neetoAps: `${BASE_URL}/neeto_apps`,
6956
+ neetoApps: `${BASE_URL}/neeto_apps`,
6944
6957
  };
6945
6958
 
6946
6959
  const SIGNUP_SELECTORS = {
@@ -7019,10 +7032,9 @@ class OrganizationPage {
7019
7032
  await this.page.getByTestId(SIGNUP_SELECTORS.profileSubmitButton).click();
7020
7033
  await submitProfile;
7021
7034
  };
7022
- this.setupOrganization = async () => {
7035
+ this.setupOrganization = async (product) => {
7023
7036
  if (!IS_STAGING_ENV)
7024
7037
  return;
7025
- let headers = {};
7026
7038
  const { user } = readFileSyncIfExists();
7027
7039
  await this.createOrganization({
7028
7040
  businessName: user.businessName,
@@ -7030,20 +7042,15 @@ class OrganizationPage {
7030
7042
  firstName: user.firstName,
7031
7043
  lastName: user.lastName,
7032
7044
  subdomainName: user.subdomainName,
7033
- appName: "neetoInvoice",
7034
- });
7035
- await this.page.route(`**${ROUTES.neetoAps}`, async (route) => {
7036
- headers = await route.request().allHeaders();
7037
- await route.continue();
7045
+ appName: `neeto${product}`,
7038
7046
  });
7039
7047
  await test.expect(this.page.locator(COMMON_SELECTORS.spinner)).toBeHidden();
7040
7048
  const userCredentials = readFileSyncIfExists();
7041
7049
  await this.page.context().storageState({ path: STORAGE_STATE });
7042
- const mergedCredentials = {
7043
- ...readFileSyncIfExists(),
7044
- ...userCredentials,
7045
- headers,
7046
- };
7050
+ const mergedCredentials = ramda.mergeAll([
7051
+ readFileSyncIfExists(),
7052
+ userCredentials,
7053
+ ]);
7047
7054
  writeDataToFile(JSON.stringify(mergedCredentials, null, 2));
7048
7055
  };
7049
7056
  this.updateSubdomainIfExists = async (appName) => {
@@ -7097,8 +7104,9 @@ const LOGIN_SELECTORS = {
7097
7104
 
7098
7105
  const COMMON_TEXTS = { edit: "Edit" };
7099
7106
 
7100
- const initializeCredentials = () => {
7107
+ const initializeCredentials = (product) => {
7101
7108
  const { user } = readFileSyncIfExists();
7109
+ const stagingData = generateStagingData(product);
7102
7110
  const newState = {
7103
7111
  ...user,
7104
7112
  businessName: (user === null || user === void 0 ? void 0 : user.businessName) || stagingData.businessName,
@@ -7116,34 +7124,28 @@ const initializeCredentials = () => {
7116
7124
  }
7117
7125
  };
7118
7126
 
7119
- const loginWithoutSSO = async ({ page, neetoPlaywrightUtilities, }) => {
7127
+ const loginWithoutSSO = async ({ page, neetoPlaywrightUtilities, loginPath = "/", }) => {
7120
7128
  var _a;
7121
- await page.goto((_a = process.env.BASE_URL) !== null && _a !== void 0 ? _a : "");
7122
- let headers = {};
7123
- await page.route(`**${ROUTES.login}`, async (route) => {
7124
- headers = await route.request().allHeaders();
7125
- await route.continue();
7126
- });
7129
+ await page.goto((_a = `${process.env.BASE_URL}${loginPath}`) !== null && _a !== void 0 ? _a : "");
7127
7130
  await page.getByTestId("login-email-text-field").fill(CREDENTIALS.email);
7128
7131
  await page
7129
7132
  .getByTestId("login-password-text-field")
7130
7133
  .fill(CREDENTIALS.password);
7131
7134
  const login = neetoPlaywrightUtilities.interceptMultipleResponses({
7132
- times: 2,
7135
+ times: 1,
7133
7136
  });
7134
7137
  await page.getByTestId(LOGIN_SELECTORS.submitButton).click();
7135
7138
  await login;
7136
7139
  const userCredentials = readFileSyncIfExists();
7137
7140
  await page.context().storageState({ path: STORAGE_STATE });
7138
- const mergedCredentials = {
7139
- ...readFileSyncIfExists(),
7140
- ...userCredentials,
7141
- headers,
7142
- };
7141
+ const mergedCredentials = ramda.mergeAll([
7142
+ readFileSyncIfExists(),
7143
+ userCredentials,
7144
+ ]);
7143
7145
  writeDataToFile(JSON.stringify(mergedCredentials, null, 2));
7144
7146
  };
7145
- const login = async ({ page, neetoPlaywrightUtilities }) => !IS_STAGING_ENV &&
7146
- (await loginWithoutSSO({ page, neetoPlaywrightUtilities }));
7147
+ const login = async ({ page, neetoPlaywrightUtilities, loginPath, }) => !IS_STAGING_ENV &&
7148
+ (await loginWithoutSSO({ page, neetoPlaywrightUtilities, loginPath }));
7147
7149
 
7148
7150
  var main$1 = {exports: {}};
7149
7151
 
@@ -7593,6 +7595,7 @@ const definePlaywrightConfig = (overrides) => {
7593
7595
  });
7594
7596
  };
7595
7597
 
7598
+ exports.BASE_URL = BASE_URL;
7596
7599
  exports.COMMON_SELECTORS = COMMON_SELECTORS;
7597
7600
  exports.COMMON_TEXTS = COMMON_TEXTS;
7598
7601
  exports.CREDENTIALS = CREDENTIALS;
@@ -7609,6 +7612,7 @@ exports.STORAGE_STATE = STORAGE_STATE;
7609
7612
  exports.clearCredentials = clearCredentials;
7610
7613
  exports.commands = commands;
7611
7614
  exports.definePlaywrightConfig = definePlaywrightConfig;
7615
+ exports.generateStagingData = generateStagingData;
7612
7616
  exports.i18n = i18n;
7613
7617
  exports.initializeCredentials = initializeCredentials;
7614
7618
  exports.joinString = joinString;
@@ -7616,7 +7620,6 @@ exports.login = login;
7616
7620
  exports.loginWithoutSSO = loginWithoutSSO;
7617
7621
  exports.readFileSyncIfExists = readFileSyncIfExists;
7618
7622
  exports.readTranslations = readTranslations;
7619
- exports.stagingData = stagingData;
7620
7623
  exports.updateCredentials = updateCredentials;
7621
7624
  exports.writeDataToFile = writeDataToFile;
7622
7625
  //# sourceMappingURL=index.cjs.js.map