@bigbinary/neeto-playwright-commons 2.1.5 → 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.cjs.js CHANGED
@@ -1,31 +1,32 @@
1
1
  'use strict';
2
2
 
3
- var child_process = require('child_process');
4
3
  var neetoCist = require('@bigbinary/neeto-cist');
5
4
  var faker = require('@faker-js/faker');
6
- var require$$0$4 = require('fs');
7
- var require$$0$5 = require('os');
5
+ var fs$4 = require('fs');
6
+ var require$$0$4 = require('os');
8
7
  var path$1 = require('path');
9
8
  var test = require('@playwright/test');
10
9
  var playwrightI18nextFixture = require('playwright-i18next-fixture');
11
10
  var require$$0$3 = require('util');
12
11
  var ramda = require('ramda');
12
+ var child_process = require('child_process');
13
13
  var dayjs = require('dayjs');
14
- var require$$0$8 = require('stream');
15
- var require$$0$7 = require('node:buffer');
16
- var require$$0$6 = require('buffer');
14
+ var require$$0$7 = require('stream');
15
+ var require$$0$6 = require('node:buffer');
16
+ var require$$0$5 = require('buffer');
17
17
  var require$$1$2 = require('string_decoder');
18
18
  var require$$1$3 = require('node:stream');
19
- var require$$0$9 = require('crypto');
19
+ var require$$0$8 = require('crypto');
20
20
  var require$$1$4 = require('zlib');
21
- var require$$0$a = require('assert');
22
- var require$$0$b = require('tty');
21
+ var require$$0$9 = require('assert');
22
+ var require$$0$a = require('tty');
23
23
  var stealth$1 = require('puppeteer-extra-plugin-stealth');
24
24
  var require$$1$5 = require('events');
25
25
  var customParseFormat = require('dayjs/plugin/customParseFormat');
26
26
  var timezone = require('dayjs/plugin/timezone');
27
27
  var utc = require('dayjs/plugin/utc');
28
28
  var https = require('https');
29
+ var http = require('http');
29
30
 
30
31
  function _interopNamespaceDefault(e) {
31
32
  var n = Object.create(null);
@@ -44,8 +45,9 @@ function _interopNamespaceDefault(e) {
44
45
  return Object.freeze(n);
45
46
  }
46
47
 
47
- var require$$0__namespace = /*#__PURE__*/_interopNamespaceDefault(require$$0$4);
48
+ var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs$4);
48
49
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path$1);
50
+ var http__namespace = /*#__PURE__*/_interopNamespaceDefault(http);
49
51
 
50
52
  const BASE_URL = "/api/v1";
51
53
  const NEETO_AUTH_BASE_URL = (subdomain = "app") => `https://${subdomain}.neetoauth.net`;
@@ -245,86 +247,63 @@ class MemberApis {
245
247
  });
246
248
  }
247
249
 
