@bigbinary/neeto-playwright-commons 1.8.44 → 1.8.46

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
@@ -356,14 +356,26 @@ declare class ZapierPage extends IntegrationBase {
356
356
  disconnectAndVerify: () => Promise<void>;
357
357
  }
358
358
 
359
- interface CreateOrganizationProps {
359
+ interface BasicUserInfo {
360
+ firstName: string;
361
+ lastName: string;
360
362
  email: string;
363
+ }
364
+ interface CreateOrganizationProps extends BasicUserInfo {
361
365
  businessName: string;
362
366
  subdomainName: string;
363
- firstName: string;
364
- lastName: string;
365
367
  appName: string;
366
368
  }
369
+ interface LoginAndOnboardParams extends BasicUserInfo {
370
+ handleOnboarding: () => Promise<void>;
371
+ }
372
+ interface Credentials extends BasicUserInfo {
373
+ otp?: number;
374
+ domain: string;
375
+ currentUserName: string;
376
+ businessName: string;
377
+ subdomainName: string;
378
+ }
367
379
  declare class OrganizationPage {
368
380
  page: Page;
369
381
  neetoPlaywrightUtilities: CustomCommands;
@@ -372,6 +384,45 @@ declare class OrganizationPage {
372
384
  createOrganization: ({ email, businessName, subdomainName, firstName, lastName, appName, }: CreateOrganizationProps) => Promise<void>;
373
385
  setupOrganization: (product: string) => Promise<void>;
374
386
  updateSubdomainIfExists: (appName: string) => Promise<void>;
387
+ loginViaSSO: (email?: string) => Promise<void>;
388
+ setupProfile: ({ firstName, lastName, }?: {
389
+ firstName?: string | undefined;
390
+ lastName?: string | undefined;
391
+ }) => Promise<void>;
392
+ loginAndOnboard: ({ email, firstName, lastName, handleOnboarding, }: LoginAndOnboardParams) => Promise<void>;
393
+ signUp: ({ credentials, fetchOtpFromEmail, appName, }: {
394
+ credentials: Credentials;
395
+ fetchOtpFromEmail?: ((params: {
396
+ email: string;
397
+ timeout: number;
398
+ }) => Promise<string>) | undefined;
399
+ appName: string;
400
+ }) => Promise<{
401
+ STORAGE_STATE: {
402
+ cookies: {
403
+ name: string;
404
+ value: string;
405
+ domain: string;
406
+ path: string;
407
+ expires: number;
408
+ httpOnly: boolean;
409
+ secure: boolean;
410
+ sameSite: "Strict" | "Lax" | "None";
411
+ }[];
412
+ origins: {
413
+ origin: string;
414
+ localStorage: {
415
+ name: string;
416
+ value: string;
417
+ }[];
418
+ }[];
419
+ };
420
+ baseURL: string | undefined;
421
+ }>;
422
+ fillOrganizationDetails: ({ credentials, appName, }: {
423
+ credentials: Credentials;
424
+ appName: string;
425
+ }) => Promise<void>;
375
426
  }
376
427
 
377
428
  declare class SidebarSection {
@@ -413,6 +464,7 @@ declare const ROUTES: {
413
464
  neetoAuth: string;
414
465
  loginLink: string;
415
466
  profile: string;
467
+ admin: string;
416
468
  myProfile: string;
417
469
  authSettings: string;
418
470
  webhooks: string;
package/index.js CHANGED
@@ -12522,6 +12522,7 @@ const ROUTES = {
12522
12522
  neetoAuth: NEETO_AUTH_BASE_URL(),
12523
12523
  loginLink: "/login",
12524
12524
  profile: "/profile",
12525
+ admin: "/admin",
12525
12526
  myProfile: "/my/profile",
12526
12527
  authSettings: "/settings",
12527
12528
  webhooks: "/webhooks",
@@ -12834,10 +12835,12 @@ class HelpAndProfilePage {
12834
12835
  await expect(profileSidebarHeader).toBeHidden();
12835
12836
  });
12836
12837
  await test$2.step("Step 3: Open Help center and verify", this.openHelpCenterV2);
12837
- await test$2.step("Step 4: Open My organization link and verify", async () => this.openAuthLinkAndVerify({
12838
- linkSelector: PROFILE_SECTION_SELECTORS.profileOrganizationSettingsButton,
12839
- redirectLink: ROUTES.authSettings,
12840
- }));
12838
+ await test$2.step("Step 4: Open My organization link and verify", async () => {
12839
+ await this.page
12840
+ .getByTestId(PROFILE_SECTION_SELECTORS.profileOrganizationSettingsButton)
12841
+ .click();
12842
+ await expect(this.page).toHaveURL(new RegExp(ROUTES.authSettings));
12843
+ });
12841
12844
  };
12842
12845
  this.verifyLogoutV2 = async () => {
12843
12846
  if (shouldSkipSetupAndTeardown())
@@ -13444,6 +13447,18 @@ class ZapierPage extends IntegrationBase {
13444
13447
  }
13445
13448
  }
13446
13449
 
13450
+ const LOGIN_SELECTORS = {
13451
+ appleAuthenticationButton: "apple-authentication-button",
13452
+ emailTextField: "login-email-text-field",
13453
+ googleAuthenticationButton: "google-authentication-button",
13454
+ githubAuthenticationButton: "github-authentication-button",
13455
+ loginViaEmailButton: "login-via-email-button",
13456
+ passwordTextField: "login-password-text-field",
13457
+ rememberMeCheckBox: "login-remember-me-check-box",
13458
+ submitButton: "login-submit-button",
13459
+ twitterAuthenticationButton: "twitter-authentication-button",
13460
+ };
13461
+
13447
13462
  const SIGNUP_SELECTORS = {
13448
13463
  emailTextField: "signup-email-text-field",
13449
13464
  firstNameTextField: "signup-profile-first-name-text-field",
@@ -13460,6 +13475,29 @@ const SIGNUP_SELECTORS = {
13460
13475
  unregisterdEmailError: "unregisterd-email-error",
13461
13476
  };
13462
13477
 
13478
+ const loginWithoutSSO = async ({ page, neetoPlaywrightUtilities, loginPath = "/", }) => {
13479
+ if (shouldSkipSetupAndTeardown())
13480
+ return;
13481
+ await page.goto(loginPath);
13482
+ await page.getByTestId("login-email-text-field").fill(CREDENTIALS.email);
13483
+ await page
13484
+ .getByTestId("login-password-text-field")
13485
+ .fill(CREDENTIALS.password);
13486
+ const login = neetoPlaywrightUtilities.interceptMultipleResponses({
13487
+ times: 1,
13488
+ });
13489
+ await page.getByTestId(LOGIN_SELECTORS.submitButton).click();
13490
+ await login;
13491
+ const userCredentials = readFileSyncIfExists();
13492
+ await page.context().storageState({ path: STORAGE_STATE });
13493
+ const mergedCredentials = mergeAll([readFileSyncIfExists(), userCredentials]);
13494
+ writeDataToFile(JSON.stringify(mergedCredentials, null, 2));
13495
+ updateCredentials({ key: "isLoggedIn", value: "true" });
13496
+ };
13497
+ const login = async ({ page, neetoPlaywrightUtilities, loginPath, }) => !IS_STAGING_ENV &&
13498
+ (await loginWithoutSSO({ page, neetoPlaywrightUtilities, loginPath }));
13499
+ const generateRandomBypassEmail = () => `cpt${process.env.OTP_BYPASS_KEY}+${faker.number.int()}@bigbinary.com`;
13500
+
13463
13501
  const extractSubdomainFromError = (errorString) => {
13464
13502
  const regex = /cpt[a-zA-Z0-9-]+/g;
13465
13503
  const matches = errorString.match(regex);
@@ -13492,47 +13530,18 @@ class OrganizationPage {
13492
13530
  await this.page.getByTestId(SIGNUP_SELECTORS.submitButton).click();
13493
13531
  await signup;
13494
13532
  await this.page.getByTestId(SIGNUP_SELECTORS.otpTextBox).fill(defaultOtp);
13495
- await this.page
13496
- .getByTestId(SIGNUP_SELECTORS.organizationNameTextField)
13497
- .fill(businessName);
13498
- const fetchSubdomainAvailability = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13499
- responseUrl: ROUTES.subdomainAvailability,
13500
- timeout: 60 * 1000,
13501
- baseUrl: NEETO_AUTH_BASE_URL(),
13502
- });
13503
- await this.page
13504
- .getByTestId(SIGNUP_SELECTORS.subdomainNameTextField)
13505
- .fill(subdomainName);
13506
- await fetchSubdomainAvailability;
13507
- const subdomainError = this.page.getByTestId(SIGNUP_SELECTORS.subdomainError);
13508
- const subdomainErrorCount = await subdomainError.count();
13509
- if (subdomainErrorCount !== 0) {
13510
- await this.updateSubdomainIfExists(appNameInLowerCase);
13511
- }
13512
- const fetchProfile = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13513
- times: 2,
13514
- timeout: 60 * 1000,
13515
- baseUrl: NEETO_AUTH_BASE_URL(),
13516
- });
13517
- await this.page
13518
- .getByTestId(SIGNUP_SELECTORS.organizationSubmitButton)
13519
- .click();
13520
- await fetchProfile;
13521
- await this.page.waitForURL(`**${ROUTES.profile}`, { timeout: 60 * 1000 });
13522
- await this.page
13523
- .getByTestId(SIGNUP_SELECTORS.firstNameTextField)
13524
- .fill(firstName);
13525
- await this.page
13526
- .getByTestId(SIGNUP_SELECTORS.lastNameTextField)
13527
- .fill(lastName);
13528
- await this.page.getByTestId(COMMON_SELECTORS.checkbox).click();
13529
- const submitProfile = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13530
- responseUrl: ROUTES.signup,
13531
- timeout: 1000 * 60,
13532
- baseUrl: NEETO_AUTH_BASE_URL(),
13533
+ await this.fillOrganizationDetails({
13534
+ credentials: {
13535
+ firstName,
13536
+ lastName,
13537
+ email,
13538
+ currentUserName: email,
13539
+ businessName,
13540
+ subdomainName,
13541
+ domain: appNameInLowerCase,
13542
+ },
13543
+ appName: appNameInLowerCase,
13533
13544
  });
13534
- await this.page.getByTestId(SIGNUP_SELECTORS.profileSubmitButton).click();
13535
- await submitProfile;
13536
13545
  await this.page.waitForURL(new RegExp(getGlobalUserState().domain), {
13537
13546
  waitUntil: "load",
13538
13547
  });
@@ -13601,6 +13610,106 @@ class OrganizationPage {
13601
13610
  }
13602
13611
  }
13603
13612
  };
