@bigbinary/neeto-playwright-commons 2.2.0 → 2.2.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
@@ -1,6 +1,6 @@
1
1
  import * as playwright_core from 'playwright-core';
2
2
  import * as _playwright_test from '@playwright/test';
3
- import { Page, APIRequestContext, Response, APIResponse, Locator, Fixtures, PlaywrightWorkerArgs, PlaywrightWorkerOptions, PlaywrightTestArgs, PlaywrightTestOptions, Browser, BrowserContext, FrameLocator, CDPSession, PlaywrightTestConfig, LaunchOptions } from '@playwright/test';
3
+ import { Page, APIRequestContext, Response, APIResponse, Locator, BrowserContext, Fixtures, PlaywrightWorkerArgs, PlaywrightWorkerOptions, PlaywrightTestArgs, PlaywrightTestOptions, Browser, FrameLocator, CDPSession, PlaywrightTestConfig, LaunchOptions } from '@playwright/test';
4
4
  import { TFunction } from 'i18next';
5
5
  import { I18nPlaywrightFixture } from 'playwright-i18next-fixture';
6
6
  import { TOTP, Secret } from 'otpauth';
@@ -805,16 +805,18 @@ interface BaseRailsEmailSearchParams {
805
805
  receivedAfter: string;
806
806
  }
807
807
  type RailsEmailSearchParams = Partial<BaseRailsEmailSearchParams>;
