@bigbinary/neeto-playwright-commons 1.26.13 → 1.26.15

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
@@ -306,14 +306,18 @@ const ENVIRONMENT = {
306
306
  review: "review",
307
307
  };
308
308
  const EXAMPLE_URL = "https://example.com";
309
- const IS_STAGING_ENV = process.env.TEST_ENV === "staging";
309
+ const IS_STAGING_ENV = process.env.TEST_ENV === ENVIRONMENT.staging;
310
+ const IS_DEV_ENV = process.env.TEST_ENV === ENVIRONMENT.development;
310
311
  const STORAGE_STATE = "./e2e/auth/user.json";
311
312
  const GLOBAL_TRANSLATIONS_PATTERN = "../node_modules/@bigbinary/**/translations/en.json";
312
313
  const PROJECT_TRANSLATIONS_PATH = "../app/javascript/src/translations/en.json";
313
314
  const CREDENTIALS = {
315
+ firstName: "Oliver",
316
+ lastName: "Smith",
314
317
  name: "Oliver Smith",
315
318
  email: "oliver@example.com",
316
319
  password: "welcome",
320
+ subdomainName: "spinkart",
317
321
  };
318
322
  const OTP_EMAIL_PATTERN = "is your login code";
319
323
  const SLACK_DEFAULT_CHANNEL = "general";
@@ -4850,23 +4854,26 @@ const generateStagingData = (product = "invoice") => {
4850
4854
  const timestamp = jobCompletionIndex
4851
4855
  ? `${dateTimeString}-${jobCompletionIndex}`
4852
4856
  : dateTimeString;
4853
- const firstName = "André";
4854
- const lastName = "O'Reilly";
4857
+ const firstName = IS_STAGING_ENV ? "André" : CREDENTIALS.firstName;
4858
+ const lastName = IS_STAGING_ENV ? "O'Reilly" : CREDENTIALS.lastName;
4855
4859
  const otpBypassKey = process.env.OTP_BYPASS_KEY;
4856
- const stagingOrganization = `cpt-${product}-${timestamp}`;
4860
+ const isGlobalSetup = !getGlobalUserState(); // For dev global setup staging data, we use the default subdomain `spinkart`.
4861
+ const shouldKeepDefaultDataForDevEnv = isGlobalSetup && IS_DEV_ENV;
4862
+ const stagingOrganization = shouldKeepDefaultDataForDevEnv
4863
+ ? CREDENTIALS.subdomainName
4864
+ : `cpt-${product}-${timestamp}`;
4865
+ const email = shouldKeepDefaultDataForDevEnv
4866
+ ? CREDENTIALS.email
4867
+ : `cpt${otpBypassKey}+${product}+${timestamp}@bigbinary.com`;
4857
4868
  return {
4858
4869
  firstName,
4859
4870
  lastName,
4860
4871
  otp: 111111,
4861
- domain: `neeto${product}.net`,
4862
- currentUserName: IS_STAGING_ENV
4863
- ? joinString(firstName, lastName)
4864
- : CREDENTIALS.name,
4872
+ domain: IS_STAGING_ENV ? `neeto${product}.net` : `lvh.me`,
4873
+ currentUserName: joinString(firstName, lastName),
4865
4874
  businessName: stagingOrganization,
4866
- subdomainName: IS_STAGING_ENV ? stagingOrganization : "spinkart",
4867
- email: IS_STAGING_ENV
4868
- ? `cpt${otpBypassKey}+${product}+${timestamp}@bigbinary.com`
4869
- : CREDENTIALS.email,
4875
+ subdomainName: stagingOrganization,
4876
+ email,
4870
4877
  };
4871
4878
  };
4872
4879
 
@@ -4907,7 +4914,7 @@ const removeCredentialFile = () => {
4907
4914
  require$$0__namespace.unlink(STORAGE_STATE, error => {
4908
4915
  if (!error)
4909
4916
  return;
4910
- console.error(error);
4917
+ console.log(error);
4911
4918
  });
4912
4919
  };
