@bigbinary/neeto-playwright-commons 1.23.9 → 1.24.1
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 +294 -121
- package/index.cjs.js.map +1 -1
- package/index.d.ts +248 -162
- package/index.js +291 -123
- package/index.js.map +1 -1
- package/package.json +1 -1
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);
|
|
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);
|
|
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
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
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
|
|
5466
|
-
await test.expect(
|
|
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
|
|
5471
|
-
|
|
5472
|
-
.
|
|
5473
|
-
|
|
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 (
|
|
116046
|
-
|
|
116047
|
-
|
|
116048
|
-
|
|
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;
|
|
@@ -116148,14 +116153,24 @@ class GooglePage extends IntegrationBase {
|
|
|
116148
116153
|
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116149
116154
|
await this.page.waitForURL(new RegExp(THIRD_PARTY_ROUTES.google.myAccount));
|
|
116150
116155
|
};
|
|
116151
|
-
this.enterTotpCode =
|
|
116152
|
-
|
|
116153
|
-
await
|
|
116154
|
-
|
|
116155
|
-
|
|
116156
|
-
|
|
116157
|
-
|
|
116158
|
-
|
|
116156
|
+
this.enterTotpCode = async (locator) => {
|
|
116157
|
+
let previousToken = null;
|
|
116158
|
+
await test.expect(async () => {
|
|
116159
|
+
let totpToken = this.totp.generate({ timestamp: Date.now() });
|
|
116160
|
+
if (totpToken === previousToken) {
|
|
116161
|
+
const remainingTime = this.totp.remaining({ timestamp: Date.now() });
|
|
116162
|
+
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
116163
|
+
await this.page.waitForTimeout(remainingTime + 500); // Wait for the remaining time plus a small buffer (500ms) to ensure new token
|
|
116164
|
+
totpToken = this.totp.generate({ timestamp: Date.now() });
|
|
116165
|
+
}
|
|
116166
|
+
previousToken = totpToken;
|
|
116167
|
+
await this.page.getByLabel(GOOGLE_LOGIN_TEXTS.enterCode).fill(totpToken);
|
|
116168
|
+
test.expect(this.totp.validate({ token: totpToken })).not.toBeNull();
|
|
116169
|
+
await this.page.locator(GOOGLE_LOGIN_SELECTORS.totpNext).click();
|
|
116170
|
+
await test.expect(this.page.getByText(GOOGLE_LOGIN_TEXTS.wrongCode)).toBeHidden({ timeout: 10000 });
|
|
116171
|
+
await test.expect(locator).toBeHidden({ timeout: 10000 });
|
|
116172
|
+
}).toPass({ timeout: 2 * 60 * 1000 });
|
|
116173
|
+
};
|
|
116159
116174
|
this.logoutFromGoogle = async () => {
|
|
116160
116175
|
await this.page.goto(THIRD_PARTY_ROUTES.google.myAccount, {
|
|
116161
116176
|
timeout: 20000,
|
|
@@ -116229,7 +116244,113 @@ class GooglePage extends IntegrationBase {
|
|
|
116229
116244
|
}
|
|
116230
116245
|
}
|
|
116231
116246
|
|
|
116232
|
-
|
|
116247
|
+
class MicrosoftPage extends IntegrationBase {
|
|
116248
|
+
constructor({ page, neetoPlaywrightUtilities, integrationRouteIndex, integration = "", }) {
|
|
116249
|
+
super({
|
|
116250
|
+
page,
|
|
116251
|
+
neetoPlaywrightUtilities,
|
|
116252
|
+
integrationRouteIndex,
|
|
116253
|
+
integration,
|
|
116254
|
+
});
|
|
116255
|
+
this.stagingConsentFlow = async (abortFlow = false) => {
|
|
116256
|
+
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116257
|
+
await test.expect(this.page.getByRole("heading", {
|
|
116258
|
+
name: MICROSOFT_LOGIN_TEXTS.permissionsRequested,
|
|
116259
|
+
})).toBeVisible({ timeout: 20000 });
|
|
116260
|
+
await this.page
|
|
116261
|
+
.locator(abortFlow
|
|
116262
|
+
? MICROSOFT_LOGIN_SELECTORS.cancelButton
|
|
116263
|
+
: MICROSOFT_LOGIN_SELECTORS.acceptButton)
|
|
116264
|
+
.click();
|
|
116265
|
+
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116266
|
+
await this.neetoPlaywrightUtilities.waitForFloatingMenu();
|
|
116267
|
+
};
|
|
116268
|
+
this.enterEmail = async () => {
|
|
116269
|
+
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116270
|
+
await test.expect(this.page.getByRole("heading", { name: MICROSOFT_LOGIN_TEXTS.signIn })).toBeVisible({ timeout: 20000 });
|
|
116271
|
+
await this.page
|
|
116272
|
+
.locator(MICROSOFT_LOGIN_SELECTORS.emailInput)
|
|
116273
|
+
.or(this.page.locator(MICROSOFT_LOGIN_SELECTORS.placeholder))
|
|
116274
|
+
.or(this.page.getByRole("textbox", {
|
|
116275
|
+
name: MICROSOFT_LOGIN_TEXTS.emailInput,
|
|
116276
|
+
}))
|
|
116277
|
+
.pressSequentially(process.env.MICROSOFT_LOGIN_EMAIL, { delay: 25 });
|
|
116278
|
+
};
|
|
116279
|
+
this.enterPassword = async () => {
|
|
116280
|
+
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116281
|
+
await test.expect(this.page.getByRole("heading", {
|
|
116282
|
+
name: MICROSOFT_LOGIN_TEXTS.enterPassword,
|
|
116283
|
+
})).toBeVisible({ timeout: 10000 });
|
|
116284
|
+
await this.page
|
|
116285
|
+
.getByPlaceholder(MICROSOFT_LOGIN_TEXTS.password)
|
|
116286
|
+
.or(this.page.locator(MICROSOFT_LOGIN_SELECTORS.placeholder))
|
|
116287
|
+
.or(this.page.getByRole("textbox", {
|
|
116288
|
+
name: MICROSOFT_LOGIN_TEXTS.passwordInput,
|
|
116289
|
+
}))
|
|
116290
|
+
.pressSequentially(process.env.MICROSOFT_LOGIN_PASSWORD, { delay: 15 });
|
|
116291
|
+
};
|
|
116292
|
+
this.loginToMicrosoft = async () => {
|
|
116293
|
+
if (ramda.isNil(process.env.MICROSOFT_LOGIN_EMAIL) ||
|
|
116294
|
+
ramda.isNil(process.env.MICROSOFT_LOGIN_PASSWORD) ||
|
|
116295
|
+
ramda.isNil(process.env.MICROSOFT_2FA_SECRET_KEY)) {
|
|
116296
|
+
throw new Error("ENV variable MICROSOFT_LOGIN_EMAIL or MICROSOFT_LOGIN_PASSWORD or MICROSOFT_2FA_SECRET_KEY is not properly configured");
|
|
116297
|
+
}
|
|
116298
|
+
await this.page.goto(THIRD_PARTY_ROUTES.microsoft.login);
|
|
116299
|
+
await this.enterEmail();
|
|
116300
|
+
await this.page
|
|
116301
|
+
.getByRole("button", { name: MICROSOFT_LOGIN_TEXTS.next })
|
|
116302
|
+
.click();
|
|
116303
|
+
await this.enterPassword();
|
|
116304
|
+
await this.page
|
|
116305
|
+
.getByRole("button", { name: MICROSOFT_LOGIN_TEXTS.signIn })
|
|
116306
|
+
.click();
|
|
116307
|
+
await this.enterTotpCode();
|
|
116308
|
+
await this.staySignedIn();
|
|
116309
|
+
};
|
|
116310
|
+
this.enterTotpCode = async () => {
|
|
116311
|
+
const verifyBtn = this.page.getByRole("button", {
|
|
116312
|
+
name: MICROSOFT_LOGIN_TEXTS.verify,
|
|
116313
|
+
});
|
|
116314
|
+
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116315
|
+
await test.expect(async () => {
|
|
116316
|
+
const token = this.totp.generate({ timestamp: Date.now() + 5000 });
|
|
116317
|
+
await this.page.getByLabel(MICROSOFT_LOGIN_TEXTS.enterCode).fill(token);
|
|
116318
|
+
test.expect(this.totp.validate({ token })).not.toBeNull();
|
|
116319
|
+
await verifyBtn.click();
|
|
116320
|
+
await test.expect(this.page.getByRole("alert")).toBeHidden();
|
|
116321
|
+
await test.expect(verifyBtn).toBeHidden();
|
|
116322
|
+
}).toPass({ timeout: 60 * 1000, intervals: [10000] });
|
|
116323
|
+
};
|
|
116324
|
+
this.staySignedIn = async () => {
|
|
116325
|
+
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116326
|
+
await this.page.waitForURL(THIRD_PARTY_ROUTES.microsoft.staySignedIn);
|
|
116327
|
+
await test.expect(this.page.getByRole("heading", {
|
|
116328
|
+
name: MICROSOFT_LOGIN_TEXTS.staySignedIn,
|
|
116329
|
+
})).toBeVisible({ timeout: 15000 });
|
|
116330
|
+
const acceptBtn = this.page.locator(MICROSOFT_LOGIN_SELECTORS.acceptButton);
|
|
116331
|
+
await acceptBtn.click();
|
|
116332
|
+
await test.expect(acceptBtn).toBeHidden({ timeout: 10000 });
|
|
116333
|
+
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116334
|
+
};
|
|
116335
|
+
this.revokePermissions = async () => {
|
|
116336
|
+
await this.page.goto(THIRD_PARTY_ROUTES.microsoft.myApps);
|
|
116337
|
+
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116338
|
+
const dropdown = this.page.locator(MICROSOFT_LOGIN_SELECTORS.dropdownMenu);
|
|
116339
|
+
await dropdown.click();
|
|
116340
|
+
await this.page
|
|
116341
|
+
.getByRole("menuitem", { name: MICROSOFT_LOGIN_TEXTS.remove })
|
|
116342
|
+
.click();
|
|
116343
|
+
await test.expect(dropdown).toBeHidden({ timeout: 10000 });
|
|
116344
|
+
await this.page.waitForLoadState("load", { timeout: 25000 });
|
|
116345
|
+
};
|
|
116346
|
+
this.mailerUtils = new MailerUtils(neetoPlaywrightUtilities);
|
|
116347
|
+
this.totp = initializeTotp({
|
|
116348
|
+
issuer: "Microsoft",
|
|
116349
|
+
secret: process.env.MICROSOFT_2FA_SECRET_KEY,
|
|
116350
|
+
});
|
|
116351
|
+
}
|
|
116352
|
+
}
|
|
116353
|
+
|
|
116233
116354
|
class SlackPage extends IntegrationBase {
|
|
116234
116355
|
constructor({ page, neetoPlaywrightUtilities, integrationRouteIndex, }) {
|
|
116235
116356
|
super({
|
|
@@ -116278,6 +116399,7 @@ class SlackPage extends IntegrationBase {
|
|
|
116278
116399
|
await this.page
|
|
116279
116400
|
.getByRole("button", { name: this.t("neetoSlack.common.continue") })
|
|
116280
116401
|
.click();
|
|
116402
|
+
await this.neetoPlaywrightUtilities.waitForPageLoad();
|
|
116281
116403
|
if (customSteps) {
|
|
116282
116404
|
await customSteps();
|
|
116283
116405
|
}
|
|
@@ -116297,11 +116419,7 @@ class SlackPage extends IntegrationBase {
|
|
|
116297
116419
|
await this.disconnect();
|
|
116298
116420
|
await this.verifyIntegrationStatus("disconnected");
|
|
116299
116421
|
};
|
|
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, }) => {
|
|
116422
|
+
this.updateConfigureSlackChannel = async ({ newSlackChannel = "random", refreshChannelList = false, }) => {
|
|
116305
116423
|
await this.page.getByTestId(INTEGRATION_SELECTORS.manageButton).click();
|
|
116306
116424
|
await this.page
|
|
116307
116425
|
.getByRole("button", { name: this.t("neetoSlack.common.edit") })
|
|
@@ -116367,17 +116485,16 @@ class SlackPage extends IntegrationBase {
|
|
|
116367
116485
|
})
|
|
116368
116486
|
.click();
|
|
116369
116487
|
};
|
|
116370
|
-
this.goToSlackChannel =
|
|
116371
|
-
|
|
116372
|
-
|
|
116373
|
-
.click();
|
|
116374
|
-
};
|
|
116488
|
+
this.goToSlackChannel = (slackChannel) => this.slackWebappPage
|
|
116489
|
+
.locator(SLACK_SELECTORS.virtualListItem, { hasText: slackChannel })
|
|
116490
|
+
.click();
|
|
116375
116491
|
this.createNewSlackChannel = async ({ channelName, kind = "public", }) => {
|
|
116376
116492
|
await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.sectionHeadingButton).click();
|
|
116377
116493
|
await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.channelSectionSubmenuCreate).click();
|
|
116378
116494
|
await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.channelSectionMenuCreateChannel).click();
|
|
116495
|
+
const spinner = this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.infiniteSpinner);
|
|
116379
116496
|
await test.expect(this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.skModalContent)).toBeVisible();
|
|
116380
|
-
await test.expect(
|
|
116497
|
+
await test.expect(spinner).toBeHidden();
|
|
116381
116498
|
await test.expect(this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.channelNameOptionsList)).toBeHidden({ timeout: 5000 });
|
|
116382
116499
|
await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.skModalContent)
|
|
116383
116500
|
.getByText(SLACK_WEB_TEXTS.name, { exact: true })
|
|
@@ -116386,13 +116503,14 @@ class SlackPage extends IntegrationBase {
|
|
|
116386
116503
|
SLACK_DATA_QA_SELECTORS.skModalContent,
|
|
116387
116504
|
SLACK_DATA_QA_SELECTORS.channelNameInput,
|
|
116388
116505
|
]).pressSequentially(channelName);
|
|
116389
|
-
|
|
116390
|
-
await test.expect(
|
|
116391
|
-
await
|
|
116506
|
+
const nextButton = this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.createChannelNextButton);
|
|
116507
|
+
await test.expect(spinner).toBeHidden();
|
|
116508
|
+
await test.expect(nextButton).toBeEnabled();
|
|
116509
|
+
await nextButton.click();
|
|
116392
116510
|
await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.skModalContent)
|
|
116393
116511
|
.getByRole("radio", { name: kind })
|
|
116394
116512
|
.check();
|
|
116395
|
-
await
|
|
116513
|
+
await nextButton.click();
|
|
116396
116514
|
await this.slackWebappPageDataQa(SLACK_DATA_QA_SELECTORS.inviteToWorkspaceSkipButton).click();
|
|
116397
116515
|
};
|
|
116398
116516
|
this.deleteSlackChannel = async (channel) => {
|
|
@@ -117526,9 +117644,7 @@ class TeamMembers {
|
|
|
117526
117644
|
}).toPass({ timeout: 40000 });
|
|
117527
117645
|
await this.neetoPlaywrightUtilities.verifyToast();
|
|
117528
117646
|
};
|
|
117529
|
-
this.searchAndVerifyMemberByEmail = async ({ email
|
|
117530
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
117531
|
-
interceptOptions = {}, }) => {
|
|
117647
|
+
this.searchAndVerifyMemberByEmail = async ({ email }) => {
|
|
117532
117648
|
await this.neetoPlaywrightUtilities.waitForPageLoad();
|
|
117533
117649
|
await this.page.getByTestId(MEMBER_SELECTORS.searchTextField).fill(email);
|
|
117534
117650
|
const emailSubstr = email.length > 20 ? email.substring(0, 20) : email;
|
|
@@ -118163,6 +118279,69 @@ class CustomDomainPage {
|
|
|
118163
118279
|
}
|
|
118164
118280
|
}
|
|
118165
118281
|
|
|
118282
|
+
class IPRestrictionsPage {
|
|
118283
|
+
constructor(page, neetoPlaywrightUtilities) {
|
|
118284
|
+
this.page = page;
|
|
118285
|
+
this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
|
|
118286
|
+
this.setIPRange = async (ipRange, type, index = 0) => {
|
|
118287
|
+
await this.page
|
|
118288
|
+
.getByTestId(IP_RESTRICTIONS_SELECTORS.ipStartTextField)
|
|
118289
|
+
// Using nth methods here as it determines which input to interact with
|
|
118290
|
+
// eslint-disable-next-line playwright/no-nth-methods
|
|
118291
|
+
.nth(index)
|
|
118292
|
+
.fill(ipRange[0]);
|
|
118293
|
+
await this.page
|
|
118294
|
+
.getByTestId(IP_RESTRICTIONS_SELECTORS.ipEndTextField)
|
|
118295
|
+
// Using nth methods here as it determines which input to interact with
|
|
118296
|
+
// eslint-disable-next-line playwright/no-nth-methods
|
|
118297
|
+
.nth(index)
|
|
118298
|
+
.fill(ipRange[1]);
|
|
118299
|
+
if (!neetoCist.isPresent(type))
|
|
118300
|
+
return;
|
|
118301
|
+
await this.page
|
|
118302
|
+
.getByTestId(COMMON_SELECTORS.customSelectContainer("type"))
|
|
118303
|
+
// Using nth methods here as it determines which dropdown to interact with
|
|
118304
|
+
// eslint-disable-next-line playwright/no-nth-methods
|
|
118305
|
+
.nth(index)
|
|
118306
|
+
.fill(type);
|
|
118307
|
+
await this.page.keyboard.press("Enter");
|
|
118308
|
+
await test.expect(this.page
|
|
118309
|
+
.getByTestId(COMMON_SELECTORS.customSelectValueContainer("type"))
|
|
118310
|
+
// Using nth methods here as it determines which dropdown to interact with
|
|
118311
|
+
// eslint-disable-next-line playwright/no-nth-methods
|
|
118312
|
+
.nth(index)).toContainText(type);
|
|
118313
|
+
};
|
|
118314
|
+
this.saveChanges = async () => {
|
|
118315
|
+
await this.saveButton.click();
|
|
118316
|
+
await this.neetoPlaywrightUtilities.clickButtonAndAwaitLoad({
|
|
118317
|
+
locator: this.page.getByTestId(COMMON_SELECTORS.alertModalSubmitButton),
|
|
118318
|
+
});
|
|
118319
|
+
};
|
|
118320
|
+
this.disableIPRestriction = async () => {
|
|
118321
|
+
if (!this.page.url().includes(ROUTES.adminPanel.ipRestriction))
|
|
118322
|
+
return;
|
|
118323
|
+
const enableCheckbox = this.page.getByTestId(IP_RESTRICTIONS_SELECTORS.enableIPRestrictionChk);
|
|
118324
|
+
const [isChecked, isSaveDisabled, isDeleteHidden] = await Promise.all([
|
|
118325
|
+
enableCheckbox.isChecked(),
|
|
118326
|
+
this.saveButton.isDisabled(),
|
|
118327
|
+
this.page
|
|
118328
|
+
.getByTestId(IP_RESTRICTIONS_SELECTORS.ipRangeDeleteBtn)
|
|
118329
|
+
.isHidden(),
|
|
118330
|
+
]);
|
|
118331
|
+
if (isChecked && (isSaveDisabled || isDeleteHidden)) {
|
|
118332
|
+
await enableCheckbox.click();
|
|
118333
|
+
if (await this.saveButton.isEnabled()) {
|
|
118334
|
+
await this.saveButton.click();
|
|
118335
|
+
await this.neetoPlaywrightUtilities.verifyToast();
|
|
118336
|
+
}
|
|
118337
|
+
}
|
|
118338
|
+
};
|
|
118339
|
+
this.t = playwrightI18nextFixture.getI18nInstance().t;
|
|
118340
|
+
this.ipRestrictionsApi = new IpRestrictionsApi(this.neetoPlaywrightUtilities);
|
|
118341
|
+
this.saveButton = this.page.getByTestId(IP_RESTRICTIONS_SELECTORS.saveChanges);
|
|
118342
|
+
}
|
|
118343
|
+
}
|
|
118344
|
+
|
|
118166
118345
|
class RolesPage {
|
|
118167
118346
|
constructor(page, neetoPlaywrightUtilities) {
|
|
118168
118347
|
this.getPermissionIds = async (targetPermissions, isGranularPermission = false) => {
|
|
@@ -118226,11 +118405,6 @@ class RolesPage {
|
|
|
118226
118405
|
this.neetoPlaywrightUtilities.verifyToast(),
|
|
118227
118406
|
]);
|
|
118228
118407
|
};
|
|
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
118408
|
this.deleteRoleViaUI = async (roleName) => {
|
|
118235
118409
|
await this.neetoPlaywrightUtilities.waitForPageLoad();
|
|
118236
118410
|
await this.page.getByTestId(ROLES_SELECTORS.searchTextField).fill(roleName);
|
|
@@ -118259,17 +118433,11 @@ class RolesPage {
|
|
|
118259
118433
|
if (neetoCist.isNotEqualDeep(roleAccessableLinks, adminAccessableLinks)) {
|
|
118260
118434
|
for (const link of adminAccessableLinks) {
|
|
118261
118435
|
await this.page.goto(link);
|
|
118262
|
-
await
|
|
118263
|
-
.soft(this.page.getByTestId(COMMON_SELECTORS.floatingActionMenuButton))
|
|
118264
|
-
.toBeVisible({ timeout: 15000 });
|
|
118436
|
+
await this.neetoPlaywrightUtilities.waitForFloatingMenu();
|
|
118265
118437
|
await this.neetoPlaywrightUtilities.waitForPageLoad();
|
|
118266
|
-
await test.expect(this.page.
|
|
118267
|
-
const unauthorizedHeading = this.page.getByRole("heading", {
|
|
118438
|
+
await test.expect(this.page.getByRole("heading", {
|
|
118268
118439
|
name: this.t("neetoMolecules.errorPage.unauthorized"),
|
|
118269
|
-
});
|
|
118270
|
-
roleAccessableLinks.includes(link)
|
|
118271
|
-
? await test.expect(unauthorizedHeading).toBeHidden()
|
|
118272
|
-
: await test.expect(unauthorizedHeading).toBeVisible();
|
|
118440
|
+
}))[roleAccessableLinks.includes(link) ? "toBeHidden" : "toBeVisible"]();
|
|
118273
118441
|
}
|
|
118274
118442
|
}
|
|
118275
118443
|
};
|
|
@@ -123863,10 +124031,12 @@ exports.HELP_CENTER_SELECTORS = HELP_CENTER_SELECTORS;
|
|
|
123863
124031
|
exports.HelpAndProfilePage = HelpAndProfilePage;
|
|
123864
124032
|
exports.INTEGRATIONS_TEXTS = INTEGRATIONS_TEXTS;
|
|
123865
124033
|
exports.INTEGRATION_SELECTORS = INTEGRATION_SELECTORS;
|
|
124034
|
+
exports.IPRestrictionsPage = IPRestrictionsPage;
|
|
123866
124035
|
exports.IP_RESTRICTIONS_SELECTORS = IP_RESTRICTIONS_SELECTORS;
|
|
123867
124036
|
exports.IS_STAGING_ENV = IS_STAGING_ENV;
|
|
123868
124037
|
exports.ImageUploader = ImageUploader;
|
|
123869
124038
|
exports.IntegrationBase = IntegrationBase;
|
|
124039
|
+
exports.IpRestrictionsApi = IpRestrictionsApi;
|
|
123870
124040
|
exports.KEYBOARD_SHORTCUTS_SELECTORS = KEYBOARD_SHORTCUTS_SELECTORS;
|
|
123871
124041
|
exports.LIST_MODIFIER_SELECTORS = LIST_MODIFIER_SELECTORS;
|
|
123872
124042
|
exports.LIST_MODIFIER_TAGS = LIST_MODIFIER_TAGS;
|
|
@@ -123875,9 +124045,12 @@ exports.MEMBER_FORM_SELECTORS = MEMBER_FORM_SELECTORS;
|
|
|
123875
124045
|
exports.MEMBER_SELECTORS = MEMBER_SELECTORS;
|
|
123876
124046
|
exports.MEMBER_TEXTS = MEMBER_TEXTS;
|
|
123877
124047
|
exports.MERGE_TAGS_SELECTORS = MERGE_TAGS_SELECTORS;
|
|
124048
|
+
exports.MICROSOFT_LOGIN_SELECTORS = MICROSOFT_LOGIN_SELECTORS;
|
|
124049
|
+
exports.MICROSOFT_LOGIN_TEXTS = MICROSOFT_LOGIN_TEXTS;
|
|
123878
124050
|
exports.MailerUtils = MailerUtils;
|
|
123879
124051
|
exports.Member = Member;
|
|
123880
124052
|
exports.MemberApis = MemberApis;
|
|
124053
|
+
exports.MicrosoftPage = MicrosoftPage;
|
|
123881
124054
|
exports.NEETO_AUTH_BASE_URL = NEETO_AUTH_BASE_URL;
|
|
123882
124055
|
exports.NEETO_EDITOR_SELECTORS = NEETO_EDITOR_SELECTORS;
|
|
123883
124056
|
exports.NEETO_FILTERS_SELECTORS = NEETO_FILTERS_SELECTORS;
|