248
- class RailsEmailRakeClient {
249
- workingDirectory;
250
- constructor() {
251
- this.workingDirectory = process.env.RAILS_ROOT || "..";
252
- }
253
- convertRawEmail = (rawEmail) => ({
254
- from: rawEmail.from,
255
- to: rawEmail.to,
256
- cc: rawEmail.cc,
257
- bcc: rawEmail.bcc,
258
- replyTo: rawEmail.reply_to,
259
- subject: rawEmail.subject,
260
- htmlBody: rawEmail.html_body,
261
- textBody: rawEmail.text_body,
262
- receivedAt: rawEmail.received_at,
263
- attachments: rawEmail.attachments?.map(att => ({
264
- name: att.filename,
265
- type: att.mime_type,
266
- content: att.data,
250
+ class RailsEmailApiClient {
251
+ port = process.env.RAILS_SERVER_PORT;
252
+ subdomain = process.env.SUBDOMAIN ?? "spinkart";
253
+ baseUrl = `http://${this.subdomain}.lvh.me:${this.port}`;
254
+ emailsEndpoint = `${this.baseUrl}/api/v1/testing/emails`;
255
+ constructor() { }
256
+ convertRawEmail = (raw) => ({
257
+ from: raw.from,
258
+ to: raw.to,
259
+ cc: raw.cc,
260
+ bcc: raw.bcc,
261
+ replyTo: raw.reply_to,
262
+ subject: raw.subject,
263
+ htmlBody: raw.html_body,
264
+ textBody: raw.text_body,
265
+ receivedAt: raw.received_at,
266
+ attachments: raw.attachments?.map(({ filename, mime_type, data }) => ({
267
+ name: filename,
268
+ type: mime_type,
269
+ content: data,
267
270
  })),
268
271
  });
269
- executeRakeTask = async (taskName, args = []) => {
270
- const childProcess = child_process.spawn("bundle", ["exec", "rake", taskName, "--", ...args], {
271
- cwd: this.workingDirectory,
272
- stdio: ["ignore", "pipe", "pipe"],
273
- });
274
- let stdout = "";
275
- let stderr = "";
276
- childProcess.stdout?.on("data", data => {
277
- stdout += data.toString();
278
- });
279
- childProcess.stderr?.on("data", data => {
280
- stderr += data.toString();
281
- });
282
- const exitCode = await new Promise((resolve, reject) => {
283
- childProcess.on("error", reject);
284
- childProcess.on("close", resolve);
285
- });
286
- if (exitCode !== 0) {
287
- throw new Error(`Rake task ${taskName} failed: ${stderr || stdout || `Exit code ${exitCode}`}`);
288
- }
289
- return this.extractJsonFromOutput(stdout);
290
- };
291
- extractJsonFromOutput = (output) => {
292
- const delimiterMatch = output.match(/<-- Captured Emails Start-->([\s\S]*?)<-- Captured Emails End-->/);
293
- return delimiterMatch ? delimiterMatch[1].trim() : output.trim();
272
+ buildQueryString = (params) => {
273
+ if (!params)
274
+ return "";
275
+ const filtered = Object.fromEntries(Object.entries(neetoCist.keysToSnakeCase(params))
276
+ .filter(([, v]) => v != null && v !== "")
277
+ .map(([k, v]) => [k, String(v)]));
278
+ const query = new URLSearchParams(filtered).toString();
279
+ return query ? `?${query}` : "";
294
280
  };
295
- listEmails = async (searchParams) => {
281
+ fetchJson = async (url, options) => {
296
282
  try {
297
- const args = this.buildSearchArgs(searchParams);
298
- const output = await this.executeRakeTask("playwright:fetch_captured_emails", args);
299
- if (!output)
300
- return [];
301
- const rawEmails = JSON.parse(output);
302
- return rawEmails.map(this.convertRawEmail);
283
+ const res = await fetch(url, options);
284
+ if (!res.ok)
285
+ return null;
286
+ return (await res.json());
303
287
  }
304
- catch (error) {
305
- console.error("Failed to fetch emails:", error);
306
- return [];
288
+ catch (err) {
289
+ console.error("API error:", err);
290
+ return null;
307
291
  }
308
292
  };
309
- buildSearchArgs = (searchParams) => Object.entries(neetoCist.keysToSnakeCase(searchParams ?? {}))
310
- .filter(([, value]) => value != null && value !== "")
311
- .map(([key, value]) => `--${key}=${value}`);
293
+ listEmails = async (searchParams) => {
294
+ const query = this.buildQueryString(searchParams);
295
+ const data = await this.fetchJson(`${this.emailsEndpoint}${query}`);
296
+ return data?.map(this.convertRawEmail) ?? [];
297
+ };
312
298
  getLatestEmail = async (searchParams) => {
313
299
  const emails = await this.listEmails(searchParams);
314
- if (emails.length === 0)
315
- return null;
316
- return emails.reduce((latest, current) => new Date(current.receivedAt) > new Date(latest.receivedAt)
317
- ? current
318
- : latest);
319
- };
320
- clearEmails = async () => {
321
- try {
322
- await this.executeRakeTask("playwright:clear_captured_emails");
323
- }
324
- catch (error) {
325
- console.error("Failed to clear emails:", error);
326
- }
300
+ return emails.reduce((latest, curr) => !latest || new Date(curr.receivedAt) > new Date(latest.receivedAt)
301
+ ? curr
302
+ : latest, null);
327
303
  };
304
+ clearEmails = () => this.fetchJson(this.emailsEndpoint, {
305
+ method: "DELETE",
306
+ });
328
307
  }
329
308
 
330
309
  class RoleApis {
@@ -5094,7 +5073,7 @@ const joinString = (string1, string2, string3 = "", separator = " ") => {
5094
5073
  };
5095
5074
  const readFileSyncIfExists = (path = STORAGE_STATE) => {
5096
5075
  try {
5097
- return JSON.parse(require$$0__namespace.readFileSync(path, "utf8"));
5076
+ return JSON.parse(fs__namespace.readFileSync(path, "utf8"));
5098
5077
  }
5099
5078
  catch {
5100
5079
  return {};
@@ -5103,7 +5082,7 @@ const readFileSyncIfExists = (path = STORAGE_STATE) => {
5103
5082
  const getGlobalUserState = () => readFileSyncIfExists()?.user;
5104
5083
  const writeDataToFile = data => {
5105
5084
  try {
5106
- require$$0__namespace.writeFileSync(STORAGE_STATE, data, "utf8");
5085
+ fs__namespace.writeFileSync(STORAGE_STATE, data, "utf8");
5107
5086
  }
5108
5087
  catch (error) {
5109
5088
  console.log(error);
@@ -5116,7 +5095,7 @@ const updateCredentials = ({ key, value }) => {
5116
5095
  return writeDataToFile(JSON.stringify(data));
5117
5096
  };
5118
5097
  const removeCredentialFile = () => {
5119
- require$$0__namespace.unlink(STORAGE_STATE, error => {
5098
+ fs__namespace.unlink(STORAGE_STATE, error => {
5120
5099
  if (!error)
5121
5100
  return;
5122
5101
  console.log(error);
@@ -6079,7 +6058,7 @@ class CustomCommands {
6079
6058
  };
6080
6059
  uploadFileViaDispatch = async ({ fileNameWithType, assetsPath = "../../../e2e/assets/", dispatchEvent = "drop", droppableZone = this.page.getByTestId(COMMON_SELECTORS.fileUploadBody), }) => {
6081
6060
  const filePath = path$1.join(__dirname, `${assetsPath}/${fileNameWithType}`);
6082
- const buffer = require$$0$4.readFileSync(filePath).toString("base64");
6061
+ const buffer = fs$4.readFileSync(filePath).toString("base64");
6083
6062
  const dataTransfer = await droppableZone.evaluateHandle((_, { buffer, fileNameWithType }) => {
6084
6063
  const dataTransfer = new DataTransfer();
6085
6064
  const fileName = fileNameWithType.split("/")?.[1];
@@ -6266,7 +6245,7 @@ class CustomCommands {
6266
6245
  await test.expect(locator).toBeChecked({ checked: shouldBeChecked });
6267
6246
  }).toPass({ timeout: 15_000 });
6268
6247
  moveCursorAtBottom = async () => {
6269
- const isMacOS = require$$0$5.platform() === "darwin";
6248
+ const isMacOS = require$$0$4.platform() === "darwin";
6270
6249
  const rightArrowKey = isMacOS ? "Meta+ArrowRight" : "End";
6271
6250
  const downArrowKey = isMacOS ? "Meta+ArrowDown" : "PageDown";
6272
6251
  await this.page.keyboard.press(rightArrowKey);
@@ -8907,7 +8886,7 @@ function requireSafer () {
8907
8886
  if (hasRequiredSafer) return safer_1;
8908
8887
  hasRequiredSafer = 1;
8909
8888
 
8910
- var buffer = require$$0$6;
8889
+ var buffer = require$$0$5;
8911
8890
  var Buffer = buffer.Buffer;
8912
8891
 
8913
8892
  var safer = {};
@@ -26602,7 +26581,7 @@ function requireCharset () {
26602
26581
  if (hasRequiredCharset) return charset.exports;
26603
26582
  hasRequiredCharset = 1;
26604
26583
 
26605
- const { Buffer } = require$$0$7;
26584
+ const { Buffer } = require$$0$6;
26606
26585
  const iconv = requireLib$b();
26607
26586
  const encodingJapanese = requireSrc$2();
26608
26587
  const charsets = requireCharsets();
@@ -26728,7 +26707,7 @@ function requireLibbase64 () {
26728
26707
  if (hasRequiredLibbase64) return libbase64;
26729
26708
  hasRequiredLibbase64 = 1;
26730
26709
 
26731
- const { Buffer } = require$$0$7;
26710
+ const { Buffer } = require$$0$6;
26732
26711
  const stream = require$$1$3;
26733
26712
  const Transform = stream.Transform;
26734
26713
 
@@ -26989,7 +26968,7 @@ function requireLibqp () {
26989
26968
  if (hasRequiredLibqp) return libqp;
26990
26969
  hasRequiredLibqp = 1;
26991
26970
 
26992
- const { Buffer } = require$$0$7;
26971
+ const { Buffer } = require$$0$6;
26993
26972
  const stream = require$$1$3;
26994
26973
  const Transform = stream.Transform;
26995
26974
 
@@ -29364,7 +29343,7 @@ function requireLibmime () {
29364
29343
  if (hasRequiredLibmime) return libmime.exports;
29365
29344
  hasRequiredLibmime = 1;
29366
29345
 
29367
- const { Buffer } = require$$0$7;
29346
+ const { Buffer } = require$$0$6;
29368
29347
  const libcharset = requireCharset();
29369
29348
  const libbase64 = requireLibbase64();
29370
29349
  const libqp = requireLibqp();
@@ -30545,7 +30524,7 @@ function requireMimeNode () {
30545
30524
  const libmime = requireLibmime();
30546
30525
  const libqp = requireLibqp();
30547
30526
  const libbase64 = requireLibbase64();
30548
- const PassThrough = require$$0$8.PassThrough;
30527
+ const PassThrough = require$$0$7.PassThrough;
30549
30528
  const pathlib = path$1;
30550
30529
 
30551
30530
  class MimeNode {
@@ -30814,7 +30793,7 @@ function requireMessageSplitter () {
30814
30793
  if (hasRequiredMessageSplitter) return messageSplitter;
30815
30794
  hasRequiredMessageSplitter = 1;
30816
30795
 
30817
- const Transform = require$$0$8.Transform;
30796
+ const Transform = require$$0$7.Transform;
30818
30797
  const MimeNode = requireMimeNode();
30819
30798
 
30820
30799
  const MAX_HEAD_SIZE = 1 * 1024 * 1024;
@@ -31244,7 +31223,7 @@ function requireMessageJoiner () {
31244
31223
  if (hasRequiredMessageJoiner) return messageJoiner;
31245
31224
  hasRequiredMessageJoiner = 1;
31246
31225
 
31247
- const Transform = require$$0$8.Transform;
31226
+ const Transform = require$$0$7.Transform;
31248
31227
 
31249
31228
  class MessageJoiner extends Transform {
31250
31229
  constructor() {
@@ -31284,7 +31263,7 @@ function requireFlowedDecoder () {
31284
31263
 
31285
31264
  // Helper class to rewrite nodes with specific mime type
31286
31265
 
31287
- const Transform = require$$0$8.Transform;
31266
+ const Transform = require$$0$7.Transform;
31288
31267
  const libmime = requireLibmime();
31289
31268
 
31290
31269
  /**
@@ -31347,7 +31326,7 @@ function requireNodeRewriter () {
31347
31326
 
31348
31327
  // Helper class to rewrite nodes with specific mime type
31349
31328
 
31350
- const Transform = require$$0$8.Transform;
31329
+ const Transform = require$$0$7.Transform;
31351
31330
  const FlowedDecoder = requireFlowedDecoder();
31352
31331
 
31353
31332
  /**
@@ -31549,7 +31528,7 @@ function requireNodeStreamer () {
31549
31528
 
31550
31529
  // Helper class to rewrite nodes with specific mime type
31551
31530
 
31552
- const Transform = require$$0$8.Transform;
31531
+ const Transform = require$$0$7.Transform;
31553
31532
  const FlowedDecoder = requireFlowedDecoder();
31554
31533
 
31555
31534
  /**
@@ -31676,7 +31655,7 @@ function requireChunkedPassthrough () {
31676
31655
  if (hasRequiredChunkedPassthrough) return chunkedPassthrough;
31677
31656
  hasRequiredChunkedPassthrough = 1;
31678
31657
 
31679
- const { Transform } = require$$0$8;
31658
+ const { Transform } = require$$0$7;
31680
31659
 
31681
31660
  class ChunkedPassthrough extends Transform {
31682
31661
  constructor(options = {}) {
@@ -32602,8 +32581,8 @@ function requireStreamHash () {
32602
32581
  if (hasRequiredStreamHash) return streamHash;
32603
32582
  hasRequiredStreamHash = 1;
32604
32583
 
32605
- const crypto = require$$0$9;
32606
- const Transform = require$$0$8.Transform;
32584
+ const crypto = require$$0$8;
32585
+ const Transform = require$$0$7.Transform;
32607
32586
 
32608
32587
  class StreamHash extends Transform {
32609
32588
  constructor(attachment, algo) {
@@ -54986,7 +54965,7 @@ function requireMailParser () {
54986
54965
  const mailsplit = requireMailsplit();
54987
54966
  const libmime = requireLibmime();
54988
54967
  const addressparser = requireAddressparser();
54989
- const Transform = require$$0$8.Transform;
54968
+ const Transform = require$$0$7.Transform;
54990
54969
  const Splitter = mailsplit.Splitter;
54991
54970
  const ChunkedPassthrough = mailsplit.ChunkedPassthrough;
54992
54971
  const punycode = require$$4$2;
@@ -60307,10 +60286,10 @@ const hexToRGB = (hex) => {
60307
60286
 
60308
60287
  class RailsEmailUtils {
60309
60288
  neetoPlaywrightUtilities;
60310
- railsEmailRakeClient;
60289
+ railsEmailClient;
60311
60290
  constructor(neetoPlaywrightUtilities) {
60312
60291
  this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
60313
- this.railsEmailRakeClient = new RailsEmailRakeClient();
60292
+ this.railsEmailClient = new RailsEmailApiClient();
60314
60293
  }
60315
60294
  convertRailsEmailToFormattedList = (railsEmail) => {
60316
60295
  if (!railsEmail)
@@ -60361,11 +60340,11 @@ class RailsEmailUtils {
60361
60340
  blobId: "",
60362
60341
  };
60363
60342
  };
60364
- clearEmails = () => this.railsEmailRakeClient.clearEmails();
60365
- getLatestEmail = (searchParams) => this.railsEmailRakeClient.getLatestEmail(searchParams);
60366
- listEmails = (searchParams) => this.railsEmailRakeClient.listEmails(searchParams);
60343
+ clearEmails = () => this.railsEmailClient.clearEmails();
60344
+ getLatestEmail = (searchParams) => this.railsEmailClient.getLatestEmail(searchParams);
60345
+ listEmails = (searchParams) => this.railsEmailClient.listEmails(searchParams);
60367
60346
  listMessages = async (messageSearchCriteria = {}, { receivedAfter = new Date(new Date().valueOf() - 60 * 60 * 1000), } = {}) => {
60368
- const emails = await this.railsEmailRakeClient.listEmails({
60347
+ const emails = await this.railsEmailClient.listEmails({
60369
60348
  ...messageSearchCriteria,
60370
60349
  receivedAfter: receivedAfter.toISOString(),
60371
60350
  });
@@ -60376,7 +60355,7 @@ class RailsEmailUtils {
60376
60355
  findMessage = async (messageSearchCriteria = {}, { timeout = 10_000, receivedAfter = new Date(new Date().valueOf() - 60 * 60 * 1000), expectedEmailCount = 1, } = {}, shouldThrowErrorOnTimeout = true) => {
60377
60356
  const email = (await this.neetoPlaywrightUtilities.executeRecursively({
60378
60357
  callback: async () => {
60379
- const railsEmail = await this.railsEmailRakeClient.getLatestEmail({
60358
+ const railsEmail = await this.railsEmailClient.getLatestEmail({
60380
60359
  ...messageSearchCriteria,
60381
60360
  receivedAfter: receivedAfter.toISOString(),
60382
60361
  });
@@ -60385,7 +60364,7 @@ class RailsEmailUtils {
60385
60364
  return this.convertRailsEmailToFormattedList(railsEmail);
60386
60365
  },
60387
60366
  condition: async () => {
60388
- const emails = await this.railsEmailRakeClient.listEmails({
60367
+ const emails = await this.railsEmailClient.listEmails({
60389
60368
  ...messageSearchCriteria,
60390
60369
  receivedAfter: receivedAfter.toISOString(),
60391
60370
  });
@@ -60404,7 +60383,7 @@ class RailsEmailUtils {
60404
60383
  findOtpFromEmail = async ({ email, subjectSubstring = OTP_EMAIL_PATTERN, timeout = 10_000, receivedAfter = new Date(), expectedEmailCount = 1, }) => {
60405
60384
  const otp = await this.neetoPlaywrightUtilities.executeRecursively({
60406
60385
  callback: async () => {
60407
- const railsEmail = await this.railsEmailRakeClient.getLatestEmail({
60386
+ const railsEmail = await this.railsEmailClient.getLatestEmail({
60408
60387
  to: email,
60409
60388
  subject: subjectSubstring,
60410
60389
  receivedAfter: receivedAfter.toISOString(),
@@ -60417,7 +60396,7 @@ class RailsEmailUtils {
60417
60396
  return formattedEmail.html.codes?.[0] || formattedEmail.text.codes?.[0];
60418
60397
  },
60419
60398
  condition: async () => {
60420
- const emails = await this.railsEmailRakeClient.listEmails({
60399
+ const emails = await this.railsEmailClient.listEmails({
60421
60400
  to: email,
60422
60401
  subject: subjectSubstring,
60423
60402
  receivedAfter: receivedAfter.toISOString(),
@@ -60431,7 +60410,7 @@ class RailsEmailUtils {
60431
60410
  getEmailAttachment = async (attachmentName, messageSearchCriteria = {}, { receivedAfter = new Date(new Date().valueOf() - 60 * 60 * 1000), expectedEmailCount = 1, timeout = 10_000, } = {}, shouldThrowErrorOnTimeout = true) => {
60432
60411
  const attachmentDetails = (await this.neetoPlaywrightUtilities.executeRecursively({
60433
60412
  callback: async () => {
60434
- const railsEmail = await this.railsEmailRakeClient.getLatestEmail({
60413
+ const railsEmail = await this.railsEmailClient.getLatestEmail({
60435
60414
  ...messageSearchCriteria,
60436
60415
  receivedAfter: receivedAfter.toISOString(),
60437
60416
  });
@@ -60448,7 +60427,7 @@ class RailsEmailUtils {
60448
60427
  };
60449
60428
  },
60450
60429
  condition: async () => {
60451
- const emails = await this.railsEmailRakeClient.listEmails({
60430
+ const emails = await this.railsEmailClient.listEmails({
60452
60431
  ...messageSearchCriteria,
60453
60432
  receivedAfter: receivedAfter.toISOString(),
60454
60433
  });
@@ -60620,9 +60599,7 @@ class MailerUtils {
60620
60599
  const { html: { codes }, } = await this.findMessage({ to: email, subject: subjectSubstring }, { timeout, receivedAfter, expectedEmailCount });
60621
60600
  return codes?.[0];
60622
60601
  };
60623
- generateRandomEmail = (shouldUseBypassEmail = false) => shouldUseBypassEmail
60624
- ? generateRandomBypassEmail()
60625
- : faker.faker.internet.email({ provider: process.env.FASTMAIL_DOMAIN_NAME });
60602
+ generateRandomEmail = () => faker.faker.internet.email({ provider: process.env.FASTMAIL_DOMAIN_NAME });
60626
60603
  getEmailAttachment = async (attachmentName, messageSearchCriteria = {}, { timeout = 10_000, receivedAfter = dateTimeOneHourAgo(), expectedEmailCount = 1, } = {}, shouldThrowErrorOnTimeout = true) => {
60627
60604
  if (IS_DEV_ENV) {
60628
60605
  return this.railsEmailUtils.getEmailAttachment(attachmentName, messageSearchCriteria, { receivedAfter, expectedEmailCount, timeout: timeout / 3 }, shouldThrowErrorOnTimeout);
@@ -67006,7 +66983,7 @@ function requireGifutil () {
67006
66983
 
67007
66984
  /** @namespace GifUtil */
67008
66985
 
67009
- const fs = require$$0$4;
66986
+ const fs = fs$4;
67010
66987
  const ImageQ = requireImageQ();
67011
66988
 
67012
66989
  const BitmapImage = requireBitmapimage();
@@ -69823,7 +69800,7 @@ function requireChunkstream () {
69823
69800
  hasRequiredChunkstream = 1;
69824
69801
 
69825
69802
  let util = require$$0$3;
69826
- let Stream = require$$0$8;
69803
+ let Stream = require$$0$7;
69827
69804
 
69828
69805
  let ChunkStream = (chunkstream.exports = function () {
69829
69806
  Stream.call(this);
@@ -71792,7 +71769,7 @@ function requirePackerAsync () {
71792
71769
  hasRequiredPackerAsync = 1;
71793
71770
 
71794
71771
  let util = require$$0$3;
71795
- let Stream = require$$0$8;
71772
+ let Stream = require$$0$7;
71796
71773
  let constants = requireConstants$4();
71797
71774
  let Packer = requirePacker();
71798
71775
 
@@ -71853,11 +71830,11 @@ function requireSyncInflate () {
71853
71830
  hasRequiredSyncInflate = 1;
71854
71831
  (function (module, exports$1) {
71855
71832
 
71856
- let assert = require$$0$a.ok;
71833
+ let assert = require$$0$9.ok;
71857
71834
  let zlib = require$$1$4;
71858
71835
  let util = require$$0$3;
71859
71836
 
71860
- let kMaxLength = require$$0$6.kMaxLength;
71837
+ let kMaxLength = require$$0$5.kMaxLength;
71861
71838
 
71862
71839
  function Inflate(opts) {
71863
71840
  if (!(this instanceof Inflate)) {
@@ -72314,7 +72291,7 @@ function requirePng () {
72314
72291
  hasRequiredPng = 1;
72315
72292
 
72316
72293
  let util = require$$0$3;
72317
- let Stream = require$$0$8;
72294
+ let Stream = require$$0$7;
72318
72295
  let Parser = requireParserAsync();
72319
72296
  let Packer = requirePackerAsync();
72320
72297
  let PNGSync = requirePngSync();
@@ -89472,8 +89449,8 @@ function to(promise, errorExt) {
89472
89449
  });
89473
89450
  }
89474
89451
 
89475
- const readFile = require$$0$4.promises.readFile;
89476
- const writeFile = require$$0$4.promises.writeFile;
89452
+ const readFile = fs$4.promises.readFile;
89453
+ const writeFile = fs$4.promises.writeFile;
89477
89454
 
89478
89455
  var Mime_1;
89479
89456
  var hasRequiredMime;
@@ -91544,7 +91521,7 @@ function createJimp({ plugins: pluginsArg, formats: formatsArg, } = {}) {
91544
91521
  if (Buffer.isBuffer(url) || url instanceof ArrayBuffer) {
91545
91522
  return this.fromBuffer(url);
91546
91523
  }
91547
- if (require$$0$4.existsSync(url)) {
91524
+ if (fs$4.existsSync(url)) {
91548
91525
  return this.fromBuffer(await readFile(url));
91549
91526
  }
91550
91527
  const [fetchErr, response] = await to(fetch(url));
@@ -107148,7 +107125,7 @@ var jsQR = /*@__PURE__*/getDefaultExportFromCjs(jsQRExports);
107148
107125
  const decodeQRCodeFromFile = async (filePath) => {
107149
107126
  let decodedString;
107150
107127
  try {
107151
- const buffer = require$$0$4.readFileSync(filePath);
107128
+ const buffer = fs$4.readFileSync(filePath);
107152
107129
  const image = await Jimp.read(buffer);
107153
107130
  const bitmapData = new Uint8ClampedArray(image.bitmap.data);
107154
107131
  const qrData = jsQR(bitmapData, image.bitmap.width, image.bitmap.height);
@@ -107185,7 +107162,7 @@ class QRCodeUtils {
107185
107162
  decodeQRCodeFromFile = async (filePath) => {
107186
107163
  let decodedString;
107187
107164
  try {
107188
- const buffer = require$$0$4.readFileSync(filePath);
107165
+ const buffer = fs$4.readFileSync(filePath);
107189
107166
  const image = await Jimp.read(buffer);
107190
107167
  const bitmapData = new Uint8ClampedArray(image.bitmap.data);
107191
107168
  const qrData = jsQR(bitmapData, image.bitmap.width, image.bitmap.height);
@@ -107252,7 +107229,35 @@ class ColorPickerUtils {
107252
107229
  };
107253
107230
  }
107254
107231
 
107232
+ const STATIC_ASSET_PATTERN = /\.(js|css|woff2?|ttf|eot|png|svg|ico|gif|webp)(\?.*)?$/;
107233
+ const assetCache = new Map();
107255
107234
  const commands = {
107235
+ context: async ({ context }, use) => {
107236
+ if (IS_DEV_ENV) {
107237
+ await context.route(STATIC_ASSET_PATTERN, async (route) => {
107238
+ const url = route.request().url();
107239
+ const hit = assetCache.get(url);
107240
+ if (hit)
107241
+ return route.fulfill(hit);
107242
+ try {
107243
+ const response = await route.fetch();
107244
+ const body = await response.body();
107245
+ const entry = {
107246
+ body,
107247
+ status: response.status(),
107248
+ headers: response.headers(),
107249
+ };
107250
+ if (response.ok())
107251
+ assetCache.set(url, entry);
107252
+ return route.fulfill(entry);
107253
+ }
107254
+ catch {
107255
+ return route.continue();
107256
+ }
107257
+ });
107258
+ }
107259
+ await use(context);
107260
+ },
107256
107261
  neetoPlaywrightUtilities: async ({ page, request, baseURL }, use) => {
107257
107262
  const commands = new CustomCommands(page, request, baseURL);
107258
107263
  await use(commands);
@@ -108041,7 +108046,7 @@ var hasRequiredSupportsColor;
108041
108046
  function requireSupportsColor () {
108042
108047
  if (hasRequiredSupportsColor) return supportsColor_1;
108043
108048
  hasRequiredSupportsColor = 1;
108044
- const os = require$$0$5;
108049
+ const os = require$$0$4;
108045
108050
  const hasFlag = requireHasFlag();
108046
108051
 
108047
108052
  const env = process.env;
@@ -108184,7 +108189,7 @@ function requireNode () {
108184
108189
  if (hasRequiredNode) return node.exports;
108185
108190
  hasRequiredNode = 1;
108186
108191
  (function (module, exports$1) {
108187
- const tty = require$$0$b;
108192
+ const tty = require$$0$a;
108188
108193
  const util = require$$0$3;
108189
108194
 
108190
108195
  /**
@@ -109511,7 +109516,7 @@ function requirePath () {
109511
109516
  hasRequiredPath = 1;
109512
109517
  Object.defineProperty(path, "__esModule", { value: true });
109513
109518
  path.convertPosixPathToPattern = path.convertWindowsPathToPattern = path.convertPathToPattern = path.escapePosixPath = path.escapeWindowsPath = path.escape = path.removeLeadingDotSegment = path.makeAbsolute = path.unixify = void 0;
109514
- const os = require$$0$5;
109519
+ const os = require$$0$4;
109515
109520
  const path$2 = path$1;
109516
109521
  const IS_WINDOWS_PLATFORM = os.platform() === 'win32';
109517
109522
  const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\
@@ -109778,7 +109783,7 @@ function requireGlobParent () {
109778
109783
 
109779
109784
  var isGlob = requireIsGlob();
109780
109785
  var pathPosixDirname = path$1.posix.dirname;
109781
- var isWin32 = require$$0$5.platform() === 'win32';
109786
+ var isWin32 = require$$0$4.platform() === 'win32';
109782
109787
 
109783
109788
  var slash = '/';
109784
109789
  var backslash = /\\/g;
@@ -114171,7 +114176,7 @@ function requireMerge2 () {
114171
114176
  * Copyright (c) 2014-2020 Teambition
114172
114177
  * Licensed under the MIT license.
114173
114178
  */
114174
- const Stream = require$$0$8;
114179
+ const Stream = require$$0$7;
114175
114180
  const PassThrough = Stream.PassThrough;
114176
114181
  const slice = Array.prototype.slice;
114177
114182
 
@@ -114600,7 +114605,7 @@ function requireFs$2 () {
114600
114605
  (function (exports$1) {
114601
114606
  Object.defineProperty(exports$1, "__esModule", { value: true });
114602
114607
  exports$1.createFileSystemAdapter = exports$1.FILE_SYSTEM_ADAPTER = void 0;
114603
- const fs = require$$0$4;
114608
+ const fs = fs$4;
114604
114609
  exports$1.FILE_SYSTEM_ADAPTER = {
114605
114610
  lstat: fs.lstat,
114606
114611
  stat: fs.stat,
@@ -115030,7 +115035,7 @@ function requireFs () {
115030
115035
  (function (exports$1) {
115031
115036
  Object.defineProperty(exports$1, "__esModule", { value: true });
115032
115037
  exports$1.createFileSystemAdapter = exports$1.FILE_SYSTEM_ADAPTER = void 0;
115033
- const fs = require$$0$4;
115038
+ const fs = fs$4;
115034
115039
  exports$1.FILE_SYSTEM_ADAPTER = {
115035
115040
  lstat: fs.lstat,
115036
115041
  stat: fs.stat,
@@ -115663,7 +115668,7 @@ function requireStream$2 () {
115663
115668
  if (hasRequiredStream$2) return stream$2;
115664
115669
  hasRequiredStream$2 = 1;
115665
115670
  Object.defineProperty(stream$2, "__esModule", { value: true });
115666
- const stream_1 = require$$0$8;
115671
+ const stream_1 = require$$0$7;
115667
115672
  const async_1 = requireAsync$3();
115668
115673
  class StreamProvider {
115669
115674
  constructor(_root, _settings) {
@@ -115915,7 +115920,7 @@ function requireStream$1 () {
115915
115920
  if (hasRequiredStream$1) return stream$1;
115916
115921
  hasRequiredStream$1 = 1;
115917
115922
  Object.defineProperty(stream$1, "__esModule", { value: true });
115918
- const stream_1 = require$$0$8;
115923
+ const stream_1 = require$$0$7;
115919
115924
  const fsStat = requireOut$3();
115920
115925
  const fsWalk = requireOut$1();
115921
115926
  const reader_1 = requireReader();
@@ -116433,7 +116438,7 @@ function requireStream () {
116433
116438
  if (hasRequiredStream) return stream;
116434
116439
  hasRequiredStream = 1;
116435
116440
  Object.defineProperty(stream, "__esModule", { value: true });
116436
- const stream_1 = require$$0$8;
116441
+ const stream_1 = require$$0$7;
116437
116442
  const stream_2 = requireStream$1();
116438
116443
  const provider_1 = requireProvider();
116439
116444
  class ProviderStream extends provider_1.default {
@@ -116559,8 +116564,8 @@ function requireSettings () {
116559
116564
  (function (exports$1) {
116560
116565
  Object.defineProperty(exports$1, "__esModule", { value: true });
116561
116566
  exports$1.DEFAULT_FILE_SYSTEM_ADAPTER = void 0;
116562
- const fs = require$$0$4;
116563
- const os = require$$0$5;
116567
+ const fs = fs$4;
116568
+ const os = require$$0$4;
116564
116569
  /**
116565
116570
  * The `os.cpus` method can return zero. We expect the number of cores to be greater than zero.
116566
116571
  * https://github.com/nodejs/node/blob/7faeddf23a98c53896f8b574a6e66589e8fb1eb8/lib/os.js#L106-L107
@@ -116916,7 +116921,7 @@ class EmbedBase {
116916
116921
  ? `${embedCode}<a href='#' id='open-popup-button'>${customElementText}</a>`
116917
116922
  : embedCode);
116918
116923
  this.filePath = `tmp/${faker.faker.word.noun()}.html`;
116919
- require$$0$4.writeFileSync(this.filePath, fileContent, "utf8");
116924
+ fs$4.writeFileSync(this.filePath, fileContent, "utf8");
116920
116925
  await this.embedTestPage.goto(`file://${path$1.resolve(this.filePath)}`, {
116921
116926
  timeout: 20_000,
116922
116927
  });
@@ -116936,7 +116941,7 @@ class EmbedBase {
116936
116941
  }
116937
116942
  await this.embedTestPage.close();
116938
116943
  await this.context.close();
116939
- require$$0$4.unlinkSync(this.filePath);
116944
+ fs$4.unlinkSync(this.filePath);
116940
116945
  };
116941
116946
  clickOnPopupButton = async (popUpButtonSelectorOptions) => {
116942
116947
  const popUpButton = this.embedTestPage.getByRole(this.embedTestPageType === "floatingPopup" ? "button" : "link", popUpButtonSelectorOptions);
@@ -120030,7 +120035,7 @@ class EditorPage {
120030
120035
  }).toPass({ timeout: 30_000 });
120031
120036
  focusText = (textLocator) => test.expect(async () => {
120032
120037
  await textLocator.click();
120033
- await this.page.keyboard.press(require$$0$5.platform() === "darwin" ? "Meta+ArrowRight" : "End");
120038
+ await this.page.keyboard.press(require$$0$4.platform() === "darwin" ? "Meta+ArrowRight" : "End");
120034
120039
  await test.expect(textLocator.locator("..")).toHaveClass(/has-focus/, {
120035
120040
  timeout: 5_000,
120036
120041
  });
@@ -124970,6 +124975,185 @@ const generatePhoneNumberDetails = () => {
124970
124975
  return { flag: country.flag, name: country.name, code: country.code, number };
124971
124976
  };
124972
124977
 
124978
+ const DEFAULT_WARMUP_URLS = ["/login"];
124979
+ async function warmup({ urls = DEFAULT_WARMUP_URLS, timeout = 60_000, } = {}) {
124980
+ if (!IS_DEV_ENV)
124981
+ return;
124982
+ const { RAILS_SERVER_PORT, SUBDOMAIN = "spinkart" } = process.env;
124983
+ if (!RAILS_SERVER_PORT) {
124984
+ throw new Error("RAILS_SERVER_PORT is not defined in environment variables.");
124985
+ }
124986
+ const baseURL = `http://${SUBDOMAIN}.lvh.me:${RAILS_SERVER_PORT}`;
124987
+ const browser = await test.chromium.launch();
124988
+ const page = await browser.newPage();
124989
+ try {
124990
+ for (const url of urls) {
124991
+ const fullUrl = url.startsWith("http") ? url : `${baseURL}${url}`;
124992
+ await page.goto(fullUrl, {
124993
+ waitUntil: "networkidle", // eslint-disable-line playwright/no-networkidle
124994
+ timeout,
124995
+ });
124996
+ }
124997
+ }
124998
+ finally {
124999
+ await browser.close();
125000
+ }
125001
+ }
125002
+
125003
+ const CONFIG = {
125004
+ DIR: "/tmp/neeto-auth-web",
125005
+ LOG: "/tmp/neeto-auth-server.log",
125006
+ PORT: 9000,
125007
+ MAX_WAIT_MS: 120_000,
125008
+ EMAIL_INIT: "/tmp/neeto-auth-web/config/initializers/playwright_email_capture.rb",
125009
+ };
125010
+ const SCRIPTS_DIR = path__namespace.join(__dirname, "scripts", "neeto-auth");
125011
+ const escapeRubyString = (value) => value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
125012
+ const buildEmailCaptureInitializer = (targetApp) => {
125013
+ const template = fs__namespace.readFileSync(path__namespace.join(SCRIPTS_DIR, "playwright_email_capture.rb.template"), "utf-8");
125014
+ return template.replace("{{TARGET_APP}}", escapeRubyString(targetApp));
125015
+ };
125016
+ const log = (msg) => console.log(`[NeetoAuth] ${msg}`);
125017
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
125018
+ const httpCheck = (port, timeout = 3000) => new Promise(resolve => {
125019
+ const req = http__namespace.get(`http://localhost:${port}/`, () => resolve(true));
125020
+ req.on("error", () => resolve(false));
125021
+ req.setTimeout(timeout, () => {
125022
+ req.destroy();
125023
+ resolve(false);
125024
+ });
125025
+ });
125026
+ class NeetoAuthServer {
125027
+ process = null;
125028
+ targetApp;
125029
+ constructor(appName) {
125030
+ this.targetApp = STATUS_TEXTS.appName(appName);
125031
+ }
125032
+ get serverEnv() {
125033
+ return {
125034
+ ...process.env,
125035
+ BUNDLE_PATH: undefined,
125036
+ RAILS_ENV: "development",
125037
+ POSTGRES_USER: process.env.POSTGRES_USER ?? process.env.USER ?? "postgres",
125038
+ };
125039
+ }
125040
+ waitForProcessExit = async (pid) => {
125041
+ const deadline = Date.now() + 10_000;
125042
+ while (Date.now() < deadline) {
125043
+ try {
125044
+ process.kill(pid, 0);
125045
+ await sleep(500);
125046
+ }
125047
+ catch {
125048
+ return;
125049
+ }
125050
+ }
125051
+ };
125052
+ killServerOnPort = async () => {
125053
+ try {
125054
+ child_process.execSync(`lsof -ti tcp:${CONFIG.PORT} | xargs kill -9`, {
125055
+ stdio: "ignore",
125056
+ });
125057
+ await sleep(1000);
125058
+ }
125059
+ catch {
125060
+ // No process on that port — nothing to kill.
125061
+ }
125062
+ };
125063
+ ensureSetup = () => {
125064
+ if (fs__namespace.existsSync(`${CONFIG.DIR}/Gemfile`)) {
125065
+ log("Already set up, skipping.");
125066
+ return;
125067
+ }
125068
+ if (!process.env.GITHUB_TOKEN) {
125069
+ throw new Error("[NeetoAuth] GITHUB_TOKEN is not set. Cannot clone neeto-auth-web.");
125070
+ }
125071
+ log("Running first-time setup...");
125072
+ const setupScript = path__namespace.join(SCRIPTS_DIR, "setup.sh");
125073
+ try {
125074
+ child_process.execSync(`bash "${setupScript}" "${CONFIG.DIR}"`, {
125075
+ stdio: "inherit",
125076
+ env: this.serverEnv,
125077
+ });
125078
+ }
125079
+ catch {
125080
+ throw new Error("[NeetoAuth] First-time setup failed. Check the output above for details.");
125081
+ }
125082
+ log("Setup complete.");
125083
+ };
125084
+ waitForServer = async (timeoutMs = CONFIG.MAX_WAIT_MS) => {
125085
+ const startTime = Date.now();
125086
+ while (Date.now() - startTime < timeoutMs) {
125087
+ if (this.process !== null && this.process.exitCode !== null) {
125088
+ const logContent = fs__namespace.existsSync(CONFIG.LOG)
125089
+ ? fs__namespace.readFileSync(CONFIG.LOG, "utf-8")
125090
+ : "<no log file>";
125091
+ throw new Error(`[NeetoAuth] Server process exited unexpectedly with code ${this.process.exitCode}.\nLog:\n${logContent}`);
125092
+ }
125093
+ if (await httpCheck(CONFIG.PORT))
125094
+ return;
125095
+ await sleep(3000);
125096
+ }
125097
+ const logContent = fs__namespace.existsSync(CONFIG.LOG)
125098
+ ? fs__namespace.readFileSync(CONFIG.LOG, "utf-8")
125099
+ : "<no log file>";
125100
+ throw new Error(`[NeetoAuth] Server did not start within ${timeoutMs / 1000}s.\nLog:\n${logContent}`);
125101
+ };
125102
+ injectEmailCaptureInitializer = () => {
125103
+ fs__namespace.writeFileSync(CONFIG.EMAIL_INIT, buildEmailCaptureInitializer(this.targetApp));
125104
+ };
125105
+ isRunningForCurrentApp = () => {
125106
+ if (!fs__namespace.existsSync(CONFIG.EMAIL_INIT))
125107
+ return false;
125108
+ const currentContent = fs__namespace.readFileSync(CONFIG.EMAIL_INIT, "utf-8");
125109
+ return currentContent === buildEmailCaptureInitializer(this.targetApp);
125110
+ };
125111
+ start = async () => {
125112
+ if (IS_STAGING_ENV)
125113
+ return;
125114
+ if (await httpCheck(CONFIG.PORT)) {
125115
+ if (this.isRunningForCurrentApp()) {
125116
+ log("Server already running for this app.");
125117
+ return;
125118
+ }
125119
+ log("Server running for a different app — restarting...");
125120
+ await this.killServerOnPort();
125121
+ }
125122
+ this.ensureSetup();
125123
+ this.injectEmailCaptureInitializer();
125124
+ log("Starting server...");
125125
+ const logStream = fs__namespace.createWriteStream(CONFIG.LOG);
125126
+ this.process = child_process.spawn("bundle", [
125127
+ "exec",
125128
+ "rails",
125129
+ "server",
125130
+ "-p",
125131
+ CONFIG.PORT.toString(),
125132
+ "-b",
125133
+ "0.0.0.0",
125134
+ ], {
125135
+ cwd: CONFIG.DIR,
125136
+ stdio: ["ignore", "pipe", "pipe"],
125137
+ env: this.serverEnv,
125138
+ });
125139
+ this.process.stdout?.pipe(logStream);
125140
+ this.process.stderr?.pipe(logStream);
125141
+ await this.waitForServer();
125142
+ log("Server ready.");
125143
+ };
125144
+ stop = async () => {
125145
+ if (IS_STAGING_ENV || !this.process)
125146
+ return;
125147
+ const pid = this.process.pid;
125148
+ log("Stopping server...");
125149
+ this.process.kill("SIGTERM");
125150
+ this.process = null;
125151
+ if (pid) {
125152
+ await this.waitForProcessExit(pid);
125153
+ }
125154
+ };
125155
+ }
125156
+
124973
125157
  var main$1 = {exports: {}};
124974
125158
 
124975
125159
  var version = "17.3.1";
@@ -124981,10 +125165,10 @@ var hasRequiredMain$1;
124981
125165
  function requireMain$1 () {
124982
125166
  if (hasRequiredMain$1) return main$1.exports;
124983
125167
  hasRequiredMain$1 = 1;
124984
- const fs = require$$0$4;
125168
+ const fs = fs$4;
124985
125169
  const path = path$1;
124986
- const os = require$$0$5;
124987
- const crypto = require$$0$9;
125170
+ const os = require$$0$4;
125171
+ const crypto = require$$0$8;
124988
125172
  const packageJson = require$$4;
124989
125173
 
124990
125174
  const version = packageJson.version;
@@ -125535,7 +125719,7 @@ const envLocalPath = `${envBasePath}.local`;
125535
125719
  const reporterPackageName = "@bigbinary/neeto-playwright-reporter";
125536
125720
  process.env.TEST_ENV = process.env.TEST_ENV ?? ENVIRONMENT.development;
125537
125721
  loadEnv(`${envBasePath}.${process.env.TEST_ENV}`);
125538
- require$$0__namespace.existsSync(envLocalPath) && loadEnv(envLocalPath);
125722
+ fs__namespace.existsSync(envLocalPath) && loadEnv(envLocalPath);
125539
125723
  const playdashStagingConfig = {
125540
125724
  apiKey: process.env.PLAYDASH_STAGING_API_KEY,
125541
125725
  ciBuildId: process.env.NEETO_CI_JOB_ID,
@@ -125816,6 +126000,7 @@ exports.NEETO_IMAGE_UPLOADER_SELECTORS = NEETO_IMAGE_UPLOADER_SELECTORS;
125816
126000
  exports.NEETO_ROUTES = NEETO_ROUTES;
125817
126001
  exports.NEETO_SEO_SELECTORS = NEETO_SEO_SELECTORS;
125818
126002
  exports.NEETO_TEXT_MODIFIER_SELECTORS = NEETO_TEXT_MODIFIER_SELECTORS;
126003
+ exports.NeetoAuthServer = NeetoAuthServer;
125819
126004
  exports.NeetoTowerApi = NeetoTowerApi;
125820
126005
  exports.ONBOARDING_SELECTORS = ONBOARDING_SELECTORS;
125821
126006
  exports.ORGANIZATION_TEXTS = ORGANIZATION_TEXTS;
@@ -125830,7 +126015,7 @@ exports.PROJECT_NAMES = PROJECT_NAMES;
125830
126015
  exports.PROJECT_TRANSLATIONS_PATH = PROJECT_TRANSLATIONS_PATH;
125831
126016
  exports.ROLES_SELECTORS = ROLES_SELECTORS;
125832
126017
  exports.ROUTES = ROUTES;
125833
- exports.RailsEmailRakeClient = RailsEmailRakeClient;
126018
+ exports.RailsEmailApiClient = RailsEmailApiClient;
125834
126019
  exports.RailsEmailUtils = RailsEmailUtils;
125835
126020
  exports.RoleApis = RoleApis;
125836
126021
  exports.RolesPage = RolesPage;
@@ -125932,5 +126117,6 @@ exports.stealthTest = stealth;
125932
126117
  exports.tableUtils = tableUtils;
125933
126118
  exports.toCamelCase = toCamelCase;
125934
126119
  exports.updateCredentials = updateCredentials;
126120
+ exports.warmup = warmup;
125935
126121
  exports.writeDataToFile = writeDataToFile;
125936
126122
  //# sourceMappingURL=index.cjs.js.map