13613
+ this.loginViaSSO = async (email = generateRandomBypassEmail()) => {
13614
+ await this.page.getByTestId(LOGIN_SELECTORS.emailTextField).fill(email);
13615
+ await expect(async () => {
13616
+ await this.page.getByTestId(LOGIN_SELECTORS.submitButton).click();
13617
+ await expect(this.page.getByTestId(SIGNUP_SELECTORS.unregisterdEmailError)).toBeHidden();
13618
+ }).toPass({ timeout: 15000 });
13619
+ await this.page
13620
+ .getByTestId(SIGNUP_SELECTORS.otpTextBox)
13621
+ .fill(faker.string.numeric(6));
13622
+ };
13623
+ this.setupProfile = async ({ firstName = faker.person.firstName(), lastName = faker.person.lastName(), } = {}) => {
13624
+ await this.page
13625
+ .getByTestId(SIGNUP_SELECTORS.firstNameTextField)
13626
+ .fill(firstName);
13627
+ await this.page
13628
+ .getByTestId(SIGNUP_SELECTORS.lastNameTextField)
13629
+ .fill(lastName);
13630
+ await this.page.getByTestId(COMMON_SELECTORS.checkbox).click();
13631
+ const submitProfile = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13632
+ customPageContext: this.page,
13633
+ responseUrl: ROUTES.signup,
13634
+ baseUrl: NEETO_AUTH_BASE_URL(),
13635
+ timeout: 60000,
13636
+ });
13637
+ await this.page.getByTestId(SIGNUP_SELECTORS.profileSubmitButton).click();
13638
+ await submitProfile;
13639
+ await expect(this.page.getByTestId(COMMON_SELECTORS.pageLoader)).toBeHidden();
13640
+ };
13641
+ this.loginAndOnboard = async ({ email, firstName, lastName, handleOnboarding, }) => {
13642
+ await this.page.goto(ROUTES.admin);
13643
+ await this.loginViaSSO(email);
13644
+ await this.setupProfile({ firstName, lastName });
13645
+ await this.page.waitForURL(new RegExp(getGlobalUserState().domain), {
13646
+ waitUntil: "load",
13647
+ });
13648
+ await handleOnboarding();
13649
+ };
13650
+ this.signUp = async ({ credentials, fetchOtpFromEmail, appName, }) => {
13651
+ let otp = "123456";
13652
+ await this.page.goto(`${ROUTES.neetoAuthSignup}?redirect_uri=${credentials.domain}`);
13653
+ await this.page
13654
+ .getByTestId(SIGNUP_SELECTORS.emailTextField)
13655
+ .fill(credentials.email);
13656
+ const signup = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13657
+ responseUrl: ROUTES.signup,
13658
+ timeout: 60 * 1000,
13659
+ baseUrl: NEETO_AUTH_BASE_URL(),
13660
+ });
13661
+ await this.page.getByTestId(SIGNUP_SELECTORS.submitButton).click();
13662
+ await signup;
13663
+ if (fetchOtpFromEmail !== undefined) {
13664
+ otp = await fetchOtpFromEmail({
13665
+ email: credentials.email,
13666
+ timeout: 4 * 60 * 1000,
13667
+ });
13668
+ }
13669
+ await this.page.getByTestId(SIGNUP_SELECTORS.otpTextBox).fill(otp);
13670
+ await this.fillOrganizationDetails({
13671
+ credentials,
13672
+ appName,
13673
+ });
13674
+ await this.page.waitForURL(new RegExp(credentials.domain));
13675
+ const STORAGE_STATE = await this.page.context().storageState();
13676
+ return { STORAGE_STATE, baseURL: process.env.BASE_URL };
13677
+ };
13678
+ this.fillOrganizationDetails = async ({ credentials, appName, }) => {
13679
+ await this.page
13680
+ .getByTestId(SIGNUP_SELECTORS.organizationNameTextField)
13681
+ .fill(credentials.businessName);
13682
+ const fetchSubdomainAvailability = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13683
+ responseUrl: ROUTES.subdomainAvailability,
13684
+ timeout: 60 * 1000,
13685
+ baseUrl: NEETO_AUTH_BASE_URL(),
13686
+ });
13687
+ await this.page
13688
+ .getByTestId(SIGNUP_SELECTORS.subdomainNameTextField)
13689
+ .fill(credentials.subdomainName);
13690
+ await fetchSubdomainAvailability;
13691
+ const subdomainError = this.page.getByTestId(SIGNUP_SELECTORS.subdomainError);
13692
+ const subdomainErrorCount = await subdomainError.count();
13693
+ if (subdomainErrorCount !== 0) {
13694
+ await this.updateSubdomainIfExists(appName);
13695
+ }
13696
+ const fetchProfile = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13697
+ times: 2,
13698
+ timeout: 60 * 1000,
13699
+ baseUrl: NEETO_AUTH_BASE_URL(),
13700
+ });
13701
+ await this.page
13702
+ .getByTestId(SIGNUP_SELECTORS.organizationSubmitButton)
13703
+ .click();
13704
+ await fetchProfile;
13705
+ await this.page.waitForURL(`**${ROUTES.profile}`, {
13706
+ timeout: 60 * 1000,
13707
+ });
13708
+ await this.setupProfile({
13709
+ firstName: credentials.firstName,
13710
+ lastName: credentials.lastName,
13711
+ });
13712
+ };
13604
13713
  this.page = page;
