@bigbinary/neeto-playwright-commons 1.26.10 → 1.26.12

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
@@ -3937,6 +3937,8 @@ declare class OrganizationPage {
3937
3937
  * @endexample
3938
3938
  */
3939
3939
  baseUrlGenerator: (appName: string) => string;
3940
+ private fillOTP;
3941
+ private submitEmail;
3940
3942
  /**
3941
3943
  *
3942
3944
  * Used to create a new organization. It takes the following parameters:
@@ -6674,6 +6676,7 @@ declare const SIGNUP_SELECTORS: {
6674
6676
  signupViaEmailButton: string;
6675
6677
  submitButton: string;
6676
6678
  subdomainNameTextField: string;
6679
+ subdomainAvailabilityMsg: string;
6677
6680
  subdomainError: string;
6678
6681
  tryFreeButton: string;
6679
6682
  /** @deprecated Use unregisteredEmailError instead. */
@@ -7687,7 +7690,7 @@ declare const getListCount: ({
7687
7690
  declare const getGlobalUserProps: (page: Page) => Promise<Record<string, string>>;
7688
7691
  /**
7689
7692
  *
7690
- * Fetches the current text content from the system clipboard in the browser context.
7693
+ * Fetches the current text content from the system clipboard in the browser context. It first attempts to use the native clipboard API (navigator.clipboard.readText()). If that fails, it falls back to creating a temporary textarea and using keyboard paste to retrieve the clipboard content.
7691
7694
  *
7692
7695
  * page: The Playwright Page object representing the current browser page.
7693
7696
  *
package/index.js CHANGED
@@ -8,7 +8,7 @@ import path__default from 'path';
8
8
  import test, { expect, test as test$1, chromium as chromium$1, defineConfig, devices } from '@playwright/test';
9
9
  import { getI18nInstance, initI18n } from 'playwright-i18next-fixture';
10
10
  import require$$0$4 from 'util';
11
- import { curry, not, isEmpty, pluck, mergeDeepLeft, isNil, isNotNil, mergeAll } from 'ramda';
11
+ import { curry, isNotNil, not, isEmpty, pluck, mergeDeepLeft, isNil, mergeAll } from 'ramda';
12
12
  import { execSync } from 'child_process';
13
13
  import dayjs from 'dayjs';
14
14
  import require$$0$7 from 'stream';
@@ -4886,7 +4886,7 @@ const removeCredentialFile = () => {
4886
4886
  require$$0$3.unlink(STORAGE_STATE, error => {
4887
4887
  if (!error)
4888
4888
  return;
4889
- console.log(error);
4889
+ console.error(error);
4890
4890
  });
4891
4891
  };
4892
4892
  const clearCredentials = () => {
@@ -4955,7 +4955,43 @@ const getListCount = async ({ page, countSelector, }) => {
4955
4955
  return Number(countText === null || countText === void 0 ? void 0 : countText.trim().split(" ")[0]);
4956
4956
  };
4957
4957
  const getGlobalUserProps = async (page) => (await page.evaluate(() => window.globalProps.user));
4958
- const getClipboardContent = (page) => page.evaluate(() => navigator.clipboard.readText());
4958
+ const createTextareaAndEvaluateCopiedText = async (page) => {
4959
+ const textareaHandle = await page.evaluateHandle(() => {
4960
+ const textarea = document.createElement("textarea");
4961
+ Object.assign(textarea.style, {
4962
+ position: "fixed",
4963
+ top: "0",
4964
+ left: "0",
4965
+ opacity: "0",
4966
+ pointerEvents: "none",
4967
+ zIndex: "9999",
4968
+ });
4969
+ document.body.appendChild(textarea);
4970
+ textarea.focus();
4971
+ return textarea;
4972
+ });
4973
+ try {
4974
+ await page.keyboard.press("ControlOrMeta+v");
4975
+ return await page.evaluate(el => el.value, textareaHandle);
4976
+ }
4977
+ finally {
4978
+ await textareaHandle.evaluate(el => el.remove());
4979
+ await textareaHandle.dispose();
4980
+ }
4981
+ };
4982
+ const getClipboardContent = async (page) => {
4983
+ // Attempt 1: Native Clipboard API
4984
+ const clipboardText = await page.evaluate(async () => {
4985
+ var _a;
4986
+ if (!((_a = navigator.clipboard) === null || _a === void 0 ? void 0 : _a.readText))
4987
+ return null;
4988
+ return await navigator.clipboard.readText();
4989
+ });
4990
+ if (isNotNil(clipboardText))
4991
+ return clipboardText;
4992
+ // Attempt 2: Keyboard paste fallback
4993
+ return createTextareaAndEvaluateCopiedText(page);
4994
+ };
4959
4995
  const grantClipboardPermissions = (context) => context.grantPermissions(["clipboard-read", "clipboard-write"]);
4960
4996
  const getFullUrl = (path) => shouldSkipCustomDomainSetup() ? path : `${process.env.BASE_URL}${path}`;
4961
4997
  const globalShortcuts = (t) => [
@@ -5296,6 +5332,7 @@ const SIGNUP_SELECTORS = {
5296
5332
  signupViaEmailButton: "signup-via-email-button",
5297
5333
  submitButton: "signup-email-submit-button",
5298
5334
  subdomainNameTextField: "signup-organization-subdomain-text-field",
5335
+ subdomainAvailabilityMsg: "subdomain-availability-message",
5299
5336
  subdomainError: "subdomain-input-error",
5300
5337
  tryFreeButton: "neeto-auth-signup-link",
5301
5338
  /** @deprecated Use unregisteredEmailError instead. */
@@ -116419,7 +116456,7 @@ class GooglePage extends IntegrationBase {
116419
116456
  .click();
116420
116457
  await this.page.waitForLoadState("load", { timeout: 25000 });
116421
116458
  await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.password));
116422
- await expect(this.page.getByText(GOOGLE_LOGIN_TEXTS.showPassword)).toBeVisible();
116459
+ await expect(this.page.getByText(GOOGLE_LOGIN_TEXTS.showPassword)).toBeVisible({ timeout: 10000 });
116423
116460
  await this.page
116424
116461
  .getByLabel(GOOGLE_LOGIN_TEXTS.enterYourPassword)
116425
116462
  .pressSequentially(process.env.GOOGLE_LOGIN_PASSWORD, { delay: 10 });
@@ -116438,7 +116475,7 @@ class GooglePage extends IntegrationBase {
116438
116475
  level: 2,
116439
116476
  exact: true,
116440
116477
  });
116441
- await expect(twoStepVerification).toBeVisible();
116478
+ await expect(twoStepVerification).toBeVisible({ timeout: 15000 });
116442
116479
  await this.enterTotpCode(twoStepVerification);
116443
116480
  await this.page.waitForLoadState("load", { timeout: 25000 });
116444
116481
  await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.myAccount));
