@bigbinary/neeto-playwright-commons 1.23.9 → 1.24.0

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.cjs.js CHANGED
@@ -102,6 +102,11 @@ const THIRD_PARTY_ROUTES = {
102
102
  slack: {
103
103
  loginWithPassword: (workspace) => `https://${workspace}.slack.com/sign_in_with_password`,
104
104
  },
105
+ microsoft: {
106
+ login: "https://login.microsoftonline.com/",
107
+ myApps: "https://myapplications.microsoft.com/",
108
+ staySignedIn: "https://login.microsoftonline.com/common/SAS/ProcessAuth",
109
+ },
105
110
  zapier: {
106
111
  login: "https://zapier.com/",
107
112
  logOut: "https://zapier.com/logout",
@@ -154,6 +159,30 @@ class CustomDomainApi {
154
159
  }
155
160
  }
156
161
 
162
+ const IP_RESTRICTIONS_BASE_URL = `ip_restrictions${BASE_URL}/ip_restriction`;
163
+ class IpRestrictionsApi {
164
+ constructor(neetoPlaywrightUtilities) {
165
+ this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
166
+ this.enable = ({ ipStart, ipEnd, addressType }) => this.neetoPlaywrightUtilities.apiRequest({
167
+ url: IP_RESTRICTIONS_BASE_URL,
168
+ method: "patch",
169
+ body: {
170
+ ip_restriction: {
171
+ is_ip_restriction_enabled: true,
172
+ allowed_ip_ranges: [
173
+ { ip_start: ipStart, ip_end: ipEnd, address_type: addressType },
174
+ ],
175
+ },
176
+ },
177
+ });
178
+ this.disable = () => this.neetoPlaywrightUtilities.apiRequest({
179
+ body: { ip_restriction: { is_ip_restriction_enabled: false } },
180
+ url: IP_RESTRICTIONS_BASE_URL,
181
+ method: "patch",
182
+ });
183
+ }
184
+ }
185
+
157
186
  class MemberApis {
158
187
  constructor(neetoPlaywrightUtilities) {
159
188
  this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
@@ -4627,7 +4656,7 @@ const writeDataToFile = data => {
4627
4656
  require$$0__namespace.writeFileSync(STORAGE_STATE, data, "utf8");
4628
4657
  }
4629
4658
  catch (error) {
4630
- console.log(error); // eslint-disable-line
4659
+ console.log(error);
4631
4660
  }
4632
4661
  return true;
4633
4662
  };
@@ -4640,7 +4669,7 @@ const removeCredentialFile = () => {
4640
4669
  require$$0__namespace.unlink(STORAGE_STATE, error => {
4641
4670
  if (!error)
4642
4671
  return;
4643
- console.log(error); // eslint-disable-line
4672
+ console.log(error);
4644
4673
  });
4645
4674
  };
4646
4675
  const clearCredentials = () => {
@@ -5269,6 +5298,7 @@ const IP_RESTRICTIONS_SELECTORS = {
5269
5298
  ipStartInpError: "ip-start-input-error",
5270
5299
  ipEndInpError: "ip-end-input-error",
5271
5300
  typeSelectError: "type-select-error",
5301
+ resetButton: "ip-restriction-reset-button",
5272
5302
  };
5273
5303
 
5274
5304
  const DATE_PICKER_SELECTORS = {
@@ -5295,6 +5325,15 @@ const NEETO_SEO_SELECTORS = {
5295
5325
  configureButton: "neeto-seo-configure-button",
5296
5326
  };
5297
5327
 
5328
+ const MICROSOFT_LOGIN_SELECTORS = {
5329
+ acceptButton: '[data-report-event="Signin_Submit"]',
5330
+ cancelButton: 'input[type="button"]',
5331
+ signInProfileIcon: "#mectrl_headerPicture",
5332
+ emailInput: '[type="email"]',
5333
+ placeholder: ".placeholderInnerContainer",
5334
+ dropdownMenu: "button[aria-label='NeetoForm - Stagingapp context menu']",
5335
+ };
5336
+
5298
5337
  const mimeTypeMap = {
5299
5338
  csv: "text/csv",
5300
5339
  avi: "video/x-msvideo",
@@ -5359,24 +5398,19 @@ class CustomCommands {
5359
5398
  .getAttribute("content");
5360
5399
  return this.csrfToken;
5361
5400
  };
5362
- /**
5363
- * @deprecated Use UI assertions instead.
5364
- */
5365
- this.interceptMultipleResponses = ({ responseUrl = "", responseStatus = 200, times = 1, baseUrl, customPageContext, timeout = 35000, } = {}) => {
5366
- const pageContext = customPageContext !== null && customPageContext !== void 0 ? customPageContext : this.page;
5367
- return Promise.all([...new Array(times)].map(() => pageContext.waitForResponse((response) => {
5368
- var _a, _b, _c;
5369
- if (response.request().resourceType() === "xhr" &&
5370
- response.status() === responseStatus &&
5371
- response.url().includes(responseUrl) &&
5372
- response.url().startsWith((_a = baseUrl !== null && baseUrl !== void 0 ? baseUrl : this.baseURL) !== null && _a !== void 0 ? _a : "") &&
5373
- !this.responses.includes((_b = response.headers()) === null || _b === void 0 ? void 0 : _b["x-request-id"])) {
5374
- this.responses.push((_c = response.headers()) === null || _c === void 0 ? void 0 : _c["x-request-id"]);
5375
- return true;
5376
- }
5377
- return false;
5378
- }, { timeout })));
5379
- };
5401
+ this.waitForFloatingMenu = () => test.expect(this.page.getByTestId(COMMON_SELECTORS.floatingActionMenuButton)).toBeVisible({ timeout: 25000 });
5402
+ this.interceptMultipleResponses = ({ responseUrl = "", responseStatus = 200, times = 1, baseUrl, customPageContext = this.page, timeout = 35000, } = {}) => Promise.all([...new Array(times)].map(() => customPageContext.waitForResponse((response) => {
5403
+ var _a, _b, _c;
5404
+ if (response.request().resourceType() === "xhr" &&
5405
+ response.status() === responseStatus &&
5406
+ response.url().includes(responseUrl) &&
5407
+ response.url().startsWith((_a = baseUrl !== null && baseUrl !== void 0 ? baseUrl : this.baseURL) !== null && _a !== void 0 ? _a : "") &&
5408
+ !this.responses.includes((_b = response.headers()) === null || _b === void 0 ? void 0 : _b["x-request-id"])) {
5409
+ this.responses.push((_c = response.headers()) === null || _c === void 0 ? void 0 : _c["x-request-id"]);
5410
+ return true;
5411
+ }
5412
+ return false;
5413
+ }, { timeout })));
5380
5414
  this.recursiveMethod = async (callback, condition, timeout, startTime, iteration) => {
5381
5415
  if (Date.now() - timeout >= startTime) {
5382
5416
  await callback();
@@ -5412,9 +5446,7 @@ class CustomCommands {
5412
5446
  /**
5413
5447
  * @deprecated Use reload & waitForPageLoad instead.
5414
5448
  */
5415
- this.reloadAndWait = async (
5416
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
5417
- requestCount, customPageContext = this.page,
5449
+ this.reloadAndWait = async (requestCount, customPageContext = this.page,
5418
5450
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
5419
5451
  interceptMultipleResponsesProps = {}) => {
5420
5452
  await customPageContext.reload();
@@ -5454,24 +5486,23 @@ class CustomCommands {
5454
5486
  return await this.request[method](formattedUrl, requestOptions);
5455
5487
  };
5456
5488
  this.selectOptionFromDropdown = async ({ label = "nui", value, page = this.page, options = {}, }) => {
5457
- const selectValueContainerSelector = COMMON_SELECTORS.customSelectValueContainer(label);
5458
- const selectMenuSelector = COMMON_SELECTORS.customDropDownMenu(label);
5459
5489
  Object.assign({
5460
5490
  visibilityTimeout: 2000,
5461
5491
  textAssertionTimeout: 1000,
5462
5492
  retryTimeout: 20000,
5463
5493
  }, options);
5494
+ const menu = page.getByTestId(COMMON_SELECTORS.customDropDownMenu(label));
5495
+ const container = page.getByTestId(COMMON_SELECTORS.customSelectValueContainer(label));
5464
5496
  await test.expect(async () => {
5465
- await page.getByTestId(selectValueContainerSelector).click();
5466
- await test.expect(page.getByTestId(selectMenuSelector)).toBeVisible({
5497
+ await container.click();
5498
+ await test.expect(menu).toBeVisible({
5467
5499
  timeout: options.visibilityTimeout,
5468
5500
  });
5469
5501
  await page.keyboard.type(value);
5470
- await page
5471
- .getByTestId(selectMenuSelector)
5472
- .getByText(value, { exact: true })
5473
- .click();
5474
- await test.expect(page.getByTestId(selectValueContainerSelector)).toContainText(value, { timeout: options.textAssertionTimeout });
5502
+ await menu.getByText(value, { exact: true }).click();
5503
+ await test.expect(container).toContainText(value, {
5504
+ timeout: options.textAssertionTimeout,
5505
+ });
5475
5506
  }).toPass({ timeout: options.retryTimeout });
5476
5507
  };
5477
5508
  this.verifyFieldValue = values => {
@@ -113290,16 +113321,11 @@ const i18nFixture = {
113290
113321
  ],
113291
113322
  };
113292
113323
 
113324
+ /**
113325
+ * @deprecated
113326
+ */
113293
113327
  class AdminPanelPage {
113294
113328
  constructor(page, neetoPlaywrightUtilities) {
113295
- /**
113296
- * @deprecated This method is deprecated. Use assertCardDetails from neetoPlaywrightUtilities instead.
113297
- */
113298
- this.verifyAdminPanelCard = ({ cardLocator, title, description, }) => Promise.all([
113299
- test.expect(cardLocator.getByTestId(ADMIN_PANEL_SELECTORS.settingsItemHeading)).toHaveText(title),
113300
- test.expect(cardLocator.getByTestId(ADMIN_PANEL_SELECTORS.settingsItemDescription)).toHaveText(description),
113301
- test.expect(this.page.getByTestId(COMMON_SELECTORS.sidebarSubLink(title))).toHaveCSS("background-color", COLOR.transparent),
113302
- ]);
113303
113329
  this.page = page;
113304
113330
  this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
113305
113331
  this.t = playwrightI18nextFixture.getI18nInstance().t;
@@ -113380,26 +113406,6 @@ class ThankYouPage {
113380
113406
 
113381
113407
  class EmbedBase {
113382
113408
  constructor({ context, page, neetoPlaywrightUtilities, appName, }) {
113383
- /**
113384
- * @deprecated This method is deprecated. Use initializeEmbedPage instead.
113385
- */
113386
- this.initializeEmbedPageV2 = async ({ embedType, embedCode, customElementText = "Click here", }) => {
113387
- this.embedTestPage = await this.context.newPage();
113388
- this.embedTestPageType = embedType;
113389
- const fileContent = basicHTMLContent(this.embedTestPageType === "elementPopup"
113390
- ? `${embedCode}<a href='#' id='open-popup-button'>${customElementText}</a>`
113391
- : embedCode);
113392
- this.filePath = `tmp/${faker.faker.word.noun()}.html`;
113393
- require$$0$4.writeFileSync(this.filePath, fileContent, "utf8");
113394
- await this.embedTestPage.goto(`file://${path$1.resolve(this.filePath)}`, {
113395
- timeout: 20000,
113396
- });
113397
- await this.embedTestPage.waitForLoadState("load");
113398
- this.embeddedFrame = this.embedTestPage.frameLocator(this.embedTestPageType === "inline" || this.embedTestPageType === "iframe"
113399
- ? "iframe"
113400
- : EMBED_SELECTORS.iframe(this.appName));
113401
- return this.embedTestPage;
113402
- };
113403
113409
  this.initializeEmbedPage = async ({ embedType, embedCode, customElementText = "Click here", }) => {
113404
113410
  this.embedTestPage = await this.context.newPage();
113405
113411
  this.embedTestPageType = embedType;
@@ -113442,26 +113448,11 @@ class EmbedBase {
113442
113448
  });
113443
113449
  }).toPass({ timeout: 2 * 60 * 1000 });
113444
113450
  };
113445
- /**
113446
- * @deprecated This method is deprecated. Use copyEmbedScript instead.
113447
- */
113448
- this.copyEmbedScriptV2 = async (embedType) => {
113449
- await this.selectEmbedType(embedType);
113450
- await this.page.getByTestId(COMMON_SELECTORS.copyButton).click();
113451
- return await this.page.evaluate(() => navigator.clipboard.readText());
113452
- };
113453
113451
  this.copyEmbedScript = async (embedType) => {
113454
113452
  await this.selectEmbedType(embedType);
113455
113453
  await this.page.getByTestId(COMMON_SELECTORS.copyButton).click();
113456
113454
  return await this.page.evaluate(() => navigator.clipboard.readText());
113457
113455
  };
113458
- /**
113459
- * @deprecated This method is deprecated. Use selectEmbedType instead.
113460
- */
113461
- this.selectEmbedTypeV2 = async (embedType) => {
113462
- await this.page.locator(EMBED_SELECTORS.embedSelector(embedType)).click();
113463
- await this.neetoPlaywrightUtilities.waitForPageLoad();
113464
- };
113465
113456
  this.selectEmbedType = async (embedType) => {
113466
113457
  await this.page.locator(EMBED_SELECTORS.embedSelector(embedType)).click();
113467
113458
  await this.neetoPlaywrightUtilities.waitForPageLoad();
@@ -113633,6 +113624,20 @@ const ZAPIER_LIMIT_EXHAUSTED_MESSAGE = "Zapier free task limit is exhausted. Tes
113633
113624
  const EMOJI_LABEL = "thumbs up";
113634
113625
  const SELECT_COUNTRY = "Select country";
113635
113626
  const GOOGLE_CALENDAR_DATE_FORMAT = "YYYY/M/D";
113627
+ const MICROSOFT_LOGIN_TEXTS = {
113628
+ passwordInput: "Enter the password",
113629
+ emailInput: "Enter your email",
113630
+ enterCode: "Enter code",
113631
+ verify: "Verify",
113632
+ staySignedIn: "Stay signed in?",
113633
+ signIn: "Sign in",
113634
+ next: "Next",
113635
+ enterPassword: "Enter password",
113636
+ password: "Password",
113637
+ permissionsRequested: "Permissions requested",
113638
+ yes: "Yes",
113639
+ remove: "Remove",
113640
+ };
113636
113641
  const GOOGLE_LOGIN_TEXTS = {
113637
113642
  googleAccount: "Google Account:",
113638
113643
  connectYourGoogleAccount: "Connect your Google account",
@@ -116042,11 +116047,11 @@ class IntegrationBase {
116042
116047
  });
116043
116048
  };
116044
116049
  this.gotoIntegrationIndex = async () => {
116045
- if (neetoCist.isNotEmpty(this.integrationRouteIndex)) {
116046
- await this.page.goto(this.integrationRouteIndex, { timeout: 20000 });
116047
- await test.expect(this.page.getByTestId(COMMON_SELECTORS.floatingActionMenuButton)).toBeVisible({ timeout: 25000 });
116048
- await this.neetoPlaywrightUtilities.waitForPageLoad();
116049
- }
116050
+ if (ramda.isEmpty(this.integrationRouteIndex))
116051
+ return;
116052
+ await this.page.goto(this.integrationRouteIndex, { timeout: 20000 });
116053
+ await this.neetoPlaywrightUtilities.waitForFloatingMenu();
116054
+ await this.neetoPlaywrightUtilities.waitForPageLoad();
116050
116055
  };
116051
116056
  this.page = page;
116052
116057
  this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
@@ -116229,7 +116234,113 @@ class GooglePage extends IntegrationBase {
116229
116234
  }
116230
116235
  }
116231
116236
 
116232
- /* eslint-disable playwright/no-raw-locators */
116237
+ class MicrosoftPage extends IntegrationBase {
116238
+ constructor({ page, neetoPlaywrightUtilities, integrationRouteIndex, integration = "", }) {
116239
+ super({
116240
+ page,
116241
+ neetoPlaywrightUtilities,
116242
+ integrationRouteIndex,
116243
+ integration,
116244
+ });
116245
+ this.stagingConsentFlow = async (abortFlow = false) => {
116246
+ await this.page.waitForLoadState("load", { timeout: 25000 });
116247
+ await test.expect(this.page.getByRole("heading", {
116248
+ name: MICROSOFT_LOGIN_TEXTS.permissionsRequested,
116249
+ })).toBeVisible({ timeout: 20000 });
116250
+ await this.page
116251
+ .locator(abortFlow
116252
+ ? MICROSOFT_LOGIN_SELECTORS.cancelButton
116253
+ : MICROSOFT_LOGIN_SELECTORS.acceptButton)
116254
+ .click();
116255
+ await this.page.waitForLoadState("load", { timeout: 25000 });
116256
+ await this.neetoPlaywrightUtilities.waitForFloatingMenu();
116257
+ };
116258
+ this.enterEmail = async () => {
116259
+ await this.page.waitForLoadState("load", { timeout: 25000 });
116260
+ await test.expect(this.page.getByRole("heading", { name: MICROSOFT_LOGIN_TEXTS.signIn })).toBeVisible({ timeout: 20000 });
116261
+ await this.page
116262
+ .locator(MICROSOFT_LOGIN_SELECTORS.emailInput)
116263
+ .or(this.page.locator(MICROSOFT_LOGIN_SELECTORS.placeholder))
116264
+ .or(this.page.getByRole("textbox", {
116265
+ name: MICROSOFT_LOGIN_TEXTS.emailInput,
116266
+ }))
116267
+ .pressSequentially(process.env.MICROSOFT_LOGIN_EMAIL, { delay: 25 });
116268
+ };
116269
+ this.enterPassword = async () => {
116270
+ await this.page.waitForLoadState("load", { timeout: 25000 });
116271
+ await test.expect(this.page.getByRole("heading", {
116272
+ name: MICROSOFT_LOGIN_TEXTS.enterPassword,
116273
+ })).toBeVisible({ timeout: 10000 });
116274
+ await this.page
116275
+ .getByPlaceholder(MICROSOFT_LOGIN_TEXTS.password)
116276
+ .or(this.page.locator(MICROSOFT_LOGIN_SELECTORS.placeholder))
116277
+ .or(this.page.getByRole("textbox", {
116278
+ name: MICROSOFT_LOGIN_TEXTS.passwordInput,
116279
+ }))
116280
+ .pressSequentially(process.env.MICROSOFT_LOGIN_PASSWORD, { delay: 15 });
116281
+ };
116282
+ this.loginToMicrosoft = async () => {
116283
+ if (ramda.isNil(process.env.MICROSOFT_LOGIN_EMAIL) ||
116284
+ ramda.isNil(process.env.MICROSOFT_LOGIN_PASSWORD) ||
116285
+ ramda.isNil(process.env.MICROSOFT_2FA_SECRET_KEY)) {
116286
+ throw new Error("ENV variable MICROSOFT_LOGIN_EMAIL or MICROSOFT_LOGIN_PASSWORD or MICROSOFT_2FA_SECRET_KEY is not properly configured");
116287
+ }
116288
+ await this.page.goto(THIRD_PARTY_ROUTES.microsoft.login);
116289
+ await this.enterEmail();
116290
+ await this.page
116291
+ .getByRole("button", { name: MICROSOFT_LOGIN_TEXTS.next })
116292
+ .click();
116293
+ await this.enterPassword();
116294
+ await this.page
116295
+ .getByRole("button", { name: MICROSOFT_LOGIN_TEXTS.signIn })
116296
+ .click();
116297
+ await this.enterTotpCode();
116298
+ await this.staySignedIn();
116299
+ };
116300
+ this.enterTotpCode = async () => {
116301
+ const verifyBtn = this.page.getByRole("button", {
116302
+ name: MICROSOFT_LOGIN_TEXTS.verify,
116303
+ });
116304
+ await this.page.waitForLoadState("load", { timeout: 25000 });
116305
+ await test.expect(async () => {
116306
+ const token = this.totp.generate({ timestamp: Date.now() + 5000 });
116307
+ await this.page.getByLabel(MICROSOFT_LOGIN_TEXTS.enterCode).fill(token);
116308
+ test.expect(this.totp.validate({ token })).not.toBeNull();
116309
+ await verifyBtn.click();
116310
+ await test.expect(this.page.getByRole("alert")).toBeHidden();
116311
+ await test.expect(verifyBtn).toBeHidden();
116312
+ }).toPass({ timeout: 60 * 1000, intervals: [10000] });
116313
+ };
116314
+ this.staySignedIn = async () => {
116315
+ await this.page.waitForLoadState("load", { timeout: 25000 });
116316
+ await this.page.waitForURL(THIRD_PARTY_ROUTES.microsoft.staySignedIn);
116317
+ await test.expect(this.page.getByRole("heading", {
116318
+ name: MICROSOFT_LOGIN_TEXTS.staySignedIn,
116319
+ })).toBeVisible({ timeout: 15000 });
116320
+ const acceptBtn = this.page.locator(MICROSOFT_LOGIN_SELECTORS.acceptButton);
116321
+ await acceptBtn.click();
116322
+ await test.expect(acceptBtn).toBeHidden({ timeout: 10000 });
116323
+ await this.page.waitForLoadState("load", { timeout: 25000 });
116324
+ };
116325
+ this.revokePermissions = async () => {
116326
+ await this.page.goto(THIRD_PARTY_ROUTES.microsoft.myApps);
116327
+ await this.page.waitForLoadState("load", { timeout: 25000 });
116328
+ const dropdown = this.page.locator(MICROSOFT_LOGIN_SELECTORS.dropdownMenu);
116329
+ await dropdown.click();
116330
+ await this.page
116331
+ .getByRole("menuitem", { name: MICROSOFT_LOGIN_TEXTS.remove })
116332
+ .click();
116333
+ await test.expect(dropdown).toBeHidden({ timeout: 10000 });
116334
+ await this.page.waitForLoadState("load", { timeout: 25000 });
116335
+ };
116336
+ this.mailerUtils = new MailerUtils(neetoPlaywrightUtilities);
116337
+ this.totp = initializeTotp({
116338
+ issuer: "Microsoft",
116339
+ secret: process.env.MICROSOFT_2FA_SECRET_KEY,
116340
+ });
116341
+ }
116342
+ }
116343
+
116233
116344
  class SlackPage extends IntegrationBase {
116234
116345
  constructor({ page, neetoPlaywrightUtilities, integrationRouteIndex, }) {
116235
116346
  super({
@@ -116278,6 +116389,7 @@ class SlackPage extends IntegrationBase {
116278
116389
  await this.page
116279
116390
  .getByRole("button", { name: this.t("neetoSlack.common.continue") })
116280
116391
  .click();
116392
+ await this.neetoPlaywrightUtilities.waitForPageLoad();
116281
116393
  if (customSteps) {
116282
116394
  await customSteps();
116283
116395
  }
@@ -116297,11 +116409,7 @@ class SlackPage extends IntegrationBase {
116297
116409
  await this.disconnect();
116298
116410
  await this.verifyIntegrationStatus("disconnected");
116299
116411
  };
116300
- this.updateConfigureSlackChannel = async ({ newSlackChannel = "random",
116301
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
116302
- interceptMultipleResponsesParams = {},
116303
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
116304
- refreshInterceptMultipleResponsesParams = {}, refreshChannelList = false, }) => {
116412
+ this.updateConfigureSlackChannel = async ({ newSlackChannel = "random", refreshChannelList = false, }) => {
116305
116413
  await this.page.getByTestId(INTEGRATION_SELECTORS.manageButton).click();
116306
116414
  await this.page
116307
116415
  .getByRole("button", { name: this.t("neetoSlack.common.edit") })
@@ -116367,17 +116475,16 @@ class SlackPage extends IntegrationBase {
116367
116475
  })
116368
116476
  .click();
116369
116477
  };
116370
- this.goToSlackChannel = async (slackChannel) => {
116371
- await this.slackWebappPage
116372
- .locator(SLACK_SELECTORS.virtualListItem, { hasText: slackChannel })
116373
- .click();
116374
- };
116478
+ this.goToSlackChannel = (slackChannel) => this.slackWebappPage
116479
+ .locator(SLACK_SELECTORS.virtualListItem, { hasText: slackChannel })
116480
+ .click();
116375
116481
  this.createNewSlackChannel = async ({ channelName, kind = "public", }) => {
116376
116482
  await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.sectionHeadingButton).click();
116377
116483
  await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.channelSectionSubmenuCreate).click();
116378
116484
  await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.channelSectionMenuCreateChannel).click();
116485
+ const spinner = this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.infiniteSpinner);
116379
116486
  await test.expect(this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.skModalContent)).toBeVisible();
116380
- await test.expect(this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.infiniteSpinner)).toBeHidden();
116487
+ await test.expect(spinner).toBeHidden();
116381
116488
  await test.expect(this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.channelNameOptionsList)).toBeHidden({ timeout: 5000 });
116382
116489
  await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.skModalContent)
116383
116490
  .getByText(SLACK_WEB_TEXTS.name, { exact: true })
@@ -116386,13 +116493,14 @@ class SlackPage extends IntegrationBase {
116386
116493
  SLACK_DATA_QA_SELECTORS.skModalContent,
116387
116494
  SLACK_DATA_QA_SELECTORS.channelNameInput,
116388
116495
  ]).pressSequentially(channelName);
116389
- await test.expect(this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.infiniteSpinner)).toBeHidden();
116390
- await test.expect(this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.createChannelNextButton)).toBeEnabled();
116391
- await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.createChannelNextButton).click();
116496
+ const nextButton = this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.createChannelNextButton);
116497
+ await test.expect(spinner).toBeHidden();
116498
+ await test.expect(nextButton).toBeEnabled();
116499
+ await nextButton.click();
116392
116500
  await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.skModalContent)
116393
116501
  .getByRole("radio", { name: kind })
116394
116502
  .check();
116395
- await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.createChannelNextButton).click();
116503
+ await nextButton.click();
116396
116504
  await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.inviteToWorkspaceSkipButton).click();
116397
116505
  };
116398
116506
  this.deleteSlackChannel = async (channel) => {
@@ -117526,9 +117634,7 @@ class TeamMembers {
117526
117634
  }).toPass({ timeout: 40000 });
117527
117635
  await this.neetoPlaywrightUtilities.verifyToast();
117528
117636
  };
117529
- this.searchAndVerifyMemberByEmail = async ({ email,
117530
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
117531
- interceptOptions = {}, }) => {
117637
+ this.searchAndVerifyMemberByEmail = async ({ email }) => {
117532
117638
  await this.neetoPlaywrightUtilities.waitForPageLoad();
117533
117639
  await this.page.getByTestId(MEMBER_SELECTORS.searchTextField).fill(email);
117534
117640
  const emailSubstr = email.length > 20 ? email.substring(0, 20) : email;
@@ -118163,6 +118269,69 @@ class CustomDomainPage {
118163
118269
  }
118164
118270
  }
118165
118271
 
118272
+ class IPRestrictionsPage {
118273
+ constructor(page, neetoPlaywrightUtilities) {
118274
+ this.page = page;
118275
+ this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
118276
+ this.setIPRange = async (ipRange, type, index = 0) => {
118277
+ await this.page
118278
+ .getByTestId(IP_RESTRICTIONS_SELECTORS.ipStartTextField)
118279
+ // Using nth methods here as it determines which input to interact with
118280
+ // eslint-disable-next-line playwright/no-nth-methods
118281
+ .nth(index)
118282
+ .fill(ipRange[0]);
118283
+ await this.page
118284
+ .getByTestId(IP_RESTRICTIONS_SELECTORS.ipEndTextField)
118285
+ // Using nth methods here as it determines which input to interact with
118286
+ // eslint-disable-next-line playwright/no-nth-methods
118287
+ .nth(index)
118288
+ .fill(ipRange[1]);
118289
+ if (!neetoCist.isPresent(type))
118290
+ return;
118291
+ await this.page
118292
+ .getByTestId(COMMON_SELECTORS.customSelectContainer("type"))
118293
+ // Using nth methods here as it determines which dropdown to interact with
118294
+ // eslint-disable-next-line playwright/no-nth-methods
118295
+ .nth(index)
118296
+ .fill(type);
118297
+ await this.page.keyboard.press("Enter");
118298
+ await test.expect(this.page
118299
+ .getByTestId(COMMON_SELECTORS.customSelectValueContainer("type"))
118300
+ // Using nth methods here as it determines which dropdown to interact with
118301
+ // eslint-disable-next-line playwright/no-nth-methods
118302
+ .nth(index)).toContainText(type);
118303
+ };
118304
+ this.saveChanges = async () => {
118305
+ await this.saveButton.click();
118306
+ await this.neetoPlaywrightUtilities.clickButtonAndAwaitLoad({
118307
+ locator: this.page.getByTestId(COMMON_SELECTORS.alertModalSubmitButton),
118308
+ });
118309
+ };
118310
+ this.disableIPRestriction = async () => {
118311
+ if (!this.page.url().includes(ROUTES.adminPanel.ipRestriction))
118312
+ return;
118313
+ const enableCheckbox = this.page.getByTestId(IP_RESTRICTIONS_SELECTORS.enableIPRestrictionChk);
118314
+ const [isChecked, isSaveDisabled, isDeleteHidden] = await Promise.all([
118315
+ enableCheckbox.isChecked(),
118316
+ this.saveButton.isDisabled(),
118317
+ this.page
118318
+ .getByTestId(IP_RESTRICTIONS_SELECTORS.ipRangeDeleteBtn)
118319
+ .isHidden(),
118320
+ ]);
118321
+ if (isChecked && (isSaveDisabled || isDeleteHidden)) {
118322
+ await enableCheckbox.click();
118323
+ if (await this.saveButton.isEnabled()) {
118324
+ await this.saveButton.click();
118325
+ await this.neetoPlaywrightUtilities.verifyToast();
118326
+ }
118327
+ }
118328
+ };
118329
+ this.t = playwrightI18nextFixture.getI18nInstance().t;
118330
+ this.ipRestrictionsApi = new IpRestrictionsApi(this.neetoPlaywrightUtilities);
118331
+ this.saveButton = this.page.getByTestId(IP_RESTRICTIONS_SELECTORS.saveChanges);
118332
+ }
118333
+ }
118334
+
118166
118335
  class RolesPage {
118167
118336
  constructor(page, neetoPlaywrightUtilities) {
118168
118337
  this.getPermissionIds = async (targetPermissions, isGranularPermission = false) => {
@@ -118226,11 +118395,6 @@ class RolesPage {
118226
118395
  this.neetoPlaywrightUtilities.verifyToast(),
118227
118396
  ]);
118228
118397
  };
118229
- this.verifyAdminPanelCard = ({ cardLocator, title, description, }) => Promise.all([
118230
- test.expect(cardLocator.getByTestId(ADMIN_PANEL_SELECTORS.settingsItemHeading)).toHaveText(title),
118231
- test.expect(cardLocator.getByTestId(ADMIN_PANEL_SELECTORS.settingsItemDescription)).toHaveText(description),
118232
- test.expect(this.page.getByTestId(COMMON_SELECTORS.sidebarSubLink(title))).toHaveCSS("background-color", COLOR.transparent),
118233
- ]);
118234
118398
  this.deleteRoleViaUI = async (roleName) => {
118235
118399
  await this.neetoPlaywrightUtilities.waitForPageLoad();
118236
118400
  await this.page.getByTestId(ROLES_SELECTORS.searchTextField).fill(roleName);
@@ -118259,17 +118423,11 @@ class RolesPage {
118259
118423
  if (neetoCist.isNotEqualDeep(roleAccessableLinks, adminAccessableLinks)) {
118260
118424
  for (const link of adminAccessableLinks) {
118261
118425
  await this.page.goto(link);
118262
- await test.expect
118263
- .soft(this.page.getByTestId(COMMON_SELECTORS.floatingActionMenuButton))
118264
- .toBeVisible({ timeout: 15000 });
118426
+ await this.neetoPlaywrightUtilities.waitForFloatingMenu();
118265
118427
  await this.neetoPlaywrightUtilities.waitForPageLoad();
118266
- await test.expect(this.page.locator(COMMON_SELECTORS.tableSpinner)).toBeHidden({ timeout: 35000 });
118267
- const unauthorizedHeading = this.page.getByRole("heading", {
118428
+ await test.expect(this.page.getByRole("heading", {
118268
118429
  name: this.t("neetoMolecules.errorPage.unauthorized"),
118269
- });
118270
- roleAccessableLinks.includes(link)
118271
- ? await test.expect(unauthorizedHeading).toBeHidden()
118272
- : await test.expect(unauthorizedHeading).toBeVisible();
118430
+ }))[roleAccessableLinks.includes(link) ? "toBeHidden" : "toBeVisible"]();
118273
118431
  }
118274
118432
  }
118275
118433
  };
@@ -123863,10 +124021,12 @@ exports.HELP_CENTER_SELECTORS = HELP_CENTER_SELECTORS;
123863
124021
  exports.HelpAndProfilePage = HelpAndProfilePage;
123864
124022
  exports.INTEGRATIONS_TEXTS = INTEGRATIONS_TEXTS;
123865
124023
  exports.INTEGRATION_SELECTORS = INTEGRATION_SELECTORS;
124024
+ exports.IPRestrictionsPage = IPRestrictionsPage;
123866
124025
  exports.IP_RESTRICTIONS_SELECTORS = IP_RESTRICTIONS_SELECTORS;
123867
124026
  exports.IS_STAGING_ENV = IS_STAGING_ENV;
123868
124027
  exports.ImageUploader = ImageUploader;
123869
124028
  exports.IntegrationBase = IntegrationBase;
124029
+ exports.IpRestrictionsApi = IpRestrictionsApi;
123870
124030
  exports.KEYBOARD_SHORTCUTS_SELECTORS = KEYBOARD_SHORTCUTS_SELECTORS;
123871
124031
  exports.LIST_MODIFIER_SELECTORS = LIST_MODIFIER_SELECTORS;
123872
124032
  exports.LIST_MODIFIER_TAGS = LIST_MODIFIER_TAGS;
@@ -123875,9 +124035,12 @@ exports.MEMBER_FORM_SELECTORS = MEMBER_FORM_SELECTORS;
123875
124035
  exports.MEMBER_SELECTORS = MEMBER_SELECTORS;
123876
124036
  exports.MEMBER_TEXTS = MEMBER_TEXTS;
123877
124037
  exports.MERGE_TAGS_SELECTORS = MERGE_TAGS_SELECTORS;
124038
+ exports.MICROSOFT_LOGIN_SELECTORS = MICROSOFT_LOGIN_SELECTORS;
124039
+ exports.MICROSOFT_LOGIN_TEXTS = MICROSOFT_LOGIN_TEXTS;
123878
124040
  exports.MailerUtils = MailerUtils;
123879
124041
  exports.Member = Member;
123880
124042
  exports.MemberApis = MemberApis;
124043
+ exports.MicrosoftPage = MicrosoftPage;
123881
124044
  exports.NEETO_AUTH_BASE_URL = NEETO_AUTH_BASE_URL;
123882
124045
  exports.NEETO_EDITOR_SELECTORS = NEETO_EDITOR_SELECTORS;
123883
124046
  exports.NEETO_FILTERS_SELECTORS = NEETO_FILTERS_SELECTORS;