808
- declare class RailsEmailRakeClient {
809
- private workingDirectory;
808
+ declare class RailsEmailApiClient {
809
+ private readonly port;
810
+ private readonly subdomain;
811
+ private readonly baseUrl;
812
+ private readonly emailsEndpoint;
810
813
  constructor();
811
814
  private convertRawEmail;
812
- private executeRakeTask;
813
- private extractJsonFromOutput;
815
+ private buildQueryString;
816
+ private fetchJson;
814
817
  listEmails: (searchParams?: RailsEmailSearchParams) => Promise<RailsEmail[]>;
815
- private buildSearchArgs;
816
818
  getLatestEmail: (searchParams?: RailsEmailSearchParams) => Promise<RailsEmail | null>;
817
- clearEmails: () => Promise<void>;
819
+ clearEmails: () => Promise<unknown>;
818
820
  }
819
821
  declare class RoleApis {
820
822
  private neetoPlaywrightUtilities;
@@ -1144,10 +1146,10 @@ interface AttachmentDetails$1 {
1144
1146
  }
1145
1147
  declare class RailsEmailUtils {
1146
1148
  private neetoPlaywrightUtilities;
1147
- private railsEmailRakeClient;
1149
+ private railsEmailClient;
1148
1150
  constructor(neetoPlaywrightUtilities: CustomCommands);
1149
1151
  private convertRailsEmailToFormattedList;
1150
- clearEmails: () => Promise<void>;
1152
+ clearEmails: () => Promise<unknown>;
1151
1153
  getLatestEmail: (searchParams: RailsEmailSearchParams) => Promise<RailsEmail | null>;
1152
1154
  listEmails: (searchParams?: RailsEmailSearchParams) => Promise<RailsEmail[]>;
1153
1155
  /**
@@ -1223,7 +1225,7 @@ declare class RailsEmailUtils {
1223
1225
  *
1224
1226
  * 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.
1225
1227
  *
1226
- * Note: In development environment, this method uses Rails Email page to find messages. In other environments, it uses Fastmail APIs.
1228
+ * Note: In development environment, this method uses the Rails testing HTTP API to find messages. In other environments, it uses Fastmail APIs.
1227
1229
  *
1228
1230
  * 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:
1229
1231
  *
@@ -1292,7 +1294,7 @@ declare class RailsEmailUtils {
1292
1294
  *
1293
1295
  * 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.
1294
1296
  *
1295
- * Note: In development environment, this method uses Rails Email page to find OTP. In other environments, it uses Fastmail APIs.
1297
+ * Note: In development environment, this method uses the Rails testing HTTP API to find OTP. In other environments, it uses Fastmail APIs.
1296
1298
  *
1297
1299
  * The method accepts the following named arguments:
1298
1300
  *
@@ -1320,7 +1322,7 @@ declare class RailsEmailUtils {
1320
1322
  *
1321
1323
  * This method is used to return the attachment based on the attachmentName of first email matching the search criteria. On top of the findMessage method, this method matches the attachment name with the attachments associated to the email. If any attachment matches then it will fetch the attachment details and return. If any attachment file name doesn't contain the substring attachmentName then it will throw an error saying No such attachment exists.
1322
1324
  *
1323
- * Note: In development environment, this method uses Rails Email page to fetch attachments. In other environments, it uses Fastmail APIs.
1325
+ * Note: In development environment, this method uses the Rails testing HTTP API to fetch attachments. In other environments, it uses Fastmail APIs.
1324
1326
  *
1325
1327
  * attachmentName: A substring matching the attachment file name. It can be both with or without extension.
1326
1328
  *
@@ -1554,7 +1556,7 @@ declare class MailerUtils {
1554
1556
  *
1555
1557
  * 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.
1556
1558
  *
1557
- * Note: In development environment, this method uses Rails Email page to find messages. In other environments, it uses Fastmail APIs.
1559
+ * Note: In development environment, this method uses the Rails testing HTTP API to find messages. In other environments, it uses Fastmail APIs.
1558
1560
  *
1559
1561
  * 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:
1560
1562
  *
@@ -1623,7 +1625,7 @@ declare class MailerUtils {
1623
1625
  *
1624
1626
  * 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.
1625
1627
  *
1626
- * Note: In development environment, this method uses Rails Email page to find OTP. In other environments, it uses Fastmail APIs.
1628
+ * Note: In development environment, this method uses the Rails testing HTTP API to find OTP. In other environments, it uses Fastmail APIs.
1627
1629
  *
1628
1630
  * The method accepts the following named arguments:
1629
1631
  *
@@ -1659,7 +1661,7 @@ declare class MailerUtils {
1659
1661
  *
1660
1662
  * This method is used to return the attachment based on the attachmentName of first email matching the search criteria. On top of the findMessage method, this method matches the attachment name with the attachments associated to the email. If any attachment matches then it will fetch the attachment details and return. If any attachment file name doesn't contain the substring attachmentName then it will throw an error saying No such attachment exists.
1661
1663
  *
1662
- * Note: In development environment, this method uses Rails Email page to fetch attachments. In other environments, it uses Fastmail APIs.
1664
+ * Note: In development environment, this method uses the Rails testing HTTP API to fetch attachments. In other environments, it uses Fastmail APIs.
1663
1665
  *
1664
1666
  * attachmentName: A substring matching the attachment file name. It can be both with or without extension.
1665
1667
  *
@@ -1827,6 +1829,7 @@ declare class ColorPickerUtils {
1827
1829
  }
1828
1830
  interface CustomFixture {
1829
1831
  neetoPlaywrightUtilities: CustomCommands;
1832
+ context: BrowserContext;
1830
1833
  page: Page;
1831
1834
  health: Health;
1832
1835
  mailerUtils: MailerUtils;
@@ -8888,6 +8891,14 @@ declare const getFormattedPhoneNumber: (countryName: string, phoneNumber: string
8888
8891
  * @endexample
8889
8892
  */
8890
8893
  declare const generatePhoneNumberDetails: () => CountryProps;
8894
+ interface WarmupOptions {
8895
+ urls?: string[];
8896
+ timeout?: number;
8897
+ }
8898
+ declare function warmup({
8899
+ urls,
8900
+ timeout
8901
+ }?: WarmupOptions): Promise<void>;
8891
8902
  declare class NeetoAuthServer {
8892
8903
  private process;
8893
8904
  private targetApp;
@@ -8947,5 +8958,5 @@ interface Overrides {
8947
8958
  * @endexample
8948
8959
  */
8949
8960
  declare const definePlaywrightConfig: (overrides: Overrides) => PlaywrightTestConfig<{}, {}>;
8950
- export { ACTIONS, ADMIN_PANEL_SELECTORS, API_KEYS_SELECTORS, API_ROUTES, AUDIT_LOGS_SELECTORS, ApiKeysApi, ApiKeysPage, AuditLogsPage, BASE_URL, CALENDAR_LABELS, CERTIFICATE_LIMIT_EXCEEDED_MESSAGE, CERTIFICATE_LIMIT_EXCEEDED_REGEXP, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, CHAT_WIDGET_TEXTS, COLOR, COMMON_SELECTORS, COMMON_TEXTS, COMMUNITY_TEXTS, CREDENTIALS, CURRENT_TIME_RANGES, CUSTOM_DOMAIN_SELECTORS, CUSTOM_DOMAIN_SUFFIX, CustomCommands, CustomDomainApi, CustomDomainPage, DATE_FORMATS, DATE_PICKER_SELECTORS, DATE_RANGES, DATE_TEXTS, DEFAULT_WEBHOOKS_RESPONSE_TEXT, DESCRIPTION_EDITOR_TEXTS, EMBED_SELECTORS, EMOJI_LABEL, EMPTY_STORAGE_STATE, ENGAGE_TEXTS, ENVIRONMENT, EXAMPLE_URL, EXPANDED_FONT_SIZE, EXPORT_FILE_TYPES, EditorPage, EmbedBase, FILE_FORMATS, FONT_SIZE_SELECTORS, GLOBAL_TRANSLATIONS_PATTERN, GOOGLE_ANALYTICS_SELECTORS, GOOGLE_CALENDAR_DATE_FORMAT, GOOGLE_LOGIN_SELECTORS, GOOGLE_LOGIN_TEXTS, GOOGLE_SHEETS_SELECTORS, GooglePage, HELP_CENTER_ROUTES, HELP_CENTER_SELECTORS, HelpAndProfilePage, INTEGRATIONS_TEXTS, INTEGRATION_SELECTORS, IPRestrictionsPage, IP_RESTRICTIONS_SELECTORS, IS_DEV_ENV, IS_STAGING_ENV, ImageUploader, IntegrationBase, IpRestrictionsApi, KEYBOARD_SHORTCUTS_SELECTORS, KEYBOARD_SHORTCUT_TEST_CASES, LIST_MODIFIER_SELECTORS, LIST_MODIFIER_TAGS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MEMBER_TEXTS, MERGE_TAGS_SELECTORS, MICROSOFT_LOGIN_SELECTORS, MICROSOFT_LOGIN_TEXTS, MailerUtils, Member, MemberApis, MicrosoftPage, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, NEETO_IMAGE_UPLOADER_SELECTORS, NEETO_ROUTES, NEETO_SEO_SELECTORS, NEETO_TEXT_MODIFIER_SELECTORS, NeetoAuthServer, NeetoTowerApi, ONBOARDING_SELECTORS, ORGANIZATION_TEXTS, OTP_EMAIL_PATTERN, OrganizationPage, PAST_TIME_RANGES, PHONE_NUMBER_FORMATS, PLURAL, PROFILE_LINKS, PROFILE_SECTION_SELECTORS, PROJECT_NAMES, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, RailsEmailRakeClient, RailsEmailUtils, RoleApis, RolesPage, SIGNUP_SELECTORS, SINGULAR, SLACK_DATA_QA_SELECTORS, SLACK_DEFAULT_CHANNEL, SLACK_SELECTORS, SLACK_WEB_TEXTS, STATUS_TEXTS, STORAGE_STATE, SecurityApi, SidebarSection, SlackApi, SlackPage, TABLE_SELECTORS, TAB_SELECTORS, TAGS_SELECTORS, TEAM_MEMBER_TEXTS, TEXT_MODIFIER_ROLES, TEXT_MODIFIER_SELECTORS, TEXT_MODIFIER_TAGS, THANK_YOU_SELECTORS, THEMES_SELECTORS, THEMES_TEXTS, THIRD_PARTY_ROUTES, TIME_RANGES, TOASTR_MESSAGES, TWILIO_SELECTORS, TagsApi, TagsPage, TeamMembers, ThankYouApi, ThankYouPage, TwilioApi, USER_AGENTS, WEBHOOK_SELECTORS, WebhookSiteApi, WebhooksPage, ZAPIER_LIMIT_EXHAUSTED_MESSAGE, ZAPIER_SELECTORS, ZAPIER_TEST_EMAIL, ZAPIER_WEB_TEXTS, ZapierPage, baseURLGenerator, basicHTMLContent, clearCredentials, commands, cpuThrottlingUsingCDP, createOrganizationViaRake, currencyUtils, dataQa, decodeQRCodeFromFile, definePlaywrightConfig, executeWithThrottledResources, extractSubdomainFromError, fillCredentialsAndSubmit, filterUtils, generatePhoneNumber, generatePhoneNumberDetails, generateRandomBypassEmail, generateRandomFile, generateStagingData, getByDataQA, getClipboardContent, getFormattedPhoneNumber, getFullUrl, getGlobalUserProps, getGlobalUserState, getImagePathAndName, getIsoCodeFromPhoneCode, getListCount, globalShortcuts, grantClipboardPermissions, hexToRGB, hexToRGBA, i18nFixture, imageRegex, initializeCredentials, initializeTestData, initializeTotp, isGithubIssueOpen, joinHyphenCase, joinString, login, loginWithoutSSO, networkConditions, networkThrottlingUsingCDP, readFileSyncIfExists, removeCredentialFile, serializeFileForBrowser, shouldSkipCustomDomainSetup, shouldSkipSetupAndTeardown, simulateClickWithDelay, simulateTypingWithDelay, skipTest, squish, _default as stealthTest, tableUtils, toCamelCase, updateCredentials, writeDataToFile };
8961
+ export { ACTIONS, ADMIN_PANEL_SELECTORS, API_KEYS_SELECTORS, API_ROUTES, AUDIT_LOGS_SELECTORS, ApiKeysApi, ApiKeysPage, AuditLogsPage, BASE_URL, CALENDAR_LABELS, CERTIFICATE_LIMIT_EXCEEDED_MESSAGE, CERTIFICATE_LIMIT_EXCEEDED_REGEXP, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, CHAT_WIDGET_TEXTS, COLOR, COMMON_SELECTORS, COMMON_TEXTS, COMMUNITY_TEXTS, CREDENTIALS, CURRENT_TIME_RANGES, CUSTOM_DOMAIN_SELECTORS, CUSTOM_DOMAIN_SUFFIX, CustomCommands, CustomDomainApi, CustomDomainPage, DATE_FORMATS, DATE_PICKER_SELECTORS, DATE_RANGES, DATE_TEXTS, DEFAULT_WEBHOOKS_RESPONSE_TEXT, DESCRIPTION_EDITOR_TEXTS, EMBED_SELECTORS, EMOJI_LABEL, EMPTY_STORAGE_STATE, ENGAGE_TEXTS, ENVIRONMENT, EXAMPLE_URL, EXPANDED_FONT_SIZE, EXPORT_FILE_TYPES, EditorPage, EmbedBase, FILE_FORMATS, FONT_SIZE_SELECTORS, GLOBAL_TRANSLATIONS_PATTERN, GOOGLE_ANALYTICS_SELECTORS, GOOGLE_CALENDAR_DATE_FORMAT, GOOGLE_LOGIN_SELECTORS, GOOGLE_LOGIN_TEXTS, GOOGLE_SHEETS_SELECTORS, GooglePage, HELP_CENTER_ROUTES, HELP_CENTER_SELECTORS, HelpAndProfilePage, INTEGRATIONS_TEXTS, INTEGRATION_SELECTORS, IPRestrictionsPage, IP_RESTRICTIONS_SELECTORS, IS_DEV_ENV, IS_STAGING_ENV, ImageUploader, IntegrationBase, IpRestrictionsApi, KEYBOARD_SHORTCUTS_SELECTORS, KEYBOARD_SHORTCUT_TEST_CASES, LIST_MODIFIER_SELECTORS, LIST_MODIFIER_TAGS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MEMBER_TEXTS, MERGE_TAGS_SELECTORS, MICROSOFT_LOGIN_SELECTORS, MICROSOFT_LOGIN_TEXTS, MailerUtils, Member, MemberApis, MicrosoftPage, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, NEETO_IMAGE_UPLOADER_SELECTORS, NEETO_ROUTES, NEETO_SEO_SELECTORS, NEETO_TEXT_MODIFIER_SELECTORS, NeetoAuthServer, NeetoTowerApi, ONBOARDING_SELECTORS, ORGANIZATION_TEXTS, OTP_EMAIL_PATTERN, OrganizationPage, PAST_TIME_RANGES, PHONE_NUMBER_FORMATS, PLURAL, PROFILE_LINKS, PROFILE_SECTION_SELECTORS, PROJECT_NAMES, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, RailsEmailApiClient, RailsEmailUtils, RoleApis, RolesPage, SIGNUP_SELECTORS, SINGULAR, SLACK_DATA_QA_SELECTORS, SLACK_DEFAULT_CHANNEL, SLACK_SELECTORS, SLACK_WEB_TEXTS, STATUS_TEXTS, STORAGE_STATE, SecurityApi, SidebarSection, SlackApi, SlackPage, TABLE_SELECTORS, TAB_SELECTORS, TAGS_SELECTORS, TEAM_MEMBER_TEXTS, TEXT_MODIFIER_ROLES, TEXT_MODIFIER_SELECTORS, TEXT_MODIFIER_TAGS, THANK_YOU_SELECTORS, THEMES_SELECTORS, THEMES_TEXTS, THIRD_PARTY_ROUTES, TIME_RANGES, TOASTR_MESSAGES, TWILIO_SELECTORS, TagsApi, TagsPage, TeamMembers, ThankYouApi, ThankYouPage, TwilioApi, USER_AGENTS, WEBHOOK_SELECTORS, WebhookSiteApi, WebhooksPage, ZAPIER_LIMIT_EXHAUSTED_MESSAGE, ZAPIER_SELECTORS, ZAPIER_TEST_EMAIL, ZAPIER_WEB_TEXTS, ZapierPage, baseURLGenerator, basicHTMLContent, clearCredentials, commands, cpuThrottlingUsingCDP, createOrganizationViaRake, currencyUtils, dataQa, decodeQRCodeFromFile, definePlaywrightConfig, executeWithThrottledResources, extractSubdomainFromError, fillCredentialsAndSubmit, filterUtils, generatePhoneNumber, generatePhoneNumberDetails, generateRandomBypassEmail, generateRandomFile, generateStagingData, getByDataQA, getClipboardContent, getFormattedPhoneNumber, getFullUrl, getGlobalUserProps, getGlobalUserState, getImagePathAndName, getIsoCodeFromPhoneCode, getListCount, globalShortcuts, grantClipboardPermissions, hexToRGB, hexToRGBA, i18nFixture, imageRegex, initializeCredentials, initializeTestData, initializeTotp, isGithubIssueOpen, joinHyphenCase, joinString, login, loginWithoutSSO, networkConditions, networkThrottlingUsingCDP, readFileSyncIfExists, removeCredentialFile, serializeFileForBrowser, shouldSkipCustomDomainSetup, shouldSkipSetupAndTeardown, simulateClickWithDelay, simulateTypingWithDelay, skipTest, squish, _default as stealthTest, tableUtils, toCamelCase, updateCredentials, warmup, writeDataToFile };
8951
8962
  export type { BaseThemeStyle, BaseThemeStyleType, ColumnMenuAction, CountryProps, CustomFixture, IntroPageThemeStyle, IntroPageThemeStyleType, ProjectName, ThemeCategory, ValueOf };
package/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import { spawn, execSync } from 'child_process';
2
1
  import { keysToSnakeCase, hyphenate, isNotPresent, humanize, isPresent, dynamicArray, findBy, truncate, isNotEmpty, isNotEqualDeep, randomPick } from '@bigbinary/neeto-cist';
3
2
  import { faker } from '@faker-js/faker';
4
3
  import * as fs$4 from 'fs';
@@ -10,6 +9,7 @@ import test, { expect, test as test$1, chromium as chromium$1, defineConfig, dev
10
9
  import { getI18nInstance, initI18n } from 'playwright-i18next-fixture';
11
10
  import require$$0$3 from 'util';
12
11
  import { curry, isNotNil, not, isEmpty, pluck, mergeAll, isNil, mergeDeepLeft } from 'ramda';
12
+ import { execSync, spawn } from 'child_process';
13
13
  import dayjs from 'dayjs';
14
14
  import require$$0$7 from 'stream';
15
15
  import require$$0$6 from 'node:buffer';
@@ -226,86 +226,63 @@ class MemberApis {
226
226
  });
227
227
  }
228
228
 
229
- class RailsEmailRakeClient {
230
- workingDirectory;
231
- constructor() {
232
- this.workingDirectory = process.env.RAILS_ROOT || "..";
233
- }
234
- convertRawEmail = (rawEmail) => ({
235
- from: rawEmail.from,
236
- to: rawEmail.to,
237
- cc: rawEmail.cc,
238
- bcc: rawEmail.bcc,
239
- replyTo: rawEmail.reply_to,
240
- subject: rawEmail.subject,
241
- htmlBody: rawEmail.html_body,
242
- textBody: rawEmail.text_body,
243
- receivedAt: rawEmail.received_at,
244
- attachments: rawEmail.attachments?.map(att => ({
245
- name: att.filename,
246
- type: att.mime_type,
247
- content: att.data,
229
+ class RailsEmailApiClient {
230
+ port = process.env.RAILS_SERVER_PORT;
231
+ subdomain = process.env.SUBDOMAIN ?? "spinkart";
232
+ baseUrl = `http://${this.subdomain}.lvh.me:${this.port}`;
233
+ emailsEndpoint = `${this.baseUrl}/api/v1/testing/emails`;
234
+ constructor() { }
235
+ convertRawEmail = (raw) => ({
236
+ from: raw.from,
237
+ to: raw.to,
238
+ cc: raw.cc,
239
+ bcc: raw.bcc,
240
+ replyTo: raw.reply_to,
241
+ subject: raw.subject,
242
+ htmlBody: raw.html_body,
243
+ textBody: raw.text_body,
244
+ receivedAt: raw.received_at,
245
+ attachments: raw.attachments?.map(({ filename, mime_type, data }) => ({
246
+ name: filename,
247
+ type: mime_type,
248
+ content: data,
248
249
  })),
249
250
  });
250
- executeRakeTask = async (taskName, args = []) => {
251
- const childProcess = spawn("bundle", ["exec", "rake", taskName, "--", ...args], {
252
- cwd: this.workingDirectory,
253
- stdio: ["ignore", "pipe", "pipe"],
254
- });
255
- let stdout = "";
256
- let stderr = "";
257
- childProcess.stdout?.on("data", data => {
258
- stdout += data.toString();
259
- });
260
- childProcess.stderr?.on("data", data => {
261
- stderr += data.toString();
262
- });
263
- const exitCode = await new Promise((resolve, reject) => {
264
- childProcess.on("error", reject);
265
- childProcess.on("close", resolve);
266
- });
267
- if (exitCode !== 0) {
268
- throw new Error(`Rake task ${taskName} failed: ${stderr || stdout || `Exit code ${exitCode}`}`);
269
- }
270
- return this.extractJsonFromOutput(stdout);
271
- };
272
- extractJsonFromOutput = (output) => {
273
- const delimiterMatch = output.match(/<-- Captured Emails Start-->([\s\S]*?)<-- Captured Emails End-->/);
274
- return delimiterMatch ? delimiterMatch[1].trim() : output.trim();
251
+ buildQueryString = (params) => {
252
+ if (!params)
253
+ return "";
254
+ const filtered = Object.fromEntries(Object.entries(keysToSnakeCase(params))
255
+ .filter(([, v]) => v != null && v !== "")
256
+ .map(([k, v]) => [k, String(v)]));
257
+ const query = new URLSearchParams(filtered).toString();
258
+ return query ? `?${query}` : "";
275
259
  };
276
- listEmails = async (searchParams) => {
260
+ fetchJson = async (url, options) => {
277
261
  try {
278
- const args = this.buildSearchArgs(searchParams);
279
- const output = await this.executeRakeTask("playwright:fetch_captured_emails", args);
280
- if (!output)
281
- return [];
282
- const rawEmails = JSON.parse(output);
283
- return rawEmails.map(this.convertRawEmail);
262
+ const res = await fetch(url, options);
263
+ if (!res.ok)
264
+ return null;
265
+ return (await res.json());
284
266
  }
285
- catch (error) {
286
- console.error("Failed to fetch emails:", error);
287
- return [];
267
+ catch (err) {
268
+ console.error("API error:", err);
269
+ return null;
288
270
  }
289
271
  };
290
- buildSearchArgs = (searchParams) => Object.entries(keysToSnakeCase(searchParams ?? {}))
291
- .filter(([, value]) => value != null && value !== "")
292
- .map(([key, value]) => `--${key}=${value}`);
272
+ listEmails = async (searchParams) => {
273
+ const query = this.buildQueryString(searchParams);
274
+ const data = await this.fetchJson(`${this.emailsEndpoint}${query}`);
275
+ return data?.map(this.convertRawEmail) ?? [];
276
+ };
293
277
  getLatestEmail = async (searchParams) => {
294
278
  const emails = await this.listEmails(searchParams);
295
- if (emails.length === 0)
296
- return null;
297
- return emails.reduce((latest, current) => new Date(current.receivedAt) > new Date(latest.receivedAt)
298
- ? current
299
- : latest);
300
- };
301
- clearEmails = async () => {
302
- try {
303
- await this.executeRakeTask("playwright:clear_captured_emails");
304
- }
305
- catch (error) {
306
- console.error("Failed to clear emails:", error);
307
- }
279
+ return emails.reduce((latest, curr) => !latest || new Date(curr.receivedAt) > new Date(latest.receivedAt)
280
+ ? curr
281
+ : latest, null);
308
282
  };
283
+ clearEmails = () => this.fetchJson(this.emailsEndpoint, {
284
+ method: "DELETE",
285
+ });
309
286
  }
310
287
 
311
288
  class RoleApis {
@@ -60288,10 +60265,10 @@ const hexToRGB = (hex) => {
60288
60265
 
60289
60266
  class RailsEmailUtils {
60290
60267
  neetoPlaywrightUtilities;
60291
- railsEmailRakeClient;
60268
+ railsEmailClient;
60292
60269
  constructor(neetoPlaywrightUtilities) {
60293
60270
  this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
60294
- this.railsEmailRakeClient = new RailsEmailRakeClient();
60271
+ this.railsEmailClient = new RailsEmailApiClient();
60295
60272
  }
60296
60273
  convertRailsEmailToFormattedList = (railsEmail) => {
60297
60274
  if (!railsEmail)
@@ -60342,11 +60319,11 @@ class RailsEmailUtils {
60342
60319
  blobId: "",
60343
60320
  };
60344
60321
  };
60345
- clearEmails = () => this.railsEmailRakeClient.clearEmails();
60346
- getLatestEmail = (searchParams) => this.railsEmailRakeClient.getLatestEmail(searchParams);
60347
- listEmails = (searchParams) => this.railsEmailRakeClient.listEmails(searchParams);
60322
+ clearEmails = () => this.railsEmailClient.clearEmails();
60323
+ getLatestEmail = (searchParams) => this.railsEmailClient.getLatestEmail(searchParams);
60324
+ listEmails = (searchParams) => this.railsEmailClient.listEmails(searchParams);
60348
60325
  listMessages = async (messageSearchCriteria = {}, { receivedAfter = new Date(new Date().valueOf() - 60 * 60 * 1000), } = {}) => {
60349
- const emails = await this.railsEmailRakeClient.listEmails({
60326
+ const emails = await this.railsEmailClient.listEmails({
60350
60327
  ...messageSearchCriteria,
60351
60328
  receivedAfter: receivedAfter.toISOString(),
60352
60329
  });
@@ -60357,7 +60334,7 @@ class RailsEmailUtils {
60357
60334
  findMessage = async (messageSearchCriteria = {}, { timeout = 10_000, receivedAfter = new Date(new Date().valueOf() - 60 * 60 * 1000), expectedEmailCount = 1, } = {}, shouldThrowErrorOnTimeout = true) => {
60358
60335
  const email = (await this.neetoPlaywrightUtilities.executeRecursively({
60359
60336
  callback: async () => {
60360
- const railsEmail = await this.railsEmailRakeClient.getLatestEmail({
60337
+ const railsEmail = await this.railsEmailClient.getLatestEmail({
60361
60338
  ...messageSearchCriteria,
60362
60339
  receivedAfter: receivedAfter.toISOString(),
60363
60340
  });
@@ -60366,7 +60343,7 @@ class RailsEmailUtils {
60366
60343
  return this.convertRailsEmailToFormattedList(railsEmail);
60367
60344
  },
60368
60345
  condition: async () => {
60369
- const emails = await this.railsEmailRakeClient.listEmails({
60346
+ const emails = await this.railsEmailClient.listEmails({
60370
60347
  ...messageSearchCriteria,
60371
60348
  receivedAfter: receivedAfter.toISOString(),
60372
60349
  });
@@ -60385,7 +60362,7 @@ class RailsEmailUtils {
60385
60362
  findOtpFromEmail = async ({ email, subjectSubstring = OTP_EMAIL_PATTERN, timeout = 10_000, receivedAfter = new Date(), expectedEmailCount = 1, }) => {
60386
60363
  const otp = await this.neetoPlaywrightUtilities.executeRecursively({
60387
60364
  callback: async () => {
60388
- const railsEmail = await this.railsEmailRakeClient.getLatestEmail({
60365
+ const railsEmail = await this.railsEmailClient.getLatestEmail({
60389
60366
  to: email,
60390
60367
  subject: subjectSubstring,
60391
60368
  receivedAfter: receivedAfter.toISOString(),
@@ -60398,7 +60375,7 @@ class RailsEmailUtils {
60398
60375
  return formattedEmail.html.codes?.[0] || formattedEmail.text.codes?.[0];
60399
60376
  },
60400
60377
  condition: async () => {
60401
- const emails = await this.railsEmailRakeClient.listEmails({
60378
+ const emails = await this.railsEmailClient.listEmails({
60402
60379
  to: email,
60403
60380
  subject: subjectSubstring,
60404
60381
  receivedAfter: receivedAfter.toISOString(),
@@ -60412,7 +60389,7 @@ class RailsEmailUtils {
60412
60389
  getEmailAttachment = async (attachmentName, messageSearchCriteria = {}, { receivedAfter = new Date(new Date().valueOf() - 60 * 60 * 1000), expectedEmailCount = 1, timeout = 10_000, } = {}, shouldThrowErrorOnTimeout = true) => {
60413
60390
  const attachmentDetails = (await this.neetoPlaywrightUtilities.executeRecursively({
60414
60391
  callback: async () => {
60415
- const railsEmail = await this.railsEmailRakeClient.getLatestEmail({
60392
+ const railsEmail = await this.railsEmailClient.getLatestEmail({
60416
60393
  ...messageSearchCriteria,
60417
60394
  receivedAfter: receivedAfter.toISOString(),
60418
60395
  });
@@ -60429,7 +60406,7 @@ class RailsEmailUtils {
60429
60406
  };
60430
60407
  },
60431
60408
  condition: async () => {
60432
- const emails = await this.railsEmailRakeClient.listEmails({
60409
+ const emails = await this.railsEmailClient.listEmails({
60433
60410
  ...messageSearchCriteria,
60434
60411
  receivedAfter: receivedAfter.toISOString(),
60435
60412
  });
@@ -107231,7 +107208,35 @@ class ColorPickerUtils {
107231
107208
  };
107232
107209
  }
107233
107210
 
107211
+ const STATIC_ASSET_PATTERN = /\.(js|css|woff2?|ttf|eot|png|svg|ico|gif|webp)(\?.*)?$/;
107212
+ const assetCache = new Map();
107234
107213
  const commands = {
107214
+ context: async ({ context }, use) => {
107215
+ if (IS_DEV_ENV) {
107216
+ await context.route(STATIC_ASSET_PATTERN, async (route) => {
107217
+ const url = route.request().url();
107218
+ const hit = assetCache.get(url);
107219
+ if (hit)
107220
+ return route.fulfill(hit);
107221
+ try {
107222
+ const response = await route.fetch();
107223
+ const body = await response.body();
107224
+ const entry = {
107225
+ body,
107226
+ status: response.status(),
107227
+ headers: response.headers(),
107228
+ };
107229
+ if (response.ok())
107230
+ assetCache.set(url, entry);
107231
+ return route.fulfill(entry);
107232
+ }
107233
+ catch {
107234
+ return route.continue();
107235
+ }
107236
+ });
107237
+ }
107238
+ await use(context);
107239
+ },
107235
107240
  neetoPlaywrightUtilities: async ({ page, request, baseURL }, use) => {
107236
107241
  const commands = new CustomCommands(page, request, baseURL);
107237
107242
  await use(commands);
@@ -124949,6 +124954,31 @@ const generatePhoneNumberDetails = () => {
124949
124954
  return { flag: country.flag, name: country.name, code: country.code, number };
124950
124955
  };
124951
124956
 
124957
+ const DEFAULT_WARMUP_URLS = ["/login"];
124958
+ async function warmup({ urls = DEFAULT_WARMUP_URLS, timeout = 60_000, } = {}) {
124959
+ if (!IS_DEV_ENV)
124960
+ return;
124961
+ const { RAILS_SERVER_PORT, SUBDOMAIN = "spinkart" } = process.env;
124962
+ if (!RAILS_SERVER_PORT) {
124963
+ throw new Error("RAILS_SERVER_PORT is not defined in environment variables.");
124964
+ }
124965
+ const baseURL = `http://${SUBDOMAIN}.lvh.me:${RAILS_SERVER_PORT}`;
124966
+ const browser = await chromium$1.launch();
124967
+ const page = await browser.newPage();
124968
+ try {
124969
+ for (const url of urls) {
124970
+ const fullUrl = url.startsWith("http") ? url : `${baseURL}${url}`;
124971
+ await page.goto(fullUrl, {
124972
+ waitUntil: "networkidle", // eslint-disable-line playwright/no-networkidle
124973
+ timeout,
124974
+ });
124975
+ }
124976
+ }
124977
+ finally {
124978
+ await browser.close();
124979
+ }
124980
+ }
124981
+
124952
124982
  const CONFIG = {
124953
124983
  DIR: "/tmp/neeto-auth-web",
124954
124984
  LOG: "/tmp/neeto-auth-server.log",
@@ -125864,5 +125894,5 @@ const definePlaywrightConfig = (overrides) => {
125864
125894
  });
125865
125895
  };
125866
125896
 
125867
- export { ACTIONS, ADMIN_PANEL_SELECTORS, API_KEYS_SELECTORS, API_ROUTES, AUDIT_LOGS_SELECTORS, ApiKeysApi, ApiKeysPage, AuditLogsPage, BASE_URL, CALENDAR_LABELS, CERTIFICATE_LIMIT_EXCEEDED_MESSAGE, CERTIFICATE_LIMIT_EXCEEDED_REGEXP, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, CHAT_WIDGET_TEXTS, COLOR, COMMON_SELECTORS, COMMON_TEXTS, COMMUNITY_TEXTS, CREDENTIALS, CURRENT_TIME_RANGES, CUSTOM_DOMAIN_SELECTORS, CUSTOM_DOMAIN_SUFFIX, CustomCommands, CustomDomainApi, CustomDomainPage, DATE_FORMATS, DATE_PICKER_SELECTORS, DATE_RANGES, DATE_TEXTS, DEFAULT_WEBHOOKS_RESPONSE_TEXT, DESCRIPTION_EDITOR_TEXTS, EMBED_SELECTORS, EMOJI_LABEL, EMPTY_STORAGE_STATE, ENGAGE_TEXTS, ENVIRONMENT, EXAMPLE_URL, EXPANDED_FONT_SIZE, EXPORT_FILE_TYPES, EditorPage, EmbedBase, FILE_FORMATS, FONT_SIZE_SELECTORS, GLOBAL_TRANSLATIONS_PATTERN, GOOGLE_ANALYTICS_SELECTORS, GOOGLE_CALENDAR_DATE_FORMAT, GOOGLE_LOGIN_SELECTORS, GOOGLE_LOGIN_TEXTS, GOOGLE_SHEETS_SELECTORS, GooglePage, HELP_CENTER_ROUTES, HELP_CENTER_SELECTORS, HelpAndProfilePage, INTEGRATIONS_TEXTS, INTEGRATION_SELECTORS, IPRestrictionsPage, IP_RESTRICTIONS_SELECTORS, IS_DEV_ENV, IS_STAGING_ENV, ImageUploader, IntegrationBase, IpRestrictionsApi, KEYBOARD_SHORTCUTS_SELECTORS, KEYBOARD_SHORTCUT_TEST_CASES, LIST_MODIFIER_SELECTORS, LIST_MODIFIER_TAGS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MEMBER_TEXTS, MERGE_TAGS_SELECTORS, MICROSOFT_LOGIN_SELECTORS, MICROSOFT_LOGIN_TEXTS, MailerUtils, Member, MemberApis, MicrosoftPage, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, NEETO_IMAGE_UPLOADER_SELECTORS, NEETO_ROUTES, NEETO_SEO_SELECTORS, NEETO_TEXT_MODIFIER_SELECTORS, NeetoAuthServer, NeetoTowerApi, ONBOARDING_SELECTORS, ORGANIZATION_TEXTS, OTP_EMAIL_PATTERN, OrganizationPage, PAST_TIME_RANGES, PHONE_NUMBER_FORMATS, PLURAL, PROFILE_LINKS, PROFILE_SECTION_SELECTORS, PROJECT_NAMES, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, RailsEmailRakeClient, RailsEmailUtils, RoleApis, RolesPage, SIGNUP_SELECTORS, SINGULAR, SLACK_DATA_QA_SELECTORS, SLACK_DEFAULT_CHANNEL, SLACK_SELECTORS, SLACK_WEB_TEXTS, STATUS_TEXTS, STORAGE_STATE, SecurityApi, SidebarSection, SlackApi, SlackPage, TABLE_SELECTORS, TAB_SELECTORS, TAGS_SELECTORS, TEAM_MEMBER_TEXTS, TEXT_MODIFIER_ROLES, TEXT_MODIFIER_SELECTORS, TEXT_MODIFIER_TAGS, THANK_YOU_SELECTORS, THEMES_SELECTORS, THEMES_TEXTS, THIRD_PARTY_ROUTES, TIME_RANGES, TOASTR_MESSAGES, TWILIO_SELECTORS, TagsApi, TagsPage, TeamMembers, ThankYouApi, ThankYouPage, TwilioApi, USER_AGENTS, WEBHOOK_SELECTORS, WebhookSiteApi, WebhooksPage, ZAPIER_LIMIT_EXHAUSTED_MESSAGE, ZAPIER_SELECTORS, ZAPIER_TEST_EMAIL, ZAPIER_WEB_TEXTS, ZapierPage, baseURLGenerator, basicHTMLContent, clearCredentials, commands, cpuThrottlingUsingCDP, createOrganizationViaRake, currencyUtils, dataQa, decodeQRCodeFromFile, definePlaywrightConfig, executeWithThrottledResources, extractSubdomainFromError, fillCredentialsAndSubmit, filterUtils, generatePhoneNumber, generatePhoneNumberDetails, generateRandomBypassEmail, generateRandomFile, generateStagingData, getByDataQA, getClipboardContent, getFormattedPhoneNumber, getFullUrl, getGlobalUserProps, getGlobalUserState, getImagePathAndName, getIsoCodeFromPhoneCode, getListCount, globalShortcuts, grantClipboardPermissions, hexToRGB, hexToRGBA, i18nFixture, imageRegex, initializeCredentials, initializeTestData, initializeTotp, isGithubIssueOpen, joinHyphenCase, joinString, login, loginWithoutSSO, networkConditions, networkThrottlingUsingCDP, readFileSyncIfExists, removeCredentialFile, serializeFileForBrowser, shouldSkipCustomDomainSetup, shouldSkipSetupAndTeardown, simulateClickWithDelay, simulateTypingWithDelay, skipTest, squish, stealth as stealthTest, tableUtils, toCamelCase, updateCredentials, writeDataToFile };
125897
+ export { ACTIONS, ADMIN_PANEL_SELECTORS, API_KEYS_SELECTORS, API_ROUTES, AUDIT_LOGS_SELECTORS, ApiKeysApi, ApiKeysPage, AuditLogsPage, BASE_URL, CALENDAR_LABELS, CERTIFICATE_LIMIT_EXCEEDED_MESSAGE, CERTIFICATE_LIMIT_EXCEEDED_REGEXP, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, CHAT_WIDGET_TEXTS, COLOR, COMMON_SELECTORS, COMMON_TEXTS, COMMUNITY_TEXTS, CREDENTIALS, CURRENT_TIME_RANGES, CUSTOM_DOMAIN_SELECTORS, CUSTOM_DOMAIN_SUFFIX, CustomCommands, CustomDomainApi, CustomDomainPage, DATE_FORMATS, DATE_PICKER_SELECTORS, DATE_RANGES, DATE_TEXTS, DEFAULT_WEBHOOKS_RESPONSE_TEXT, DESCRIPTION_EDITOR_TEXTS, EMBED_SELECTORS, EMOJI_LABEL, EMPTY_STORAGE_STATE, ENGAGE_TEXTS, ENVIRONMENT, EXAMPLE_URL, EXPANDED_FONT_SIZE, EXPORT_FILE_TYPES, EditorPage, EmbedBase, FILE_FORMATS, FONT_SIZE_SELECTORS, GLOBAL_TRANSLATIONS_PATTERN, GOOGLE_ANALYTICS_SELECTORS, GOOGLE_CALENDAR_DATE_FORMAT, GOOGLE_LOGIN_SELECTORS, GOOGLE_LOGIN_TEXTS, GOOGLE_SHEETS_SELECTORS, GooglePage, HELP_CENTER_ROUTES, HELP_CENTER_SELECTORS, HelpAndProfilePage, INTEGRATIONS_TEXTS, INTEGRATION_SELECTORS, IPRestrictionsPage, IP_RESTRICTIONS_SELECTORS, IS_DEV_ENV, IS_STAGING_ENV, ImageUploader, IntegrationBase, IpRestrictionsApi, KEYBOARD_SHORTCUTS_SELECTORS, KEYBOARD_SHORTCUT_TEST_CASES, LIST_MODIFIER_SELECTORS, LIST_MODIFIER_TAGS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MEMBER_TEXTS, MERGE_TAGS_SELECTORS, MICROSOFT_LOGIN_SELECTORS, MICROSOFT_LOGIN_TEXTS, MailerUtils, Member, MemberApis, MicrosoftPage, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, NEETO_IMAGE_UPLOADER_SELECTORS, NEETO_ROUTES, NEETO_SEO_SELECTORS, NEETO_TEXT_MODIFIER_SELECTORS, NeetoAuthServer, NeetoTowerApi, ONBOARDING_SELECTORS, ORGANIZATION_TEXTS, OTP_EMAIL_PATTERN, OrganizationPage, PAST_TIME_RANGES, PHONE_NUMBER_FORMATS, PLURAL, PROFILE_LINKS, PROFILE_SECTION_SELECTORS, PROJECT_NAMES, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, RailsEmailApiClient, RailsEmailUtils, RoleApis, RolesPage, SIGNUP_SELECTORS, SINGULAR, SLACK_DATA_QA_SELECTORS, SLACK_DEFAULT_CHANNEL, SLACK_SELECTORS, SLACK_WEB_TEXTS, STATUS_TEXTS, STORAGE_STATE, SecurityApi, SidebarSection, SlackApi, SlackPage, TABLE_SELECTORS, TAB_SELECTORS, TAGS_SELECTORS, TEAM_MEMBER_TEXTS, TEXT_MODIFIER_ROLES, TEXT_MODIFIER_SELECTORS, TEXT_MODIFIER_TAGS, THANK_YOU_SELECTORS, THEMES_SELECTORS, THEMES_TEXTS, THIRD_PARTY_ROUTES, TIME_RANGES, TOASTR_MESSAGES, TWILIO_SELECTORS, TagsApi, TagsPage, TeamMembers, ThankYouApi, ThankYouPage, TwilioApi, USER_AGENTS, WEBHOOK_SELECTORS, WebhookSiteApi, WebhooksPage, ZAPIER_LIMIT_EXHAUSTED_MESSAGE, ZAPIER_SELECTORS, ZAPIER_TEST_EMAIL, ZAPIER_WEB_TEXTS, ZapierPage, baseURLGenerator, basicHTMLContent, clearCredentials, commands, cpuThrottlingUsingCDP, createOrganizationViaRake, currencyUtils, dataQa, decodeQRCodeFromFile, definePlaywrightConfig, executeWithThrottledResources, extractSubdomainFromError, fillCredentialsAndSubmit, filterUtils, generatePhoneNumber, generatePhoneNumberDetails, generateRandomBypassEmail, generateRandomFile, generateStagingData, getByDataQA, getClipboardContent, getFormattedPhoneNumber, getFullUrl, getGlobalUserProps, getGlobalUserState, getImagePathAndName, getIsoCodeFromPhoneCode, getListCount, globalShortcuts, grantClipboardPermissions, hexToRGB, hexToRGBA, i18nFixture, imageRegex, initializeCredentials, initializeTestData, initializeTotp, isGithubIssueOpen, joinHyphenCase, joinString, login, loginWithoutSSO, networkConditions, networkThrottlingUsingCDP, readFileSyncIfExists, removeCredentialFile, serializeFileForBrowser, shouldSkipCustomDomainSetup, shouldSkipSetupAndTeardown, simulateClickWithDelay, simulateTypingWithDelay, skipTest, squish, stealth as stealthTest, tableUtils, toCamelCase, updateCredentials, warmup, writeDataToFile };
125868
125898
  //# sourceMappingURL=index.js.map