4913
4920
  const clearCredentials = () => {
@@ -4956,7 +4963,12 @@ const shouldSkipSetupAndTeardown = () => { var _a; return ((_a = getGlobalUserSt
4956
4963
  const shouldSkipCustomDomainSetup = () => process.env.SETUP_CUSTOM_DOMAIN !== "true" || !IS_STAGING_ENV;
4957
4964
  const baseURLGenerator = (product, customSubdomain) => {
4958
4965
  const { subdomainName } = getGlobalUserState();
4959
- return `https://${customSubdomain !== null && customSubdomain !== void 0 ? customSubdomain : subdomainName}.neeto${product.toLowerCase()}.net`;
4966
+ const subdomain = customSubdomain !== null && customSubdomain !== void 0 ? customSubdomain : subdomainName;
4967
+ const railsPort = process.env.RAILS_SERVER_PORT;
4968
+ const baseURL = IS_DEV_ENV
4969
+ ? `http://${subdomain}.lvh.me:${railsPort}`
4970
+ : `https://${subdomain}.neeto${product.toLowerCase()}.net`;
4971
+ return baseURL;
4960
4972
  };
4961
4973
  // trims and replaces multiple whitespace characters in a string with a single space
4962
4974
  const squish = (text) => text.trim().replace(/\s+/g, " ");
@@ -5036,7 +5048,7 @@ const globalShortcuts = (t) => [
5036
5048
  const generatePhoneNumber = () => `${"+91"} 9${faker.faker.string.numeric(4)} ${faker.faker.string.numeric(5)}`;
5037
5049
  const initializeTestData = (product) => {
5038
5050
  const credentials = generateStagingData(product.toLowerCase());
5039
- const baseURL = `https://${credentials.subdomainName}.${credentials.domain}`;
5051
+ const baseURL = baseURLGenerator(product, credentials.subdomainName);
5040
5052
  return { credentials, baseURL };
5041
5053
  };
5042
5054
 
@@ -116672,7 +116684,7 @@ class MicrosoftPage extends IntegrationBase {
116672
116684
  const acceptBtn = this.page.locator(MICROSOFT_LOGIN_SELECTORS.acceptButton);
116673
116685
  await acceptBtn.click();
116674
116686
  await test.expect(acceptBtn).toBeHidden({ timeout: 10000 });
116675
- await this.page.waitForLoadState("load", { timeout: 25000 });
116687
+ await this.page.waitForLoadState("load", { timeout: 50000 });
116676
116688
  };
116677
116689
  this.revokePermissions = async () => {
116678
116690
  await this.page.goto(THIRD_PARTY_ROUTES.microsoft.myApps);
@@ -116895,6 +116907,9 @@ class WebhooksPage {
116895
116907
  webhookSiteURL: `${THIRD_PARTY_ROUTES.webhooks.site}${webhookToken}`,
116896
116908
  };
116897
116909
  };
116910
+ /**
116911
+ * @deprecated This method is deprecated. Use getTokenViaAPI instead.
116912
+ */
116898
116913
  this.getWebhookURL = async () => {
116899
116914
  var _a;
116900
116915
  const WEBHOOK_URL_REGEX = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/g;
@@ -118499,30 +118514,30 @@ class TeamMembers {
118499
118514
  }
118500
118515
  }
118501
118516
 
118502
- const loginWithoutSSO = async ({ page,
118503
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
118504
- neetoPlaywrightUtilities, loginPath = "/", }) => {
118505
- if (shouldSkipSetupAndTeardown())
118506
- return;
118507
- await page.goto(loginPath, { timeout: 20000 });
118517
+ const fillCredentialsAndSubmit = async ({ page, loginPath, email = CREDENTIALS.email, }) => {
118518
+ loginPath && (await page.goto(loginPath, { timeout: 30000 }));
118508
118519
  await page.waitForLoadState("load", { timeout: 35000 });
118509
- await page
118510
- .getByTestId(LOGIN_SELECTORS.emailTextField)
118511
- .fill(CREDENTIALS.email);
118520
+ await page.getByTestId(LOGIN_SELECTORS.emailTextField).fill(email);
118512
118521
  await page
118513
118522
  .getByTestId(LOGIN_SELECTORS.passwordTextField)
118514
118523
  .fill(CREDENTIALS.password);
118515
118524
  const submitButton = page.getByTestId(LOGIN_SELECTORS.submitButton);
118516
118525
  await submitButton.click();
118517
118526
  await test.expect(submitButton).toBeHidden({ timeout: 15000 });
118527
+ await test.expect(page.getByTestId(COMMON_SELECTORS.floatingActionMenuButton)).toBeVisible({ timeout: 60000 });
118528
+ };
118529
+ const loginWithoutSSO = async ({ page, loginPath = "/", email = CREDENTIALS.email, }) => {
118530
+ if (shouldSkipSetupAndTeardown())
118531
+ return;
118532
+ await fillCredentialsAndSubmit({ page, loginPath, email });
118518
118533
  const userCredentials = readFileSyncIfExists();
118519
118534
  await page.context().storageState({ path: STORAGE_STATE });
118520
118535
  const mergedCredentials = ramda.mergeAll([readFileSyncIfExists(), userCredentials]);
118521
118536
  writeDataToFile(JSON.stringify(mergedCredentials, null, 2));
118522
118537
  updateCredentials({ key: "isLoggedIn", value: "true" });
118523
118538
  };
118524
- const login = async ({ page, neetoPlaywrightUtilities, loginPath, }) => !IS_STAGING_ENV &&
118525
- (await loginWithoutSSO({ page, neetoPlaywrightUtilities, loginPath }));
118539
+ const login = async ({ page, neetoPlaywrightUtilities, loginPath, email, }) => IS_DEV_ENV &&
118540
+ (await loginWithoutSSO({ page, loginPath, email }));
118526
118541
  const generateRandomBypassEmail = () => `cpt${process.env.OTP_BYPASS_KEY}+${faker.faker.number.int()}@bigbinary.com`;
118527
118542
 
118528
118543
  const extractSubdomainFromError = (errorString) => {
@@ -118530,13 +118545,43 @@ const extractSubdomainFromError = (errorString) => {
118530
118545
  const matches = errorString.match(regex);
118531
118546
  return matches[1];
118532
118547
  };
118548
+ const createOrganizationViaRake = async ({ email, firstName, lastName, subdomainName, }) => {
118549
+ var _a, _b;
118550
+ const workingDirectory = process.env.RAILS_ROOT || "..";
118551
+ const rakeTaskName = "playwright:create_organization";
118552
+ const childProcess = child_process.spawn("bundle", [
118553
+ "exec",
118554
+ "rake",
118555
+ rakeTaskName,
118556
+ "--",
118557
+ `--first_name=${firstName}`,
118558
+ `--last_name=${lastName}`,
118559
+ `--email=${email}`,
118560
+ `--subdomain=${subdomainName}`,
118561
+ ], {
118562
+ cwd: workingDirectory,
118563
+ stdio: ["ignore", "pipe", "pipe"],
118564
+ });
118565
+ let stdout = "";
118566
+ let stderr = "";
118567
+ (_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on("data", data => {
118568
+ stdout += data.toString("utf-8");
118569
+ });
118570
+ (_b = childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on("data", data => {
118571
+ stderr += data.toString("utf-8");
118572
+ });
118573
+ const exitCode = await new Promise((resolve, reject) => {
118574
+ childProcess.on("error", reject);
118575
+ childProcess.on("close", resolve);
118576
+ });
118577
+ if (exitCode !== 0) {
118578
+ throw new Error(`Failed to create organization: ${stderr || stdout || `Exit code ${exitCode}`}`);
118579
+ }
118580
+ return stdout.trim();
118581
+ };
118533
118582
 
118534
118583
  class OrganizationPage {
118535
118584
  constructor(page, neetoPlaywrightUtilities) {
118536
- this.baseUrlGenerator = (appName) => {
118537
- const { subdomainName } = getGlobalUserState();
118538
- return `https://${subdomainName}.${appName}.net`;
118539
- };
118540
118585
  this.fillOTP = async (otp = faker.faker.string.numeric(6)) => {
118541
118586
  await this.neetoPlaywrightUtilities.waitForPageLoad();
118542
118587
  const otpTextBox = this.page.getByTestId(SIGNUP_SELECTORS.otpTextBox);
@@ -118551,8 +118596,17 @@ class OrganizationPage {
118551
118596
  await test.expect(submitButton).toBeHidden({ timeout: 35000 });
118552
118597
  };
118553
118598
  this.createOrganization = async ({ email, businessName, subdomainName, firstName, lastName, appName, }) => {
118554
- if (!IS_STAGING_ENV || shouldSkipSetupAndTeardown())
118599
+ if (shouldSkipSetupAndTeardown())
118600
+ return;
118601
+ if (IS_DEV_ENV) {
118602
+ await createOrganizationViaRake({
118603
+ email,
118604
+ firstName,
118605
+ lastName,
118606
+ subdomainName,
118607
+ });
118555
118608
  return;
118609
+ }
118556
118610
  const appNameInLowerCase = appName.toLowerCase();
118557
118611
  const isNeetoAuth = appNameInLowerCase === "neetoauth";
118558
118612
  isNeetoAuth
@@ -118588,7 +118642,9 @@ class OrganizationPage {
118588
118642
  subdomainName: user.subdomainName,
118589
118643
  appName: `neeto${product}`,
118590
118644
  });
118591
- await test.expect(this.page.locator(COMMON_SELECTORS.spinner)).toBeHidden();
118645
+ await this.neetoPlaywrightUtilities.waitForPageLoad({
118646
+ customPageContext: this.page,
118647
+ });
118592
118648
  const userCredentials = readFileSyncIfExists();
118593
118649
  await this.page.context().storageState({ path: STORAGE_STATE });
118594
118650
  const mergedCredentials = ramda.mergeAll([
@@ -118599,7 +118655,7 @@ class OrganizationPage {
118599
118655
  updateCredentials({ key: "isLoggedIn", value: "true" });
118600
118656
  updateCredentials({
118601
118657
  key: "baseUrl",
118602
- value: this.baseUrlGenerator(`neeto${product}`),
118658
+ value: baseURLGenerator(product),
118603
118659
  });
118604
118660
  };
118605
118661
  this.updateSubdomainIfExists = async (appName) => {
@@ -118621,7 +118677,7 @@ class OrganizationPage {
118621
118677
  key: "businessName",
118622
118678
  value: newOrganizationName,
118623
118679
  });
118624
- process.env.BASE_URL = this.baseUrlGenerator(appName);
118680
+ process.env.BASE_URL = baseURLGenerator(appName);
118625
118681
  await this.page
118626
118682
  .getByTestId(SIGNUP_SELECTORS.organizationNameTextField)
118627
118683
  .fill(newOrganizationName);
@@ -118643,6 +118699,10 @@ class OrganizationPage {
118643
118699
  }).toPass({ timeout: loginTimeout });
118644
118700
  };
118645
118701
  this.loginViaSSO = async (email = generateRandomBypassEmail(), loginTimeout = 2 * 60 * 1000) => {
118702
+ if (IS_DEV_ENV) {
118703
+ await fillCredentialsAndSubmit({ page: this.page, email });
118704
+ return;
118705
+ }
118646
118706
  await this.fillEmailAndSubmit(email, loginTimeout);
118647
118707
  await this.fillOTP();
118648
118708
  };
@@ -118652,6 +118712,8 @@ class OrganizationPage {
118652
118712
  await this.fillOTP(otp);
118653
118713
  };
118654
118714
  this.setupProfile = async ({ firstName = faker.faker.person.firstName(), lastName = faker.faker.person.lastName(), country, } = {}) => {
118715
+ if (IS_DEV_ENV)
118716
+ return;
118655
118717
  await this.neetoPlaywrightUtilities.waitForPageLoad();
118656
118718
  await this.page
118657
118719
  .getByTestId(SIGNUP_SELECTORS.firstNameTextField)
@@ -118669,36 +118731,62 @@ class OrganizationPage {
118669
118731
  });
118670
118732
  };
118671
118733
  this.loginAndOnboard = async ({ email, firstName, lastName, country, handleOnboarding, baseURL = process.env.BASE_URL, fetchOtpFromEmail, }) => {
118672
- await this.page.goto(`${baseURL}${ROUTES.admin}`, { timeout: 20000 });
118673
- fetchOtpFromEmail === undefined
118674
- ? await this.loginViaSSO(email)
118675
- : await this.loginWithFastmailEmail({ email, fetchOtpFromEmail });
118676
- await this.setupProfile({ firstName, lastName, country });
118677
- await this.page.waitForURL(new RegExp(getGlobalUserState().domain), {
118678
- waitUntil: "load",
118679
- });
118734
+ if (IS_DEV_ENV) {
118735
+ await fillCredentialsAndSubmit({
118736
+ page: this.page,
118737
+ email,
118738
+ loginPath: `${baseURL}${ROUTES.admin}`,
118739
+ });
118740
+ }
118741
+ else {
118742
+ await this.page.goto(`${baseURL}${ROUTES.admin}`, { timeout: 20000 });
118743
+ fetchOtpFromEmail === undefined
118744
+ ? await this.loginViaSSO(email)
118745
+ : await this.loginWithFastmailEmail({ email, fetchOtpFromEmail });
118746
+ await this.setupProfile({ firstName, lastName, country });
118747
+ await this.page.waitForURL(new RegExp(getGlobalUserState().domain), {
118748
+ waitUntil: "load",
118749
+ });
118750
+ }
118680
118751
  await handleOnboarding();
118681
118752
  };
118682
118753
  this.signUp = async ({ credentials, fetchOtpFromEmail, appName, }) => {
118683
- let otp = "123456";
118684
- await this.page.goto(`${ROUTES.neetoAuthSignup}?redirect_uri=${credentials.domain}`, { timeout: 20000 });
118685
- await this.submitEmail(credentials.email);
118686
- if (fetchOtpFromEmail !== undefined) {
118687
- otp = await fetchOtpFromEmail({
118754
+ if (IS_DEV_ENV) {
118755
+ await createOrganizationViaRake({
118756
+ email: credentials.email,
118757
+ firstName: credentials.firstName,
118758
+ lastName: credentials.lastName,
118759
+ subdomainName: credentials.subdomainName,
118760
+ });
118761
+ await fillCredentialsAndSubmit({
118762
+ page: this.page,
118688
118763
  email: credentials.email,
118689
- timeout: 4 * 60 * 1000,
118764
+ loginPath: `${baseURLGenerator(appName, credentials.subdomainName)}${ROUTES.admin}`,
118690
118765
  });
118691
118766
  }
118692
- await this.fillOTP(otp);
118693
- await this.fillOrganizationDetails({
118694
- credentials,
118695
- appName,
118696
- });
118697
- await this.page.waitForURL(new RegExp(credentials.domain));
118767
+ else {
118768
+ let otp = "123456";
118769
+ await this.page.goto(`${ROUTES.neetoAuthSignup}?redirect_uri=${credentials.domain}`, { timeout: 20000 });
118770
+ await this.submitEmail(credentials.email);
118771
+ if (fetchOtpFromEmail !== undefined) {
118772
+ otp = await fetchOtpFromEmail({
118773
+ email: credentials.email,
118774
+ timeout: 4 * 60 * 1000,
118775
+ });
118776
+ }
118777
+ await this.fillOTP(otp);
118778
+ await this.fillOrganizationDetails({
118779
+ credentials,
118780
+ appName,
118781
+ });
118782
+ await this.page.waitForURL(new RegExp(credentials.domain));
118783
+ }
118698
118784
  const STORAGE_STATE = await this.page.context().storageState();
118699
118785
  return { STORAGE_STATE, baseURL: process.env.BASE_URL };
118700
118786
  };
118701
118787
  this.fillOrganizationDetails = async ({ credentials, appName, }) => {
118788
+ if (IS_DEV_ENV)
118789
+ return;
118702
118790
  const subdomainError = this.page.getByTestId(SIGNUP_SELECTORS.subdomainError);
118703
118791
  const organizationSubmitButton = this.page.getByTestId(SIGNUP_SELECTORS.organizationSubmitButton);
118704
118792
  await this.neetoPlaywrightUtilities.waitForPageLoad();
@@ -119677,10 +119765,7 @@ const initializeCredentials = (product) => {
119677
119765
  }
119678
119766
  const stagingData = generateStagingData(product);
119679
119767
  writeDataToFile(JSON.stringify({ user: stagingData }, null, 2));
119680
- if (IS_STAGING_ENV) {
119681
- const baseUrl = `https://${stagingData.subdomainName}.${stagingData.domain}`;
119682
- process.env.BASE_URL = baseUrl;
119683
- }
119768
+ process.env.BASE_URL = baseURLGenerator(product, stagingData.subdomainName);
119684
119769
  };
119685
119770
 
119686
119771
  const assertColumnHeaderVisibility = async ({ page, columnName, shouldBeVisible, }) => {
@@ -124623,7 +124708,6 @@ const playdashLighthouseConfig = {
124623
124708
  tags: process.env.TAG,
124624
124709
  };
124625
124710
  const isCI = neetoCist.isPresent(process.env.NEETO_CI_JOB_ID);
124626
- const isDevEnv = process.env.TEST_ENV === ENVIRONMENT.development;
124627
124711
  const railsPort = process.env.RAILS_SERVER_PORT;
124628
124712
  const vitePort = process.env.VITE_PORT;
124629
124713
  const definePlaywrightConfig = (overrides) => {
@@ -124666,7 +124750,7 @@ const definePlaywrightConfig = (overrides) => {
124666
124750
  timeout: 5 * 60 * 1000,
124667
124751
  workers: isCI ? 6 : 5,
124668
124752
  reporter: isCI ? reporter : [["line"]],
124669
- ...(isDevEnv && {
124753
+ ...(IS_DEV_ENV && {
124670
124754
  webServer: [
124671
124755
  {
124672
124756
  command: `bundle exec puma -b tcp://0.0.0.0:${railsPort} -C config/puma.rb`,
@@ -124785,6 +124869,7 @@ exports.INTEGRATIONS_TEXTS = INTEGRATIONS_TEXTS;
124785
124869
  exports.INTEGRATION_SELECTORS = INTEGRATION_SELECTORS;
124786
124870
  exports.IPRestrictionsPage = IPRestrictionsPage;
124787
124871
  exports.IP_RESTRICTIONS_SELECTORS = IP_RESTRICTIONS_SELECTORS;
124872
+ exports.IS_DEV_ENV = IS_DEV_ENV;
124788
124873
  exports.IS_STAGING_ENV = IS_STAGING_ENV;
124789
124874
  exports.ImageUploader = ImageUploader;
124790
124875
  exports.IntegrationBase = IntegrationBase;
@@ -124870,12 +124955,14 @@ exports.basicHTMLContent = basicHTMLContent;
124870
124955
  exports.clearCredentials = clearCredentials;
124871
124956
  exports.commands = commands;
124872
124957
  exports.cpuThrottlingUsingCDP = cpuThrottlingUsingCDP;
124958
+ exports.createOrganizationViaRake = createOrganizationViaRake;
124873
124959
  exports.currencyUtils = currencyUtils;
124874
124960
  exports.dataQa = dataQa;
124875
124961
  exports.decodeQRCodeFromFile = decodeQRCodeFromFile;
124876
124962
  exports.definePlaywrightConfig = definePlaywrightConfig;
124877
124963
  exports.executeWithThrottledResources = executeWithThrottledResources;
124878
124964
  exports.extractSubdomainFromError = extractSubdomainFromError;
124965
+ exports.fillCredentialsAndSubmit = fillCredentialsAndSubmit;
124879
124966
  exports.filterUtils = filterUtils;
124880
124967
  exports.generatePhoneNumber = generatePhoneNumber;
124881
124968
  exports.generatePhoneNumberDetails = generatePhoneNumberDetails;