@bigbinary/neeto-playwright-commons 1.11.13 → 1.11.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.d.ts CHANGED
@@ -58,9 +58,10 @@ interface FieldValue {
58
58
  }
59
59
  type VerifyFieldValue = (values: FieldValue | FieldValue[]) => Promise<void> | Promise<void[]>;
60
60
  interface SelectOptionFromDropdownParams {
61
- selectValueContainer: string;
62
- selectMenu: string;
61
+ selectValueContainer?: string;
62
+ selectMenu?: string;
63
63
  value: string;
64
+ page?: Page;
64
65
  options?: Partial<{
65
66
  visibilityTimeout: number;
66
67
  textAssertionTimeout: number;
@@ -232,12 +233,14 @@ declare class CustomCommands {
232
233
  *
233
234
  * operation is completed. It takes the following parameters:
234
235
  *
235
- * selectValueContainer: is the selector for the select input container.
236
+ * selectValueContainer (optional): is the selector for the select input container. Default is nui-select-value-container.
236
237
  *
237
- * selectMenu: is the selector for the select input menu.
238
+ * selectMenu (optional): is the selector for the select input menu. Default is nui-select-menu.
238
239
  *
239
240
  * value: is the value to be selected.
240
241
  *
242
+ * page (optional): is the custom page context. Default is POM's page.
243
+ *
241
244
  * options: is an object with the following optional parameters:
242
245
  *
243
246
  * visiblityTimeout: is the time to wait for the select input to be visible. Default is 2000ms.
@@ -272,6 +275,7 @@ declare class CustomCommands {
272
275
  selectValueContainer,
273
276
  selectMenu,
274
277
  value,
278
+ page,
275
279
  options
276
280
  }: SelectOptionFromDropdownParams) => Promise<void>;
277
281
  /**
@@ -1031,6 +1035,16 @@ declare class IntegrationBase {
1031
1035
  */
1032
1036
  gotoIntegrationIndex: () => Promise<void>;
1033
1037
  }
1038
+ type StagingConsentFlowParams = {
1039
+ abortFlow?: boolean;
1040
+ allowPermissions: boolean;
1041
+ };
1042
+ type GooglePageParams = {
1043
+ page: Page;
1044
+ neetoPlaywrightUtilities: CustomCommands;
1045
+ integration: string;
1046
+ integrationRouteIndex?: string;
1047
+ };
1034
1048
  declare class GooglePage extends IntegrationBase {
1035
1049
  totp: TOTP;
1036
1050
  t: TFunction;
@@ -1039,32 +1053,8 @@ declare class GooglePage extends IntegrationBase {
1039
1053
  neetoPlaywrightUtilities,
1040
1054
  integration,
1041
1055
  integrationRouteIndex
1042
- }: {
1043
- page: Page;
1044
- neetoPlaywrightUtilities: CustomCommands;
1045
- integration: string;
1046
- integrationRouteIndex: string;
1047
- });
1048
- /**
1049
- *
1050
- * Connects to slack integration and verifies the connection. It takes the following parameters:
1051
- *
1052
- * redirectUrl: URL to redirect after connecting.
1053
- *
1054
- * customSteps (optional): Custom steps to perform after connection.
1055
- *
1056
- * channelToConfigure (optional): Channel to configure.
1057
- *
1058
- * @example
1059
- *
1060
- * await slackPage.connectAndVerifyIntegration(
1061
- * /example\.com/,
1062
- * customSteps,
1063
- * "general"
1064
- * );
1065
- * @endexample
1066
- */
1067
- connectAndVerifyIntegration: () => Promise<void>;
1056
+ }: GooglePageParams);
1057
+ connectGoogleAccount: (appName: string) => Promise<void>;
1068
1058
  /**
1069
1059
  *
1070
1060
  * Selects the Google account to be used during the integration. If a verification code is required (e.g., for 2FA), it enters the TOTP code.
@@ -1074,7 +1064,7 @@ declare class GooglePage extends IntegrationBase {
1074
1064
  * await googlePage.selectGoogleAccount();
1075
1065
  * @endexample
1076
1066
  */
1077
- selectGoogleAccount: () => Promise<void>;
1067
+ selectGoogleAccount: (appName: string) => Promise<void>;
1078
1068
  /**
1079
1069
  *
1080
1070
  * Automates the login process to a Google account, filling in the email, password, and handling 2FA (Two-Factor Authentication) via TOTP.
@@ -1106,7 +1096,11 @@ declare class GooglePage extends IntegrationBase {
1106
1096
  * @endexample
1107
1097
  */