13605
13714
  this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
13606
13715
  }
@@ -13684,18 +13793,6 @@ const NEETO_FILTERS_SELECTORS = {
13684
13793
  paneModalCrossIcon: "neeto-filters-close-button",
13685
13794
  };
13686
13795
 
13687
- const LOGIN_SELECTORS = {
13688
- appleAuthenticationButton: "apple-authentication-button",
13689
- emailTextField: "login-email-text-field",
13690
- googleAuthenticationButton: "google-authentication-button",
13691
- githubAuthenticationButton: "github-authentication-button",
13692
- loginViaEmailButton: "login-via-email-button",
13693
- passwordTextField: "login-password-text-field",
13694
- rememberMeCheckBox: "login-remember-me-check-box",
13695
- submitButton: "login-submit-button",
13696
- twitterAuthenticationButton: "twitter-authentication-button",
13697
- };
13698
-
13699
13796
  const MEMBER_SELECTORS = {
13700
13797
  membersTab: "members-nav-tab",
13701
13798
  newButton: "ntm-add-member-button",
@@ -13799,29 +13896,6 @@ const initializeCredentials = (product) => {
13799
13896
  }
13800
13897
  };
13801
13898
 
13802
- const loginWithoutSSO = async ({ page, neetoPlaywrightUtilities, loginPath = "/", }) => {
13803
- if (shouldSkipSetupAndTeardown())
13804
- return;
13805
- await page.goto(loginPath);
13806
- await page.getByTestId("login-email-text-field").fill(CREDENTIALS.email);
13807
- await page
13808
- .getByTestId("login-password-text-field")
13809
- .fill(CREDENTIALS.password);
13810
- const login = neetoPlaywrightUtilities.interceptMultipleResponses({
13811
- times: 1,
13812
- });
13813
- await page.getByTestId(LOGIN_SELECTORS.submitButton).click();
13814
- await login;
13815
- const userCredentials = readFileSyncIfExists();
13816
- await page.context().storageState({ path: STORAGE_STATE });
13817
- const mergedCredentials = mergeAll([readFileSyncIfExists(), userCredentials]);
13818
- writeDataToFile(JSON.stringify(mergedCredentials, null, 2));
13819
- updateCredentials({ key: "isLoggedIn", value: "true" });
13820
- };
13821
- const login = async ({ page, neetoPlaywrightUtilities, loginPath, }) => !IS_STAGING_ENV &&
13822
- (await loginWithoutSSO({ page, neetoPlaywrightUtilities, loginPath }));
13823
- const generateRandomBypassEmail = () => `cpt${process.env.OTP_BYPASS_KEY}+${faker.number.int()}@bigbinary.com`;
13824
-
13825
13899
  const addMemberViaRequest = ({ email, role = MEMBER_TEXTS.agent, appName, neetoPlaywrightUtilities, }) => neetoPlaywrightUtilities.apiRequest({
13826
13900
  method: "post",
13827
13901
  url: API_ROUTES.teamMembers.index,