@bigbinary/neeto-playwright-commons 1.8.45 → 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",
@@ -13446,6 +13447,18 @@ class ZapierPage extends IntegrationBase {
13446
13447
  }
13447
13448
  }
13448
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
+
13449
13462
  const SIGNUP_SELECTORS = {
13450
13463
  emailTextField: "signup-email-text-field",
13451
13464
  firstNameTextField: "signup-profile-first-name-text-field",
@@ -13462,6 +13475,29 @@ const SIGNUP_SELECTORS = {
13462
13475
  unregisterdEmailError: "unregisterd-email-error",
13463
13476
  };
13464
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
+
13465
13501
  const extractSubdomainFromError = (errorString) => {
13466
13502
  const regex = /cpt[a-zA-Z0-9-]+/g;
13467
13503
  const matches = errorString.match(regex);
@@ -13494,47 +13530,18 @@ class OrganizationPage {
13494
13530
  await this.page.getByTestId(SIGNUP_SELECTORS.submitButton).click();
13495
13531
  await signup;
13496
13532
  await this.page.getByTestId(SIGNUP_SELECTORS.otpTextBox).fill(defaultOtp);
13497
- await this.page
13498
- .getByTestId(SIGNUP_SELECTORS.organizationNameTextField)
13499
- .fill(businessName);
13500
- const fetchSubdomainAvailability = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13501
- responseUrl: ROUTES.subdomainAvailability,
13502
- timeout: 60 * 1000,
13503
- baseUrl: NEETO_AUTH_BASE_URL(),
13504
- });
13505
- await this.page
13506
- .getByTestId(SIGNUP_SELECTORS.subdomainNameTextField)
13507
- .fill(subdomainName);
13508
- await fetchSubdomainAvailability;
13509
- const subdomainError = this.page.getByTestId(SIGNUP_SELECTORS.subdomainError);
13510
- const subdomainErrorCount = await subdomainError.count();
13511
- if (subdomainErrorCount !== 0) {
13512
- await this.updateSubdomainIfExists(appNameInLowerCase);
13513
- }
13514
- const fetchProfile = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13515
- times: 2,
13516
- timeout: 60 * 1000,
13517
- baseUrl: NEETO_AUTH_BASE_URL(),
13518
- });
13519
- await this.page
13520
- .getByTestId(SIGNUP_SELECTORS.organizationSubmitButton)
13521
- .click();
13522
- await fetchProfile;
13523
- await this.page.waitForURL(`**${ROUTES.profile}`, { timeout: 60 * 1000 });
13524
- await this.page
13525
- .getByTestId(SIGNUP_SELECTORS.firstNameTextField)
13526
- .fill(firstName);
13527
- await this.page
13528
- .getByTestId(SIGNUP_SELECTORS.lastNameTextField)
13529
- .fill(lastName);
13530
- await this.page.getByTestId(COMMON_SELECTORS.checkbox).click();
13531
- const submitProfile = this.neetoPlaywrightUtilities.interceptMultipleResponses({
13532
- responseUrl: ROUTES.signup,
13533
- timeout: 1000 * 60,
13534
- 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,
13535
13544
  });
13536
- await this.page.getByTestId(SIGNUP_SELECTORS.profileSubmitButton).click();
13537
- await submitProfile;
13538
13545
  await this.page.waitForURL(new RegExp(getGlobalUserState().domain), {
13539
13546
  waitUntil: "load",
13540
13547
  });
@@ -13603,6 +13610,106 @@ class OrganizationPage {
13603
13610
  }
13604
13611
  }
13605
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
+ };
13606
13713
  this.page = page;
13607
13714
  this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
13608
13715
  }
@@ -13686,18 +13793,6 @@ const NEETO_FILTERS_SELECTORS = {
13686
13793
  paneModalCrossIcon: "neeto-filters-close-button",
13687
13794
  };
13688
13795
 
13689
- const LOGIN_SELECTORS = {
13690
- appleAuthenticationButton: "apple-authentication-button",
13691
- emailTextField: "login-email-text-field",
13692
- googleAuthenticationButton: "google-authentication-button",
13693
- githubAuthenticationButton: "github-authentication-button",
13694
- loginViaEmailButton: "login-via-email-button",
13695
- passwordTextField: "login-password-text-field",
13696
- rememberMeCheckBox: "login-remember-me-check-box",
13697
- submitButton: "login-submit-button",
13698
- twitterAuthenticationButton: "twitter-authentication-button",
13699
- };
13700
-
13701
13796
  const MEMBER_SELECTORS = {
13702
13797
  membersTab: "members-nav-tab",
13703
13798
  newButton: "ntm-add-member-button",
@@ -13801,29 +13896,6 @@ const initializeCredentials = (product) => {
13801
13896
  }
13802
13897
  };
13803
13898
 
13804
- const loginWithoutSSO = async ({ page, neetoPlaywrightUtilities, loginPath = "/", }) => {
13805
- if (shouldSkipSetupAndTeardown())
13806
- return;
13807
- await page.goto(loginPath);
13808
- await page.getByTestId("login-email-text-field").fill(CREDENTIALS.email);
13809
- await page
13810
- .getByTestId("login-password-text-field")
13811
- .fill(CREDENTIALS.password);
13812
- const login = neetoPlaywrightUtilities.interceptMultipleResponses({
13813
- times: 1,
13814
- });
13815
- await page.getByTestId(LOGIN_SELECTORS.submitButton).click();
13816
- await login;
13817
- const userCredentials = readFileSyncIfExists();
13818
- await page.context().storageState({ path: STORAGE_STATE });
13819
- const mergedCredentials = mergeAll([readFileSyncIfExists(), userCredentials]);
13820
- writeDataToFile(JSON.stringify(mergedCredentials, null, 2));
13821
- updateCredentials({ key: "isLoggedIn", value: "true" });
13822
- };
13823
- const login = async ({ page, neetoPlaywrightUtilities, loginPath, }) => !IS_STAGING_ENV &&
13824
- (await loginWithoutSSO({ page, neetoPlaywrightUtilities, loginPath }));
13825
- const generateRandomBypassEmail = () => `cpt${process.env.OTP_BYPASS_KEY}+${faker.number.int()}@bigbinary.com`;
13826
-
13827
13899
  const addMemberViaRequest = ({ email, role = MEMBER_TEXTS.agent, appName, neetoPlaywrightUtilities, }) => neetoPlaywrightUtilities.apiRequest({
13828
13900
  method: "post",
13829
13901
  url: API_ROUTES.teamMembers.index,