1108
1098
  disconnectAndVerifyIntegration: () => Promise<void>;
1109
- stagingConsentFlow: () => Promise<void>;
1099
+ stagingConsentFlow: ({
1100
+ abortFlow,
1101
+ allowPermissions
1102
+ }?: Partial<StagingConsentFlowParams>) => Promise<void>;
1103
+ private handleNotVerifiedPage;
1110
1104
  }
1111
1105
  type AsyncNoArgsFunction = () => Promise<void>;
1112
1106
  type RedirectUrl = string | RegExp | ((url: URL) => boolean);
@@ -4441,11 +4435,60 @@ declare const ZAPIER_LIMIT_EXHAUSTED_MESSAGE = "Zapier free task limit is exhaus
4441
4435
  declare const EMOJI_LABEL = "thumbs up";
4442
4436
  declare const SELECT_COUNTRY = "Select country";
4443
4437
  declare const GOOGLE_CALENDAR_DATE_FORMAT = "YYYY/M/D";
4438
+ /**
4439
+ *
4440
+ * googleAccount: Text for google account.
4441
+ *
4442
+ * connectYourGoogleAccount: Text for connecting to your google account.
4443
+ *
4444
+ * signInWithGoogle: Text for signing in with google.
4445
+ *
4446
+ * signInHeading: Text heading for signing in.
4447
+ *
4448
+ * continue: Text for continue.
4449
+ *
4450
+ * selectAll: Text for selecting all permissions.
4451
+ *
4452
+ * appNotVerified: Text indicating app not verified.
4453
+ *
4454
+ * next: Text for next.
4455
+ *
4456
+ * showPassword: Text for showing password.
4457
+ *
4458
+ * emailOrPhone: Text indicating email or phone.
4459
+ *
4460
+ * enterYourPassword: Text for entering your password.
4461
+ *
4462
+ * twoStepVerification: Text for two-step verification.
4463
+ *
4464
+ * enterCode: "Text for entering code.
4465
+ *
4466
+ * allow: Text for allow.
4467
+ *
4468
+ * signOut: Text for signing out.
4469
+ *
4470
+ * wrongCode: "Text for wrong code.
4471
+ *
4472
+ * verificationCode: Text for verification code.
4473
+ *
4474
+ * confirm: Text for confirm.
4475
+ *
4476
+ * cancel: Text for cancel.
4477
+ *
4478
+ * deleteConnections: Text for deleting connections.
4479
+ *
4480
+ * noLongerConnected: Text indicating no longer connected.
4481
+ *
4482
+ * backToSafety: Text label for back to safety button.
4483
+ *
4484
+ * neetoAutomation: Text indicating neeto automation mail id.
4485
+ *
4486
+ */
4444
4487
  declare const GOOGLE_LOGIN_TEXTS: {
4445
4488
  googleAccount: string;
4446
4489
  connectYourGoogleAccount: string;
4447
4490
  signInWithGoogle: string;
4448
- signInHeading: string;
4491
+ signInHeading: (appName: string) => string;
4449
4492
  continue: string;
4450
4493
  selectAll: string;
4451
4494
  appNotVerified: string;
@@ -4459,6 +4502,12 @@ declare const GOOGLE_LOGIN_TEXTS: {
4459
4502
  signOut: string;
4460
4503
  wrongCode: string;
4461
4504
  verificationCode: string;
4505
+ confirm: string;
4506
+ cancel: string;
4507
+ deleteConnections: string;
4508
+ noLongerConnected: string;
4509
+ backToSafety: string;
4510
+ neetoAutomation: string;
4462
4511
  };
4463
4512
  declare const DESCRIPTION_EDITOR_TEXTS: {
4464
4513
  fontSize: string;
package/index.js CHANGED
@@ -3552,23 +3552,23 @@ class CustomCommands {
3552
3552
  })}`;
3553
3553
  return await this.request[method](formattedUrl, requestOptions);
3554
3554
  };
3555
- this.selectOptionFromDropdown = async ({ selectValueContainer, selectMenu, value, options = {}, }) => {
3555
+ this.selectOptionFromDropdown = async ({ selectValueContainer = COMMON_SELECTORS.selectValueContainer, selectMenu = COMMON_SELECTORS.dropdownMenu, value, page = this.page, options = {}, }) => {
3556
3556
  Object.assign({
3557
3557
  visibilityTimeout: 2000,
3558
3558
  textAssertionTimeout: 1000,
3559
3559
  retryTimeout: 20000,
3560
3560
  }, options);
3561
3561
  await expect(async () => {
3562
- await this.page.getByTestId(selectValueContainer).click();
3563
- await expect(this.page.getByTestId(selectMenu)).toBeVisible({
3562
+ await page.getByTestId(selectValueContainer).click();
3563
+ await expect(page.getByTestId(selectMenu)).toBeVisible({
3564
3564
  timeout: options.visibilityTimeout,
3565
3565
  });
3566
- await this.page.keyboard.type(value);
3567
- await this.page
3566
+ await page.keyboard.type(value);
3567
+ await page
3568
3568
  .getByTestId(selectMenu)
3569
3569
  .getByText(value, { exact: true })
3570
3570
  .click();
3571
- await expect(this.page.getByTestId(selectValueContainer)).toContainText(value, { timeout: options.textAssertionTimeout });
3571
+ await expect(page.getByTestId(selectValueContainer)).toContainText(value, { timeout: options.textAssertionTimeout });
3572
3572
  }).toPass({ timeout: options.retryTimeout });
3573
3573
  };
3574
3574
  this.verifyFieldValue = values => {
@@ -13084,7 +13084,7 @@ const GOOGLE_LOGIN_TEXTS = {
13084
13084
  googleAccount: "Google Account:",
13085
13085
  connectYourGoogleAccount: "Connect your Google account",
13086
13086
  signInWithGoogle: "Sign in with Google",
13087
- signInHeading: "Sign in to neetocal.net",
13087
+ signInHeading: (appName) => `Sign in to ${appName}.net`,
13088
13088
  continue: "Continue",
13089
13089
  selectAll: "Select All",
13090
13090
  appNotVerified: "Google hasn’t verified this app",
@@ -13098,6 +13098,12 @@ const GOOGLE_LOGIN_TEXTS = {
13098
13098
  signOut: "Sign out",
13099
13099
  wrongCode: "Wrong code. Try again",
13100
13100
  verificationCode: "verification code",
13101
+ confirm: "Confirm",
13102
+ cancel: "Cancel",
13103
+ deleteConnections: "Delete all connections you",
13104
+ noLongerConnected: "You’re no longer connected to",
13105
+ backToSafety: "Back to safety",
13106
+ neetoAutomation: "neeto.automation",
13101
13107
  };
13102
13108
 
13103
13109
  const HELP_CENTER_SELECTORS = {
@@ -13373,14 +13379,6 @@ class HelpAndProfilePage {
13373
13379
  }
13374
13380
  }
13375
13381
 
13376
- const INTEGRATION_SELECTORS = {
13377
- integrationCard: (integration) => `${integration}-integration-card`,
13378
- connectButton: "connect-button",
13379
- integrationStatusTag: "integration-status-tag",
13380
- disconnectButton: "disconnect-button",
13381
- manageButton: "manage-button",
13382
- };
13383
-
13384
13382
  const GOOGLE_LOGIN_SELECTORS = {
13385
13383
  totpNext: "#totpNext",
13386
13384
  form: "form",
@@ -15134,6 +15132,14 @@ const initializeTotp = ({ issuer, secret, }) => {
15134
15132
  });
15135
15133
  };
15136
15134
 
15135
+ const INTEGRATION_SELECTORS = {
15136
+ integrationCard: (integration) => `${integration}-integration-card`,
15137
+ connectButton: "connect-button",
15138
+ integrationStatusTag: "integration-status-tag",
15139
+ disconnectButton: "disconnect-button",
15140
+ manageButton: "manage-button",
15141
+ };
15142
+
15137
15143
  class IntegrationBase {
15138
15144
  constructor({ page, neetoPlaywrightUtilities, integration, connectHeader, connectedHeader, pageloaderTimeout, integrationRouteIndex, integrationRouteResponsesParams, }) {
15139
15145
  this.disconnect = async (interceptMultipleResponsesParams = {}) => {
@@ -15209,18 +15215,9 @@ class GooglePage extends IntegrationBase {
15209
15215
  integration,
15210
15216
  integrationRouteIndex,
15211
15217
  });
15212
- this.connectAndVerifyIntegration = async () => {
15213
- await this.connect();
15214
- await expect(this.page.getByRole("heading", {
15215
- name: GOOGLE_LOGIN_TEXTS.connectYourGoogleAccount,
15216
- })).toBeVisible({ timeout: 15000 });
15217
- await this.page
15218
- .getByRole("link", {
15219
- name: GOOGLE_LOGIN_TEXTS.signInWithGoogle,
15220
- })
15221
- .click();
15218
+ this.connectGoogleAccount = async (appName) => {
15222
15219
  await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.chooseAccount));
15223
- await this.selectGoogleAccount();
15220
+ await this.selectGoogleAccount(appName);
15224
15221
  if (process.env.TEST_ENV === ENVIRONMENT.staging) {
15225
15222
  await this.stagingConsentFlow();
15226
15223
  }
@@ -15230,22 +15227,26 @@ class GooglePage extends IntegrationBase {
15230
15227
  .getByRole("button", { name: GOOGLE_LOGIN_TEXTS.allow })
15231
15228
  .click();
15232
15229
  }
15233
- await Promise.all([
15234
- expect(this.page.getByRole("heading", { name: this.connectedHeader })).toBeVisible({ timeout: 20000 }),
15235
- expect(this.page.getByTestId(INTEGRATION_SELECTORS.manageButton)).toBeVisible({ timeout: 20000 }),
15236
- ]);
15237
15230
  };
15238
- this.selectGoogleAccount = async () => {
15239
- await this.page.getByRole("link", { name: "neeto.automation" }).click();
15240
- try {
15241
- const verificationCode = this.page
15242
- .locator(GOOGLE_LOGIN_SELECTORS.form)
15243
- .getByText(GOOGLE_LOGIN_TEXTS.verificationCode);
15244
- await expect(verificationCode).toBeVisible({ timeout: 10000 });
15231
+ this.selectGoogleAccount = async (appName) => {
15232
+ const neetoAutomationLocator = this.page.getByRole("link", {
15233
+ name: GOOGLE_LOGIN_TEXTS.neetoAutomation,
15234
+ });
15235
+ await neetoAutomationLocator.click();
15236
+ await expect(neetoAutomationLocator).toBeHidden({ timeout: 10000 });
15237
+ const verificationCode = this.page
15238
+ .locator("form")
15239
+ .getByText(GOOGLE_LOGIN_TEXTS.verificationCode);
15240
+ if (this.page.url().includes(THIRD_PARTY_ROUTES.google.totpChallenge)) {
15245
15241
  await this.enterTotpCode(verificationCode);
15246
- // eslint-disable-next-line no-empty
15247
15242
  }
15248
- catch (error) { }
15243
+ await this.handleNotVerifiedPage();
15244
+ await expect(this.page.getByRole("heading", {
15245
+ name: GOOGLE_LOGIN_TEXTS.signInHeading(appName),
15246
+ })).toBeVisible();
15247
+ await this.page
15248
+ .getByRole("button", { name: GOOGLE_LOGIN_TEXTS.continue })
15249
+ .click();
15249
15250
  };
15250
15251
  this.loginToGoogle = async () => {
15251
15252
  await this.page.goto(THIRD_PARTY_ROUTES.google.signin);
@@ -15268,17 +15269,20 @@ class GooglePage extends IntegrationBase {
15268
15269
  await this.page
15269
15270
  .getByRole("button", { name: GOOGLE_LOGIN_TEXTS.next })
15270
15271
  .click();
15271
- await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.challengeSelection));
15272
- await this.page
15273
- .locator(GOOGLE_LOGIN_SELECTORS.totpChallengeSelector)
15274
- .click();
15272
+ if (this.page.url().includes(THIRD_PARTY_ROUTES.google.challengeSelection)) {
15273
+ await this.page
15274
+ .locator(GOOGLE_LOGIN_SELECTORS.totpChallengeSelector)
15275
+ .click();
15276
+ }
15275
15277
  await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.totpChallenge));
15276
- const twoStepVerification = this.page
15277
- .locator(GOOGLE_LOGIN_SELECTORS.form)
15278
- .getByText(GOOGLE_LOGIN_TEXTS.twoStepVerification);
15278
+ const twoStepVerification = this.page.locator("form").getByRole("heading", {
15279
+ name: GOOGLE_LOGIN_TEXTS.twoStepVerification,
15280
+ level: 2,
15281
+ exact: true,
15282
+ });
15279
15283
  await expect(twoStepVerification).toBeVisible();
15280
15284
  await this.enterTotpCode(twoStepVerification);
15281
- await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.myAccount));
15285
+ await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.myAccount), { waitUntil: "load" });
15282
15286
  };
15283
15287
  this.enterTotpCode = async (locator) => {
15284
15288
  await expect(async () => {
@@ -15286,8 +15290,8 @@ class GooglePage extends IntegrationBase {
15286
15290
  await this.page.getByLabel(GOOGLE_LOGIN_TEXTS.enterCode).fill(totpToken);
15287
15291
  expect(this.totp.validate({ token: totpToken })).not.toBeNull();
15288
15292
  await this.page.locator(GOOGLE_LOGIN_SELECTORS.totpNext).click();
15289
- await expect(this.page.getByText(GOOGLE_LOGIN_TEXTS.wrongCode)).toBeHidden();
15290
- await expect(locator).toBeHidden({ timeout: 20000 });
15293
+ await expect(this.page.getByText(GOOGLE_LOGIN_TEXTS.wrongCode)).toBeHidden({ timeout: 15000 });
15294
+ await expect(locator).toBeHidden({ timeout: 10000 });
15291
15295
  }).toPass({ timeout: 50000 });
15292
15296
  };
15293
15297
  this.logoutFromGoogle = async () => {
@@ -15302,28 +15306,39 @@ class GooglePage extends IntegrationBase {
15302
15306
  await this.disconnect();
15303
15307
  await this.verifyIntegrationStatus("disconnected");
15304
15308
  };
15305
- this.stagingConsentFlow = async () => {
15306
- await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.warningScreen));
15307
- await expect(this.page.getByRole("heading", {
15308
- name: GOOGLE_LOGIN_TEXTS.appNotVerified,
15309
- })).toBeVisible();
15310
- await this.page
15311
- .getByRole("button", { name: GOOGLE_LOGIN_TEXTS.continue })
15312
- .click();
15313
- await expect(this.page.getByRole("heading", {
15314
- name: GOOGLE_LOGIN_TEXTS.signInHeading,
15315
- })).toBeVisible();
15316
- await this.page
15317
- .getByRole("button", { name: GOOGLE_LOGIN_TEXTS.continue })
15318
- .click();
15309
+ this.stagingConsentFlow = async ({ abortFlow = false, allowPermissions = true, } = {}) => {
15310
+ await this.handleNotVerifiedPage();
15311
+ if (this.page.url().includes(THIRD_PARTY_ROUTES.google.additionalInfoScreen)) {
15312
+ await this.page
15313
+ .getByRole("button", { name: GOOGLE_LOGIN_TEXTS.continue })
15314
+ .click({ timeout: 20000 });
15315
+ }
15319
15316
  await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.consentSummary));
15317
+ if (abortFlow) {
15318
+ await this.page
15319
+ .getByRole("button", { name: GOOGLE_LOGIN_TEXTS.cancel })
15320
+ .click({ timeout: 20000 });
15321
+ return;
15322
+ }
15320
15323
  const selectAllPermissions = this.page.getByLabel(GOOGLE_LOGIN_TEXTS.selectAll);
15321
- if (await selectAllPermissions.isVisible()) {
15324
+ if (allowPermissions && (await selectAllPermissions.isVisible())) {
15322
15325
  await selectAllPermissions.click();
15323
15326
  }
15324
15327
  await this.page
15325
15328
  .getByRole("button", { name: GOOGLE_LOGIN_TEXTS.continue })
15326
- .click({ timeout: 15000 });
15329
+ .click({ timeout: 20000 });
15330
+ };
15331
+ this.handleNotVerifiedPage = async () => {
15332
+ const continueUnsafeButton = this.page.getByRole("button", {
15333
+ name: GOOGLE_LOGIN_TEXTS.continue,
15334
+ });
15335
+ const backToSafety = this.page.getByRole("button", {
15336
+ name: GOOGLE_LOGIN_TEXTS.backToSafety,
15337
+ });
15338
+ if (this.page.url().includes(THIRD_PARTY_ROUTES.google.warningScreen)) {
15339
+ await continueUnsafeButton.click();
15340
+ await expect(backToSafety).toBeHidden({ timeout: 10000 });
15341
+ }
15327
15342
  };
15328
15343
  this.totp = initializeTotp({
15329
15344
  issuer: "Google",