@bigbinary/neeto-playwright-commons 1.8.9 → 1.8.11

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
@@ -141,6 +141,54 @@ declare class HelpAndProfilePage {
141
141
  verifyLogoutV2: () => Promise<void>;
142
142
  }
143
143
 
144
+ type Integration = "dailyco" | "github" | "google-calendar" | "google-analytics" | "google-sheets" | "microsoft-teams" | "neeto-chat" | "neeto-crm" | "slack" | "twilio" | "whereby" | "zapier" | "zoom";
145
+ type IntegrationStatus = "connected" | "disconnected";
146
+ interface IntegrationBaseParams {
147
+ page: Page;
148
+ neetoPlaywrightUtilities: CustomCommands;
149
+ integration: Integration;
150
+ integrationRouteIndex?: string;
151
+ connectedHeader?: string;
152
+ connectHeader?: string;
153
+ }
154
+ declare class IntegrationBase {
155
+ readonly page: Page;
156
+ readonly neetoPlaywrightUtilities: CustomCommands;
157
+ readonly t: TFunction;
158
+ readonly integration: Integration;
159
+ readonly integrationCard: Locator;
160
+ readonly connectHeader: string;
161
+ readonly connectedHeader: string;
162
+ integrationRouteIndex: string;
163
+ constructor({ page, neetoPlaywrightUtilities, integration, integrationRouteIndex, connectHeader, connectedHeader, }: IntegrationBaseParams);
164
+ disconnect: (interceptMultipleResponsesParams?: Partial<InterceptMultipleResponsesParams>) => Promise<void>;
165
+ connect: (skipGoTo?: boolean) => Promise<void>;
166
+ verifyIntegrationStatus: (status?: IntegrationStatus) => Promise<void>;
167
+ clickOnIntegrationCard: () => Promise<void>;
168
+ private gotoIntegrationIndex;
169
+ }
170
+
171
+ type AsyncNoArgsFunction = () => Promise<void>;
172
+ type RedirectUrl = string | RegExp | ((url: URL) => boolean);
173
+ type SlackPageParams = {
174
+ page: Page;
175
+ neetoPlaywrightUtilities: CustomCommands;
176
+ integrationRouteIndex?: string;
177
+ };
178
+ declare class SlackPage extends IntegrationBase {
179
+ slackWebappPage: Page;
180
+ constructor({ page, neetoPlaywrightUtilities, integrationRouteIndex, }: SlackPageParams);
181
+ connectAndVerifyIntegration: (redirectUrl: RedirectUrl, customSteps?: AsyncNoArgsFunction) => Promise<void>;
182
+ disconnectAndVerifyIntegration: () => Promise<void>;
183
+ updateConfigureSlackChannel: ({ newSlackChannel, interceptMultipleResponsesParams, }: {
184
+ newSlackChannel: string;
185
+ interceptMultipleResponsesParams?: Partial<InterceptMultipleResponsesParams> | undefined;
186
+ }) => Promise<void>;
187
+ loginToSlackWebapp: (slackWebappPage: Page) => Promise<void>;
188
+ logoutFromSlackWebApp: () => Promise<void>;
189
+ goToSlackChannel: (slackChannel: string) => Promise<void>;
190
+ }
191
+
144
192
  interface WebhooksPageParams {
145
193
  page: Page;
146
194
  request: APIRequestContext;
@@ -211,6 +259,7 @@ declare const CREDENTIALS: {
211
259
  password: string;
212
260
  };
213
261
  declare const OTP_EMAIL_PATTERN = "is your login code";
262
+ declare const SLACK_DEFAULT_CHANNEL = "general";
214
263
 
215
264
  declare const USER_AGENTS: {
216
265
  windows: string;
@@ -251,6 +300,9 @@ declare const THIRD_PARTY_ROUTES: {
251
300
  webhooks: {
252
301
  site: string;
253
302
  };
303
+ slack: {
304
+ loginWithPassword: (workspace: string) => string;
305
+ };
254
306
  };
255
307
 
256
308
  declare const COMMON_SELECTORS: {
@@ -298,6 +350,7 @@ declare const COMMON_SELECTORS: {
298
350
  modalHeader: string;
299
351
  nameInputError: string;
300
352
  selectContainer: string;
353
+ selectValueContainer: string;
301
354
  dropdownMenu: string;
302
355
  sidebarToggle: string;
303
356
  subheader: string;
@@ -573,4 +626,4 @@ interface Overrides {
573
626
  }
574
627
  declare const definePlaywrightConfig: (overrides: Overrides) => _playwright_test.PlaywrightTestConfig<{}, {}>;
575
628
 
576
- export { API_ROUTES, BASE_URL, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, type CustomFixture, ENVIRONMENT, GLOBAL_TRANSLATIONS_PATTERN, HELP_CENTER_SELECTORS, HelpAndProfilePage, IS_STAGING_ENV, KEYBOARD_SHORTCUTS_SELECTORS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MERGE_TAGS_SELECTORS, MailosaurUtils, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PROFILE_SECTION_SELECTORS, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SIGNUP_SELECTORS, STORAGE_STATE, TAGS_SELECTORS, THIRD_PARTY_ROUTES, USER_AGENTS, WebhooksPage, clearCredentials, commands, definePlaywrightConfig, extractSubdomainFromError, generateStagingData, getGlobalUserState, hyphenize, i18nFixture, initializeCredentials, joinHyphenCase, joinString, login, loginWithoutSSO, memberUtils, readFileSyncIfExists, removeCredentialFile, shouldSkipSetupAndTeardown, skipTest, updateCredentials, writeDataToFile };
629
+ export { API_ROUTES, BASE_URL, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, type CustomFixture, ENVIRONMENT, GLOBAL_TRANSLATIONS_PATTERN, HELP_CENTER_SELECTORS, HelpAndProfilePage, IS_STAGING_ENV, IntegrationBase, KEYBOARD_SHORTCUTS_SELECTORS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MERGE_TAGS_SELECTORS, MailosaurUtils, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PROFILE_SECTION_SELECTORS, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SIGNUP_SELECTORS, SLACK_DEFAULT_CHANNEL, STORAGE_STATE, SlackPage, TAGS_SELECTORS, THIRD_PARTY_ROUTES, USER_AGENTS, WebhooksPage, clearCredentials, commands, definePlaywrightConfig, extractSubdomainFromError, generateStagingData, getGlobalUserState, hyphenize, i18nFixture, initializeCredentials, joinHyphenCase, joinString, login, loginWithoutSSO, memberUtils, readFileSyncIfExists, removeCredentialFile, shouldSkipSetupAndTeardown, skipTest, updateCredentials, writeDataToFile };
package/index.js CHANGED
@@ -11,6 +11,7 @@ import require$$0$2 from 'util';
11
11
  import require$$0$3 from 'stream';
12
12
  import require$$0$4 from 'events';
13
13
  import { getI18nInstance, initI18n } from 'playwright-i18next-fixture';
14
+ import { humanize, isNotEmpty } from '@bigbinary/neeto-cist';
14
15
  import require$$3 from 'crypto';
15
16
 
16
17
  const ENVIRONMENT = {
@@ -28,6 +29,7 @@ const CREDENTIALS = {
28
29
  password: "welcome",
29
30
  };
30
31
  const OTP_EMAIL_PATTERN = "is your login code";
32
+ const SLACK_DEFAULT_CHANNEL = "general";
31
33
 
32
34
  /* eslint-disable playwright/no-skipped-test */
33
35
  const joinString = (string1, string2, string3 = "", separator = " ") => {
@@ -137,6 +139,7 @@ const COMMON_SELECTORS = {
137
139
  modalHeader: "modal-header",
138
140
  nameInputError: "name-input-error",
139
141
  selectContainer: "nui-select-container",
142
+ selectValueContainer: "nui-select-value-container",
140
143
  dropdownMenu: "nui-select-menu",
141
144
  sidebarToggle: "neeto-molecules-sidebar-toggler",
142
145
  subheader: "subheader",
@@ -145,7 +148,7 @@ const COMMON_SELECTORS = {
145
148
  appSwitcherButton: "app-switcher-button",
146
149
  appSwitcherWrapper: "switcher-wrapper",
147
150
  tableSpinner: ".ant-spin",
148
- pageLoader: "neeto-molecules-page-loader",
151
+ pageLoader: "neeto-molecules-pageloader",
149
152
  homeButton: "home-button",
150
153
  neetoUiSwitch: "nui-switch",
151
154
  floatingActionMenuButton: "floating-action-menu-container",
@@ -7178,6 +7181,9 @@ const API_ROUTES = {
7178
7181
  };
7179
7182
  const THIRD_PARTY_ROUTES = {
7180
7183
  webhooks: { site: "https://webhook.site/" },
7184
+ slack: {
7185
+ loginWithPassword: (workspace) => `https://${workspace}.slack.com/sign_in_with_password`,
7186
+ },
7181
7187
  };
7182
7188
 
7183
7189
  const CHAT_WIDGET_TEXTS = {
@@ -7187,6 +7193,14 @@ const CHAT_WIDGET_TEXTS = {
7187
7193
  const MEMBER_TEXTS = {
7188
7194
  agent: "Agent",
7189
7195
  };
7196
+ const INTEGRATIONS_TEXTS = {
7197
+ connectHeader: (integration) => `Connect your ${humanize(integration)} account`,
7198
+ connectedHeader: (integration) => `You are connected to ${humanize(integration)}`,
7199
+ };
7200
+ const SLACK_WEB_TEXTS = {
7201
+ signOut: "Sign out",
7202
+ allow: "Allow",
7203
+ };
7190
7204
 
7191
7205
  const HELP_CENTER_SELECTORS = {
7192
7206
  helpButton: "help-button",
@@ -7623,6 +7637,199 @@ class HelpAndProfilePage {
7623
7637
  }
7624
7638
  }
7625
7639
 
7640
+ const INTEGRATION_SELECTORS = {
7641
+ integrationCard: (integration) => `${integration}-integration-card`,
7642
+ connectButton: "connect-button",
7643
+ integrationStatusTag: "integration-status-tag",
7644
+ disconnectButton: "disconnect-button",
7645
+ manageButton: "manage-button",
7646
+ };
7647
+
7648
+ class IntegrationBase {
7649
+ constructor({ page, neetoPlaywrightUtilities, integration, integrationRouteIndex, connectHeader, connectedHeader, }) {
7650
+ this.disconnect = async (interceptMultipleResponsesParams = {}) => {
7651
+ await this.gotoIntegrationIndex();
7652
+ await this.clickOnIntegrationCard();
7653
+ await this.page.getByTestId(INTEGRATION_SELECTORS.disconnectButton).click();
7654
+ const disconnectPromise = this.neetoPlaywrightUtilities.interceptMultipleResponses({
7655
+ times: 0,
7656
+ ...interceptMultipleResponsesParams,
7657
+ });
7658
+ await this.page
7659
+ .getByTestId(COMMON_SELECTORS.alertModalSubmitButton)
7660
+ .click();
7661
+ await disconnectPromise;
7662
+ };
7663
+ this.connect = async (skipGoTo) => {
7664
+ !skipGoTo && (await this.gotoIntegrationIndex());
7665
+ await this.clickOnIntegrationCard();
7666
+ await expect(this.page.getByRole("heading", {
7667
+ name: this.connectHeader,
7668
+ })).toBeVisible();
7669
+ await this.page.getByTestId(INTEGRATION_SELECTORS.connectButton).click();
7670
+ };
7671
+ this.verifyIntegrationStatus = async (status = "connected") => {
7672
+ await this.gotoIntegrationIndex();
7673
+ if (status === "connected") {
7674
+ await expect(this.integrationCard.getByTestId(INTEGRATION_SELECTORS.integrationStatusTag)).toBeVisible({ timeout: 10000 });
7675
+ }
7676
+ await this.clickOnIntegrationCard();
7677
+ const header = status === "connected" ? this.connectedHeader : this.connectHeader;
7678
+ await expect(this.page.getByRole("heading", { name: header })).toBeVisible();
7679
+ };
7680
+ this.clickOnIntegrationCard = async () => {
7681
+ await expect(this.page.getByTestId(COMMON_SELECTORS.spinner)).toHaveCount(0);
7682
+ await this.integrationCard.scrollIntoViewIfNeeded();
7683
+ await this.integrationCard.click();
7684
+ await expect(this.page.getByTestId(COMMON_SELECTORS.pageLoader)).toBeHidden();
7685
+ };
7686
+ this.gotoIntegrationIndex = async () => {
7687
+ isNotEmpty(this.integrationRouteIndex) &&
7688
+ (await this.page.goto(this.integrationRouteIndex));
7689
+ };
7690
+ this.page = page;
7691
+ this.neetoPlaywrightUtilities = neetoPlaywrightUtilities;
7692
+ this.t = getI18nInstance().t;
7693
+ this.integration = integration;
7694
+ this.integrationCard = this.page.getByTestId(INTEGRATION_SELECTORS.integrationCard(integration));
7695
+ this.integrationRouteIndex = integrationRouteIndex || "";
7696
+ this.connectHeader =
7697
+ connectHeader || INTEGRATIONS_TEXTS.connectHeader(this.integration);
7698
+ this.connectedHeader =
7699
+ connectedHeader || INTEGRATIONS_TEXTS.connectedHeader(this.integration);
7700
+ }
7701
+ }
7702
+
7703
+ const SLACK_SELECTORS = {
7704
+ messageContainer: "[data-qa='message_container']",
7705
+ loginEmail: "[data-qa='login_email']",
7706
+ loginPassword: "[data-qa='login_password']",
7707
+ signInButton: "[data-qa='signin_button']",
7708
+ teamPicketButtonContent: "[data-qa='team-picker-button-content']",
7709
+ redirectOpenInBrowser: "[data-qa='ssb_redirect_open_in_browser']",
7710
+ workspaceActionsButton: "[data-qa='workspace_actions_button']",
7711
+ teamMenuTrigger: "[data-qa='team-menu-trigger']",
7712
+ menuItemButton: "[data-qa='menu_item_button']",
7713
+ threadsFlexpane: "[data-qa='threads_flexpane']",
7714
+ replyBar: "[data-qa='reply_bar']",
7715
+ markdownElement: "[data-qa='bk_markdown_element']",
7716
+ virtualListItem: "[data-qa='virtual-list-item']",
7717
+ };
7718
+
7719
+ /* eslint-disable playwright/no-raw-locators */
7720
+ class SlackPage extends IntegrationBase {
7721
+ constructor({ page, neetoPlaywrightUtilities, integrationRouteIndex, }) {
7722
+ super({
7723
+ page,
7724
+ neetoPlaywrightUtilities,
7725
+ integration: "slack",
7726
+ integrationRouteIndex,
7727
+ });
7728
+ this.connectAndVerifyIntegration = async (redirectUrl, customSteps) => {
7729
+ await this.connect();
7730
+ await this.page
7731
+ .getByRole("button", {
7732
+ name: this.t("neetoSlack.slack.connect.loginButton"),
7733
+ })
7734
+ .click({ delay: 5000 });
7735
+ await this.page.waitForURL(RegExp("(.*)slack.com/.*"));
7736
+ const allowButton = this.page.getByRole("button", {
7737
+ name: SLACK_WEB_TEXTS.allow,
7738
+ });
7739
+ await expect(allowButton).toBeEnabled({ timeout: 20000 });
7740
+ const currentWorkspace = (await this.page
7741
+ .locator(SLACK_SELECTORS.teamPicketButtonContent)
7742
+ .textContent()) || "";
7743
+ await allowButton.click();
7744
+ await this.page.waitForURL(redirectUrl);
7745
+ await expect(this.page.getByTestId(COMMON_SELECTORS.pageLoader)).toBeHidden({ timeout: 10000 });
7746
+ await expect(this.page.getByRole("heading", {
7747
+ name: this.t("neetoSlack.slack.configure.title", {
7748
+ teamName: currentWorkspace,
7749
+ }),
7750
+ })).toBeVisible();
7751
+ await expect(this.page.getByTestId(COMMON_SELECTORS.selectValueContainer)).toContainText(SLACK_DEFAULT_CHANNEL);
7752
+ await this.page
7753
+ .getByRole("button", { name: this.t("neetoSlack.common.continue") })
7754
+ .click();
7755
+ if (customSteps) {
7756
+ await customSteps();
7757
+ }
7758
+ else {
7759
+ await expect(this.page.getByRole("heading", {
7760
+ name: this.t("neetoSlack.slack.finish.title", {
7761
+ teamName: currentWorkspace,
7762
+ }),
7763
+ })).toBeVisible();
7764
+ await this.page
7765
+ .getByRole("button", { name: this.t("neetoSlack.common.done") })
7766
+ .click();
7767
+ }
7768
+ await this.verifyIntegrationStatus();
7769
+ };
7770
+ this.disconnectAndVerifyIntegration = async () => {
7771
+ await this.disconnect();
7772
+ await this.verifyIntegrationStatus("disconnected");
7773
+ };
7774
+ this.updateConfigureSlackChannel = async ({ newSlackChannel = "random", interceptMultipleResponsesParams = {}, }) => {
7775
+ await this.page.getByTestId(INTEGRATION_SELECTORS.manageButton).click();
7776
+ await this.page
7777
+ .getByRole("button", { name: this.t("neetoSlack.common.edit") })
7778
+ .click();
7779
+ await this.page.getByTestId(COMMON_SELECTORS.selectContainer).click();
7780
+ await this.page
7781
+ .getByTestId(COMMON_SELECTORS.dropdownMenu)
7782
+ .getByText(newSlackChannel)
7783
+ .click();
7784
+ const savePromise = this.neetoPlaywrightUtilities.interceptMultipleResponses({
7785
+ times: 0,
7786
+ ...interceptMultipleResponsesParams,
7787
+ });
7788
+ await this.page
7789
+ .getByRole("button", { name: this.t("neetoSlack.common.save") })
7790
+ .click();
7791
+ await savePromise;
7792
+ };
7793
+ this.loginToSlackWebapp = async (slackWebappPage) => {
7794
+ this.slackWebappPage = slackWebappPage;
7795
+ if (isNotNil(process.env.SLACK_WORKSPACE) &&
7796
+ isNotNil(process.env.SLACK_LOGIN_PASSWORD) &&
7797
+ isNotNil(process.env.SLACK_LOGIN_EMAIL)) {
7798
+ await slackWebappPage.goto(THIRD_PARTY_ROUTES.slack.loginWithPassword(process.env.SLACK_WORKSPACE));
7799
+ await slackWebappPage
7800
+ .locator(SLACK_SELECTORS.loginEmail)
7801
+ .pressSequentially(process.env.SLACK_LOGIN_EMAIL, { delay: 10 });
7802
+ await slackWebappPage
7803
+ .locator(SLACK_SELECTORS.loginPassword)
7804
+ .pressSequentially(process.env.SLACK_LOGIN_PASSWORD, { delay: 10 });
7805
+ await slackWebappPage.locator(SLACK_SELECTORS.signInButton).click();
7806
+ await slackWebappPage
7807
+ .locator(SLACK_SELECTORS.redirectOpenInBrowser)
7808
+ .click();
7809
+ }
7810
+ else {
7811
+ throw new Error("ENV variable SLACK_LOGIN_EMAIL or SLACK_LOGIN_PASSWORD or SLACK_WORKSPACE is not defined. Please add the API key to use this fixture.");
7812
+ }
7813
+ };
7814
+ this.logoutFromSlackWebApp = async () => {
7815
+ await this.slackWebappPage
7816
+ .locator(SLACK_SELECTORS.workspaceActionsButton)
7817
+ .or(this.slackWebappPage.locator(SLACK_SELECTORS.teamMenuTrigger))
7818
+ .click();
7819
+ await this.slackWebappPage
7820
+ .locator(SLACK_SELECTORS.menuItemButton, {
7821
+ hasText: SLACK_WEB_TEXTS.signOut,
7822
+ })
7823
+ .click();
7824
+ };
7825
+ this.goToSlackChannel = async (slackChannel) => {
7826
+ await this.slackWebappPage
7827
+ .locator(SLACK_SELECTORS.virtualListItem, { hasText: slackChannel })
7828
+ .click();
7829
+ };
7830
+ }
7831
+ }
7832
+
7626
7833
  const WEBHOOK_SELECTORS = {
7627
7834
  addNewWebhook: "add-new-webhook-button",
7628
7835
  endpointInputField: "endpoint-input-field",
@@ -8608,5 +8815,5 @@ const definePlaywrightConfig = (overrides) => {
8608
8815
  });
8609
8816
  };
8610
8817
 
8611
- export { API_ROUTES, BASE_URL, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, ENVIRONMENT, GLOBAL_TRANSLATIONS_PATTERN, HELP_CENTER_SELECTORS, HelpAndProfilePage, IS_STAGING_ENV, KEYBOARD_SHORTCUTS_SELECTORS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MERGE_TAGS_SELECTORS, MailosaurUtils, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PROFILE_SECTION_SELECTORS, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SIGNUP_SELECTORS, STORAGE_STATE, TAGS_SELECTORS, THIRD_PARTY_ROUTES, USER_AGENTS, WebhooksPage, clearCredentials, commands, definePlaywrightConfig, extractSubdomainFromError, generateStagingData, getGlobalUserState, hyphenize, i18nFixture, initializeCredentials, joinHyphenCase, joinString, login, loginWithoutSSO, memberUtils, readFileSyncIfExists, removeCredentialFile, shouldSkipSetupAndTeardown, skipTest, updateCredentials, writeDataToFile };
8818
+ export { API_ROUTES, BASE_URL, CHANGELOG_WIDGET_SELECTORS, CHAT_WIDGET_SELECTORS, COMMON_SELECTORS, CREDENTIALS, CustomCommands, ENVIRONMENT, GLOBAL_TRANSLATIONS_PATTERN, HELP_CENTER_SELECTORS, HelpAndProfilePage, IS_STAGING_ENV, IntegrationBase, KEYBOARD_SHORTCUTS_SELECTORS, LOGIN_SELECTORS, MEMBER_FORM_SELECTORS, MEMBER_SELECTORS, MERGE_TAGS_SELECTORS, MailosaurUtils, NEETO_AUTH_BASE_URL, NEETO_EDITOR_SELECTORS, NEETO_FILTERS_SELECTORS, OTP_EMAIL_PATTERN, OrganizationPage, PROFILE_SECTION_SELECTORS, PROJECT_TRANSLATIONS_PATH, ROLES_SELECTORS, ROUTES, SIGNUP_SELECTORS, SLACK_DEFAULT_CHANNEL, STORAGE_STATE, SlackPage, TAGS_SELECTORS, THIRD_PARTY_ROUTES, USER_AGENTS, WebhooksPage, clearCredentials, commands, definePlaywrightConfig, extractSubdomainFromError, generateStagingData, getGlobalUserState, hyphenize, i18nFixture, initializeCredentials, joinHyphenCase, joinString, login, loginWithoutSSO, memberUtils, readFileSyncIfExists, removeCredentialFile, shouldSkipSetupAndTeardown, skipTest, updateCredentials, writeDataToFile };
8612
8819
  //# sourceMappingURL=index.js.map