@@ -118485,22 +118522,29 @@ class OrganizationPage {
118485
118522
  const { subdomainName } = getGlobalUserState();
118486
118523
  return `https://${subdomainName}.${appName}.net`;
118487
118524
  };
118525
+ this.fillOTP = async (otp = faker.string.numeric(6)) => {
118526
+ await this.neetoPlaywrightUtilities.waitForPageLoad();
118527
+ const otpTextBox = this.page.getByTestId(SIGNUP_SELECTORS.otpTextBox);
118528
+ await otpTextBox.fill(otp);
118529
+ await expect(otpTextBox).toBeHidden({ timeout: 35000 });
118530
+ };
118531
+ this.submitEmail = async (email) => {
118532
+ await this.neetoPlaywrightUtilities.waitForPageLoad();
118533
+ await this.page.getByTestId(SIGNUP_SELECTORS.emailTextField).fill(email);
118534
+ const submitButton = this.page.getByTestId(SIGNUP_SELECTORS.submitButton);
118535
+ await submitButton.click();
118536
+ await expect(submitButton).toBeHidden({ timeout: 35000 });
118537
+ };
118488
118538
  this.createOrganization = async ({ email, businessName, subdomainName, firstName, lastName, appName, }) => {
118489
118539
  if (!IS_STAGING_ENV || shouldSkipSetupAndTeardown())
118490
118540
  return;
118491
- const defaultOtp = "123456";
118492
118541
  const appNameInLowerCase = appName.toLowerCase();
118493
118542
  const isNeetoAuth = appNameInLowerCase === "neetoauth";
118494
118543
  isNeetoAuth
118495
118544
  ? await this.page.goto(ROUTES.neetoAuthSignup, { timeout: 20000 })
118496
118545
  : await this.page.goto(`${ROUTES.neetoAuthSignup}?redirect_uri=${appNameInLowerCase}.net/admin`, { timeout: 20000 });
118497
- await this.neetoPlaywrightUtilities.waitForPageLoad();
118498
- const submitButton = this.page.getByTestId(SIGNUP_SELECTORS.submitButton);
118499
- await this.page.getByTestId(SIGNUP_SELECTORS.emailTextField).fill(email);
118500
- await submitButton.click();
118501
- await expect(submitButton).toBeHidden({ timeout: 30000 });
118502
- await this.neetoPlaywrightUtilities.waitForPageLoad();
118503
- await this.page.getByTestId(SIGNUP_SELECTORS.otpTextBox).fill(defaultOtp);
118546
+ await this.submitEmail(email);
118547
+ await this.fillOTP();
118504
118548
  await this.fillOrganizationDetails({
118505
118549
  credentials: {
118506
118550
  firstName,
@@ -118574,6 +118618,7 @@ class OrganizationPage {
118574
118618
  }
118575
118619
  };
118576
118620
  this.fillEmailAndSubmit = async (email, loginTimeout) => {
118621
+ await this.neetoPlaywrightUtilities.waitForPageLoad();
118577
118622
  await this.page.getByTestId(LOGIN_SELECTORS.emailTextField).fill(email);
118578
118623
  const unregisteredEmailError = this.page.getByTestId(SIGNUP_SELECTORS.unregisteredEmailError);
118579
118624
  await expect(async () => {
@@ -118584,19 +118629,15 @@ class OrganizationPage {
118584
118629
  };
118585
118630
  this.loginViaSSO = async (email = generateRandomBypassEmail(), loginTimeout = 2 * 60 * 1000) => {
118586
118631
  await this.fillEmailAndSubmit(email, loginTimeout);
118587
- await this.page
118588
- .getByTestId(SIGNUP_SELECTORS.otpTextBox)
118589
- .fill(faker.string.numeric(6));
118632
+ await this.fillOTP();
118590
118633
  };
118591
118634
  this.loginWithFastmailEmail = async ({ email, loginTimeout = 2 * 60 * 1000, fetchOtpFromEmail, }) => {
118592
118635
  await this.fillEmailAndSubmit(email, loginTimeout);
118593
- const otp = await fetchOtpFromEmail({
118594
- email,
118595
- timeout: 4 * 60 * 1000,
118596
- });
118597
- await this.page.getByTestId(SIGNUP_SELECTORS.otpTextBox).fill(otp);
118636
+ const otp = await fetchOtpFromEmail({ email, timeout: 4 * 60 * 1000 });
118637
+ await this.fillOTP(otp);
118598
118638
  };
118599
118639
  this.setupProfile = async ({ firstName = faker.person.firstName(), lastName = faker.person.lastName(), country, } = {}) => {
118640
+ await this.neetoPlaywrightUtilities.waitForPageLoad();
118600
118641
  await this.page
118601
118642
  .getByTestId(SIGNUP_SELECTORS.firstNameTextField)
118602
118643
  .fill(firstName);
@@ -118626,19 +118667,14 @@ class OrganizationPage {
118626
118667
  this.signUp = async ({ credentials, fetchOtpFromEmail, appName, }) => {
118627
118668
  let otp = "123456";
118628
118669
  await this.page.goto(`${ROUTES.neetoAuthSignup}?redirect_uri=${credentials.domain}`, { timeout: 20000 });
118629
- await this.page
118630
- .getByTestId(SIGNUP_SELECTORS.emailTextField)
118631
- .fill(credentials.email);
118632
- const submitButton = this.page.getByTestId(SIGNUP_SELECTORS.submitButton);
118633
- await submitButton.click();
118634
- await expect(submitButton).toBeHidden({ timeout: 10000 });
118670
+ await this.submitEmail(credentials.email);
118635
118671
  if (fetchOtpFromEmail !== undefined) {
118636
118672
  otp = await fetchOtpFromEmail({
118637
118673
  email: credentials.email,
118638
118674
  timeout: 4 * 60 * 1000,
118639
118675
  });
118640
118676
  }
118641
- await this.page.getByTestId(SIGNUP_SELECTORS.otpTextBox).fill(otp);
118677
+ await this.fillOTP(otp);
118642
118678
  await this.fillOrganizationDetails({
118643
118679
  credentials,
118644
118680
  appName,
@@ -118650,6 +118686,7 @@ class OrganizationPage {
118650
118686
  this.fillOrganizationDetails = async ({ credentials, appName, }) => {
118651
118687
  const subdomainError = this.page.getByTestId(SIGNUP_SELECTORS.subdomainError);
118652
118688
  const organizationSubmitButton = this.page.getByTestId(SIGNUP_SELECTORS.organizationSubmitButton);
118689
+ await this.neetoPlaywrightUtilities.waitForPageLoad();
118653
118690
  await this.page
118654
118691
  .getByTestId(SIGNUP_SELECTORS.organizationNameTextField)
118655
118692
  .fill(humanize(credentials.businessName));
@@ -118658,10 +118695,7 @@ class OrganizationPage {
118658
118695
  .fill(credentials.subdomainName);
118659
118696
  const subdomainErrorCount = await subdomainError.count();
118660
118697
  subdomainErrorCount !== 0 && (await this.updateSubdomainIfExists(appName));
118661
- //TODO: Use getByTestId when this issue https://github.com/bigbinary/neeto-auth-web/issues/6460 is resolved
118662
- await expect(this.page.getByTitle(ORGANIZATION_TEXTS.subdomainAvailable)).toBeVisible({
118663
- timeout: 45000,
118664
- });
118698
+ await expect(this.page.getByTestId(SIGNUP_SELECTORS.subdomainAvailabilityMsg)).toBeVisible({ timeout: 45000 });
118665
118699
  await organizationSubmitButton.click();
118666
118700
  await Promise.all([
118667
118701
  expect(organizationSubmitButton).toBeHidden({ timeout: 45 * 1000 }),