@bigbinary/neeto-playwright-commons 1.26.11 → 1.26.13

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
@@ -2146,7 +2146,7 @@ declare class GooglePage extends IntegrationBase {
2146
2146
  * @endexample
2147
2147
  */
2148
2148
  loginToGoogle: () => Promise<void>;
2149
- enterTotpCode: (locator: Locator) => Promise<void>;
2149
+ enterTotpCode: () => Promise<void>;
2150
2150
  /**
2151
2151
  *
2152
2152
  * Logs out of the Google account by navigating to the account settings and clicking the "Sign Out" button.
@@ -7690,7 +7690,7 @@ declare const getListCount: ({
7690
7690
  declare const getGlobalUserProps: (page: Page) => Promise<Record<string, string>>;
7691
7691
  /**
7692
7692
  *
7693
- * 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.
7694
7694
  *
7695
7695
  * page: The Playwright Page object representing the current browser page.
7696
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) => [
@@ -116391,11 +116427,8 @@ class GooglePage extends IntegrationBase {
116391
116427
  .getByRole("link", { name: GOOGLE_LOGIN_TEXTS.neetoAutomation })
116392
116428
  .click();
116393
116429
  await expect(chooseAnAccountHeading).toBeHidden({ timeout: 10000 });
116394
- const verificationCode = this.page
116395
- .locator("form")
116396
- .getByText(GOOGLE_LOGIN_TEXTS.verificationCode);
116397
116430
  this.page.url().includes(THIRD_PARTY_ROUTES.google.totpChallenge) &&
116398
- (await this.enterTotpCode(verificationCode));
116431
+ (await this.enterTotpCode());
116399
116432
  await this.handleNotVerifiedPage();
116400
116433
  const signInHeading = this.page.getByRole("heading", {
116401
116434
  name: GOOGLE_LOGIN_TEXTS.signInHeading(appName),
@@ -116434,32 +116467,29 @@ class GooglePage extends IntegrationBase {
116434
116467
  .click());
116435
116468
  await this.page.waitForLoadState("load", { timeout: 25000 });
116436
116469
  await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.totpChallenge));
116437
- const twoStepVerification = this.page.locator("form").getByRole("heading", {
116438
- name: GOOGLE_LOGIN_TEXTS.twoStepVerification,
116439
- level: 2,
116440
- exact: true,
116441
- });
116442
- await expect(twoStepVerification).toBeVisible({ timeout: 15000 });
116443
- await this.enterTotpCode(twoStepVerification);
116470
+ await this.enterTotpCode();
116444
116471
  await this.page.waitForLoadState("load", { timeout: 25000 });
116445
116472
  await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.myAccount));
116446
116473
  };
116447
- this.enterTotpCode = async (locator) => {
116474
+ this.enterTotpCode = async () => {
116448
116475
  let previousToken = null;
116476
+ const codeInput = this.page.getByLabel(GOOGLE_LOGIN_TEXTS.enterCode);
116477
+ await expect(codeInput).toBeVisible({ timeout: 20000 });
116449
116478
  await expect(async () => {
116450
116479
  let totpToken = this.totp.generate({ timestamp: Date.now() });
116451
116480
  if (totpToken === previousToken) {
116452
116481
  const remainingTime = this.totp.remaining({ timestamp: Date.now() });
116482
+ // Wait for the remaining time plus a small buffer to ensure new token is generated
116453
116483
  // eslint-disable-next-line playwright/no-wait-for-timeout
116454
- await this.page.waitForTimeout(remainingTime + 500); // Wait for the remaining time plus a small buffer (500ms) to ensure new token
116484
+ await this.page.waitForTimeout(remainingTime + 500);
116455
116485
  totpToken = this.totp.generate({ timestamp: Date.now() });
116456
116486
  }
116457
116487
  previousToken = totpToken;
116458
- await this.page.getByLabel(GOOGLE_LOGIN_TEXTS.enterCode).fill(totpToken);
116488
+ await codeInput.fill(totpToken);
116459
116489
  expect(this.totp.validate({ token: totpToken })).not.toBeNull();
116460
116490
  await this.page.locator(GOOGLE_LOGIN_SELECTORS.totpNext).click();
116461
116491
  await expect(this.page.getByText(GOOGLE_LOGIN_TEXTS.wrongCode)).toBeHidden({ timeout: 10000 });
116462
- await expect(locator).toBeHidden({ timeout: 10000 });
116492
+ await expect(codeInput).toBeHidden({ timeout: 15000 });
116463
116493
  }).toPass({ timeout: 2 * 60 * 1000 });
116464
116494
  };
116465
116495
  this.logoutFromGoogle = async () => {