@mattermost/playwright-lib 10.6.0-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.
Files changed (203) hide show
  1. package/README.md +214 -0
  2. package/dist/asset/mattermost-icon_128x128.png +0 -0
  3. package/dist/browser_context.d.ts +17 -0
  4. package/dist/browser_context.js +71 -0
  5. package/dist/browser_context.js.map +1 -0
  6. package/dist/constant.d.ts +3 -0
  7. package/dist/constant.js +8 -0
  8. package/dist/constant.js.map +1 -0
  9. package/dist/file.d.ts +42 -0
  10. package/dist/file.js +74 -0
  11. package/dist/file.js.map +1 -0
  12. package/dist/flag.d.ts +7 -0
  13. package/dist/flag.js +76 -0
  14. package/dist/flag.js.map +1 -0
  15. package/dist/global_setup.d.ts +3 -0
  16. package/dist/global_setup.js +173 -0
  17. package/dist/global_setup.js.map +1 -0
  18. package/dist/index.d.ts +9 -0
  19. package/dist/index.js +47 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/mock_browser_api.d.ts +31 -0
  22. package/dist/mock_browser_api.js +71 -0
  23. package/dist/mock_browser_api.js.map +1 -0
  24. package/dist/server/channel.d.ts +12 -0
  25. package/dist/server/channel.js +25 -0
  26. package/dist/server/channel.js.map +1 -0
  27. package/dist/server/client.d.ts +16 -0
  28. package/dist/server/client.js +39 -0
  29. package/dist/server/client.js.map +1 -0
  30. package/dist/server/default_config.d.ts +2 -0
  31. package/dist/server/default_config.js +755 -0
  32. package/dist/server/default_config.js.map +1 -0
  33. package/dist/server/index.d.ts +7 -0
  34. package/dist/server/init.d.ts +23 -0
  35. package/dist/server/init.js +73 -0
  36. package/dist/server/init.js.map +1 -0
  37. package/dist/server/post.d.ts +2 -0
  38. package/dist/server/post.js +31 -0
  39. package/dist/server/post.js.map +1 -0
  40. package/dist/server/team.d.ts +2 -0
  41. package/dist/server/team.js +18 -0
  42. package/dist/server/team.js.map +1 -0
  43. package/dist/server/user.d.ts +3 -0
  44. package/dist/server/user.js +33 -0
  45. package/dist/server/user.js.map +1 -0
  46. package/dist/test_action.d.ts +4 -0
  47. package/dist/test_action.js +24 -0
  48. package/dist/test_action.js.map +1 -0
  49. package/dist/test_config.d.ts +20 -0
  50. package/dist/test_config.js +82 -0
  51. package/dist/test_config.js.map +1 -0
  52. package/dist/test_fixture.d.ts +72 -0
  53. package/dist/test_fixture.js +172 -0
  54. package/dist/test_fixture.js.map +1 -0
  55. package/dist/types.d.ts +91 -0
  56. package/dist/ui/components/channels/app_bar.d.ts +7 -0
  57. package/dist/ui/components/channels/app_bar.js +20 -0
  58. package/dist/ui/components/channels/app_bar.js.map +1 -0
  59. package/dist/ui/components/channels/center_view.d.ts +52 -0
  60. package/dist/ui/components/channels/center_view.js +124 -0
  61. package/dist/ui/components/channels/center_view.js.map +1 -0
  62. package/dist/ui/components/channels/delete_post_confirmation_dialog.d.ts +11 -0
  63. package/dist/ui/components/channels/delete_post_confirmation_dialog.js +35 -0
  64. package/dist/ui/components/channels/delete_post_confirmation_dialog.js.map +1 -0
  65. package/dist/ui/components/channels/delete_post_modal.d.ts +8 -0
  66. package/dist/ui/components/channels/delete_post_modal.js +26 -0
  67. package/dist/ui/components/channels/delete_post_modal.js.map +1 -0
  68. package/dist/ui/components/channels/emoji_gif_picker.d.ts +16 -0
  69. package/dist/ui/components/channels/emoji_gif_picker.js +50 -0
  70. package/dist/ui/components/channels/emoji_gif_picker.js.map +1 -0
  71. package/dist/ui/components/channels/find_channels_modal.d.ts +8 -0
  72. package/dist/ui/components/channels/find_channels_modal.js +22 -0
  73. package/dist/ui/components/channels/find_channels_modal.js.map +1 -0
  74. package/dist/ui/components/channels/generic_confirm_modal.d.ts +16 -0
  75. package/dist/ui/components/channels/generic_confirm_modal.js +40 -0
  76. package/dist/ui/components/channels/generic_confirm_modal.js.map +1 -0
  77. package/dist/ui/components/channels/header.d.ts +6 -0
  78. package/dist/ui/components/channels/header.js +18 -0
  79. package/dist/ui/components/channels/header.js.map +1 -0
  80. package/dist/ui/components/channels/message_priority.d.ts +18 -0
  81. package/dist/ui/components/channels/message_priority.js +66 -0
  82. package/dist/ui/components/channels/message_priority.js.map +1 -0
  83. package/dist/ui/components/channels/post.d.ts +29 -0
  84. package/dist/ui/components/channels/post.js +63 -0
  85. package/dist/ui/components/channels/post.js.map +1 -0
  86. package/dist/ui/components/channels/post_create.d.ts +41 -0
  87. package/dist/ui/components/channels/post_create.js +118 -0
  88. package/dist/ui/components/channels/post_create.js.map +1 -0
  89. package/dist/ui/components/channels/post_dot_menu.d.ts +20 -0
  90. package/dist/ui/components/channels/post_dot_menu.js +47 -0
  91. package/dist/ui/components/channels/post_dot_menu.js.map +1 -0
  92. package/dist/ui/components/channels/post_edit.d.ts +21 -0
  93. package/dist/ui/components/channels/post_edit.js +76 -0
  94. package/dist/ui/components/channels/post_edit.js.map +1 -0
  95. package/dist/ui/components/channels/post_menu.d.ts +26 -0
  96. package/dist/ui/components/channels/post_menu.js +54 -0
  97. package/dist/ui/components/channels/post_menu.js.map +1 -0
  98. package/dist/ui/components/channels/post_reminder_menu.d.ts +11 -0
  99. package/dist/ui/components/channels/post_reminder_menu.js +29 -0
  100. package/dist/ui/components/channels/post_reminder_menu.js.map +1 -0
  101. package/dist/ui/components/channels/restore_post_confirmation_dialog.d.ts +10 -0
  102. package/dist/ui/components/channels/restore_post_confirmation_dialog.js +30 -0
  103. package/dist/ui/components/channels/restore_post_confirmation_dialog.js.map +1 -0
  104. package/dist/ui/components/channels/scheduled_draft_menu.d.ts +8 -0
  105. package/dist/ui/components/channels/scheduled_draft_menu.js +23 -0
  106. package/dist/ui/components/channels/scheduled_draft_menu.js.map +1 -0
  107. package/dist/ui/components/channels/scheduled_draft_modal.d.ts +20 -0
  108. package/dist/ui/components/channels/scheduled_draft_modal.js +84 -0
  109. package/dist/ui/components/channels/scheduled_draft_modal.js.map +1 -0
  110. package/dist/ui/components/channels/search_popover.d.ts +15 -0
  111. package/dist/ui/components/channels/search_popover.js +43 -0
  112. package/dist/ui/components/channels/search_popover.js.map +1 -0
  113. package/dist/ui/components/channels/settings/notification_settings.d.ts +13 -0
  114. package/dist/ui/components/channels/settings/notification_settings.js +41 -0
  115. package/dist/ui/components/channels/settings/notification_settings.js.map +1 -0
  116. package/dist/ui/components/channels/settings/settings_modal.d.ts +11 -0
  117. package/dist/ui/components/channels/settings/settings_modal.js +32 -0
  118. package/dist/ui/components/channels/settings/settings_modal.js.map +1 -0
  119. package/dist/ui/components/channels/sidebar_left.d.ts +24 -0
  120. package/dist/ui/components/channels/sidebar_left.js +54 -0
  121. package/dist/ui/components/channels/sidebar_left.js.map +1 -0
  122. package/dist/ui/components/channels/sidebar_right.d.ts +38 -0
  123. package/dist/ui/components/channels/sidebar_right.js +87 -0
  124. package/dist/ui/components/channels/sidebar_right.js.map +1 -0
  125. package/dist/ui/components/channels/thread_footer.d.ts +11 -0
  126. package/dist/ui/components/channels/thread_footer.js +27 -0
  127. package/dist/ui/components/channels/thread_footer.js.map +1 -0
  128. package/dist/ui/components/channels/user_profile_popover.d.ts +7 -0
  129. package/dist/ui/components/channels/user_profile_popover.js +21 -0
  130. package/dist/ui/components/channels/user_profile_popover.js.map +1 -0
  131. package/dist/ui/components/footer.d.ts +11 -0
  132. package/dist/ui/components/footer.js +28 -0
  133. package/dist/ui/components/footer.js.map +1 -0
  134. package/dist/ui/components/global_header.d.ts +15 -0
  135. package/dist/ui/components/global_header.js +46 -0
  136. package/dist/ui/components/global_header.js.map +1 -0
  137. package/dist/ui/components/index.d.ts +73 -0
  138. package/dist/ui/components/index.js +77 -0
  139. package/dist/ui/components/index.js.map +1 -0
  140. package/dist/ui/components/main_header.d.ts +8 -0
  141. package/dist/ui/components/main_header.js +22 -0
  142. package/dist/ui/components/main_header.js.map +1 -0
  143. package/dist/ui/components/system_console/navbar.d.ts +6 -0
  144. package/dist/ui/components/system_console/navbar.js +18 -0
  145. package/dist/ui/components/system_console/navbar.js.map +1 -0
  146. package/dist/ui/components/system_console/sections/system_users/column_toggle_menu.d.ts +22 -0
  147. package/dist/ui/components/system_console/sections/system_users/column_toggle_menu.js +47 -0
  148. package/dist/ui/components/system_console/sections/system_users/column_toggle_menu.js.map +1 -0
  149. package/dist/ui/components/system_console/sections/system_users/feature_discovery.d.ts +10 -0
  150. package/dist/ui/components/system_console/sections/system_users/feature_discovery.js +24 -0
  151. package/dist/ui/components/system_console/sections/system_users/feature_discovery.js.map +1 -0
  152. package/dist/ui/components/system_console/sections/system_users/filter_menu.d.ts +21 -0
  153. package/dist/ui/components/system_console/sections/system_users/filter_menu.js +42 -0
  154. package/dist/ui/components/system_console/sections/system_users/filter_menu.js.map +1 -0
  155. package/dist/ui/components/system_console/sections/system_users/filter_popover.d.ts +30 -0
  156. package/dist/ui/components/system_console/sections/system_users/filter_popover.js +61 -0
  157. package/dist/ui/components/system_console/sections/system_users/filter_popover.js.map +1 -0
  158. package/dist/ui/components/system_console/sections/system_users/mobile_security.d.ts +23 -0
  159. package/dist/ui/components/system_console/sections/system_users/mobile_security.js +56 -0
  160. package/dist/ui/components/system_console/sections/system_users/mobile_security.js.map +1 -0
  161. package/dist/ui/components/system_console/sections/system_users/system_users.d.ts +58 -0
  162. package/dist/ui/components/system_console/sections/system_users/system_users.js +114 -0
  163. package/dist/ui/components/system_console/sections/system_users/system_users.js.map +1 -0
  164. package/dist/ui/components/system_console/sidebar.d.ts +17 -0
  165. package/dist/ui/components/system_console/sidebar.js +37 -0
  166. package/dist/ui/components/system_console/sidebar.js.map +1 -0
  167. package/dist/ui/pages/channels.d.ts +31 -0
  168. package/dist/ui/pages/channels.js +79 -0
  169. package/dist/ui/pages/channels.js.map +1 -0
  170. package/dist/ui/pages/drafts.d.ts +30 -0
  171. package/dist/ui/pages/drafts.js +114 -0
  172. package/dist/ui/pages/drafts.js.map +1 -0
  173. package/dist/ui/pages/index.d.ts +19 -0
  174. package/dist/ui/pages/index.js +34 -0
  175. package/dist/ui/pages/index.js.map +1 -0
  176. package/dist/ui/pages/landing_login.d.ts +11 -0
  177. package/dist/ui/pages/landing_login.js +36 -0
  178. package/dist/ui/pages/landing_login.js.map +1 -0
  179. package/dist/ui/pages/login.d.ts +25 -0
  180. package/dist/ui/pages/login.js +62 -0
  181. package/dist/ui/pages/login.js.map +1 -0
  182. package/dist/ui/pages/reset_password.d.ts +15 -0
  183. package/dist/ui/pages/reset_password.js +44 -0
  184. package/dist/ui/pages/reset_password.js.map +1 -0
  185. package/dist/ui/pages/scheduled_draft.d.ts +38 -0
  186. package/dist/ui/pages/scheduled_draft.js +144 -0
  187. package/dist/ui/pages/scheduled_draft.js.map +1 -0
  188. package/dist/ui/pages/signup.d.ts +31 -0
  189. package/dist/ui/pages/signup.js +78 -0
  190. package/dist/ui/pages/signup.js.map +1 -0
  191. package/dist/ui/pages/system_console.d.ts +26 -0
  192. package/dist/ui/pages/system_console.js +64 -0
  193. package/dist/ui/pages/system_console.js.map +1 -0
  194. package/dist/util.d.ts +29 -0
  195. package/dist/util.js +51 -0
  196. package/dist/util.js.map +1 -0
  197. package/dist/visual/index.d.ts +3 -0
  198. package/dist/visual/index.js +37 -0
  199. package/dist/visual/index.js.map +1 -0
  200. package/dist/visual/percy.d.ts +2 -0
  201. package/dist/visual/percy.js +23 -0
  202. package/dist/visual/percy.js.map +1 -0
  203. package/package.json +68 -0
@@ -0,0 +1,172 @@
1
+ 'use strict';
2
+
3
+ var test$1 = require('@playwright/test');
4
+ var playwright = require('@axe-core/playwright');
5
+ var browser_context = require('./browser_context.js');
6
+ var flag = require('./flag.js');
7
+ var file = require('./file.js');
8
+ require('@mattermost/client');
9
+ require('./test_config.js');
10
+ var channel = require('./server/channel.js');
11
+ require('./server/default_config.js');
12
+ var init = require('./server/init.js');
13
+ var post = require('./server/post.js');
14
+ var team = require('./server/team.js');
15
+ var user = require('./server/user.js');
16
+ var test_action = require('./test_action.js');
17
+ var index = require('./ui/pages/index.js');
18
+ var index$1 = require('./visual/index.js');
19
+ var mock_browser_api = require('./mock_browser_api.js');
20
+ var util = require('./util.js');
21
+ var asyncWaitUntil = require('async-wait-until');
22
+
23
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
24
+ // See LICENSE.txt for license information.
25
+ const test = test$1.test.extend({
26
+ // eslint-disable-next-line no-empty-pattern
27
+ axe: async ({}, use) => {
28
+ const ab = new AxeBuilderExtended();
29
+ await use(ab);
30
+ },
31
+ pw: async ({ browser, page, isMobile }, use) => {
32
+ const pw = new PlaywrightExtended(browser, page, isMobile);
33
+ await use(pw);
34
+ await pw.testBrowser.close();
35
+ },
36
+ });
37
+ class PlaywrightExtended {
38
+ // ./browser_context
39
+ testBrowser;
40
+ // ./flag
41
+ shouldHaveCallsEnabled;
42
+ shouldHaveFeatureFlag;
43
+ shouldRunInLinux;
44
+ ensureLicense;
45
+ skipIfNoLicense;
46
+ skipIfFeatureFlagNotSet;
47
+ // ./file
48
+ getBlobFromAsset;
49
+ getFileFromAsset;
50
+ // ./server
51
+ getAdminClient;
52
+ initSetup;
53
+ // ./test_action
54
+ hideDynamicChannelsContent;
55
+ waitForAnimationEnd;
56
+ waitUntil;
57
+ // ./mock_browser_api
58
+ stubNotification;
59
+ waitForNotification;
60
+ // ./visual
61
+ matchSnapshot;
62
+ // ./util
63
+ duration;
64
+ simpleEmailRe;
65
+ wait;
66
+ // random
67
+ random;
68
+ // unauthenticated page
69
+ loginPage;
70
+ landingLoginPage;
71
+ signupPage;
72
+ resetPasswordPage;
73
+ hasSeenLandingPage;
74
+ constructor(browser, page, isMobile) {
75
+ // ./browser_context
76
+ this.testBrowser = new browser_context.TestBrowser(browser);
77
+ // ./flag
78
+ this.shouldHaveCallsEnabled = flag.shouldHaveCallsEnabled;
79
+ this.shouldHaveFeatureFlag = flag.shouldHaveFeatureFlag;
80
+ this.shouldRunInLinux = flag.shouldRunInLinux;
81
+ this.ensureLicense = flag.ensureLicense;
82
+ this.skipIfNoLicense = flag.skipIfNoLicense;
83
+ this.skipIfFeatureFlagNotSet = flag.skipIfFeatureFlagNotSet;
84
+ // ./file
85
+ this.getBlobFromAsset = file.getBlobFromAsset;
86
+ this.getFileFromAsset = file.getFileFromAsset;
87
+ // ./server
88
+ this.initSetup = init.initSetup;
89
+ this.getAdminClient = init.getAdminClient;
90
+ // ./test_action
91
+ this.hideDynamicChannelsContent = test_action.hideDynamicChannelsContent;
92
+ this.waitForAnimationEnd = test_action.waitForAnimationEnd;
93
+ this.waitUntil = asyncWaitUntil.waitUntil;
94
+ // unauthenticated page
95
+ this.loginPage = new index.pages.LoginPage(page);
96
+ this.landingLoginPage = new index.pages.LandingLoginPage(page, isMobile);
97
+ this.signupPage = new index.pages.SignupPage(page);
98
+ this.resetPasswordPage = new index.pages.ResetPasswordPage(page);
99
+ // ./mock_browser_api
100
+ this.stubNotification = mock_browser_api.stubNotification;
101
+ this.waitForNotification = mock_browser_api.waitForNotification;
102
+ // ./visual
103
+ this.matchSnapshot = index$1.matchSnapshot;
104
+ // ./util
105
+ this.duration = util.duration;
106
+ this.wait = util.wait;
107
+ this.simpleEmailRe = util.simpleEmailRe;
108
+ this.random = {
109
+ id: util.getRandomId,
110
+ channel: channel.createRandomChannel,
111
+ post: post.createRandomPost,
112
+ team: team.createRandomTeam,
113
+ user: user.createRandomUser,
114
+ };
115
+ this.hasSeenLandingPage = async () => {
116
+ // Visit the base URL to be able to set the localStorage
117
+ await page.goto('/');
118
+ return await waitUntilLocalStorageIsSet(page, '__landingPageSeen__', 'true');
119
+ };
120
+ }
121
+ }
122
+ class AxeBuilderExtended {
123
+ builder;
124
+ // See https://github.com/dequelabs/axe-core/blob/master/doc/API.md#axe-core-tags
125
+ tags = ['wcag2a', 'wcag2aa'];
126
+ constructor() {
127
+ this.builder = (page, options = {}) => {
128
+ // See https://github.com/dequelabs/axe-core/blob/master/doc/rule-descriptions.md#wcag-20-level-a--aa-rules
129
+ const disabledRules = [];
130
+ if (options.disableColorContrast) {
131
+ // Disabled in pages due to impact to overall theme of Mattermost.
132
+ // Option: make use of custom theme to improve color contrast.
133
+ disabledRules.push('color-contrast');
134
+ }
135
+ if (options.disableLinkInTextBlock) {
136
+ // Disabled in pages due to impact to overall theme of Mattermost.
137
+ // Option: make use of custom theme to improve color contrast.
138
+ disabledRules.push('link-in-text-block');
139
+ }
140
+ return new playwright.AxeBuilder({ page }).withTags(this.tags).disableRules(disabledRules);
141
+ };
142
+ }
143
+ violationFingerprints(accessibilityScanResults) {
144
+ const fingerprints = accessibilityScanResults.violations.map((violation) => ({
145
+ rule: violation.id,
146
+ description: violation.description,
147
+ helpUrl: violation.helpUrl,
148
+ targets: violation.nodes.map((node) => {
149
+ return { target: node.target, impact: node.impact, html: node.html };
150
+ }),
151
+ }));
152
+ return JSON.stringify(fingerprints, null, 2);
153
+ }
154
+ }
155
+ async function waitUntilLocalStorageIsSet(page, key, value, timeout = util.duration.ten_sec) {
156
+ await asyncWaitUntil.waitUntil(() => page.evaluate(({ key, value }) => {
157
+ if (localStorage.getItem(key) === value) {
158
+ return true;
159
+ }
160
+ localStorage.setItem(key, value);
161
+ return false;
162
+ }, { key, value }), { timeout });
163
+ }
164
+
165
+ Object.defineProperty(exports, "expect", {
166
+ enumerable: true,
167
+ get: function () { return test$1.expect; }
168
+ });
169
+ exports.AxeBuilderExtended = AxeBuilderExtended;
170
+ exports.PlaywrightExtended = PlaywrightExtended;
171
+ exports.test = test;
172
+ //# sourceMappingURL=test_fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_fixture.js","sources":["../src/test_fixture.ts"],"sourcesContent":["// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {Browser, Page, test as base} from '@playwright/test';\nimport {AxeResults} from 'axe-core';\nimport {AxeBuilder} from '@axe-core/playwright';\n\nimport {TestBrowser} from './browser_context';\nimport {\n ensureLicense,\n shouldHaveCallsEnabled,\n shouldHaveFeatureFlag,\n shouldRunInLinux,\n skipIfFeatureFlagNotSet,\n skipIfNoLicense,\n} from './flag';\nimport {getBlobFromAsset, getFileFromAsset} from './file';\nimport {\n createRandomChannel,\n createRandomPost,\n createRandomTeam,\n createRandomUser,\n getAdminClient,\n initSetup,\n} from './server';\nimport {hideDynamicChannelsContent, waitForAnimationEnd, waitUntil} from './test_action';\nimport {pages} from './ui/pages';\nimport {matchSnapshot} from './visual';\nimport {stubNotification, waitForNotification} from './mock_browser_api';\nimport {duration, getRandomId, simpleEmailRe, wait} from './util';\n\nexport {expect} from '@playwright/test';\n\nexport type ExtendedFixtures = {\n axe: AxeBuilderExtended;\n pw: PlaywrightExtended;\n};\n\ntype AxeBuilderOptions = {\n disableColorContrast?: boolean;\n disableLinkInTextBlock?: boolean;\n};\n\nexport const test = base.extend<ExtendedFixtures>({\n // eslint-disable-next-line no-empty-pattern\n axe: async ({}, use) => {\n const ab = new AxeBuilderExtended();\n await use(ab);\n },\n pw: async ({browser, page, isMobile}, use) => {\n const pw = new PlaywrightExtended(browser, page, isMobile);\n await use(pw);\n await pw.testBrowser.close();\n },\n});\n\nexport class PlaywrightExtended {\n // ./browser_context\n readonly testBrowser;\n\n // ./flag\n readonly shouldHaveCallsEnabled;\n readonly shouldHaveFeatureFlag;\n readonly shouldRunInLinux;\n readonly ensureLicense;\n readonly skipIfNoLicense;\n readonly skipIfFeatureFlagNotSet;\n\n // ./file\n readonly getBlobFromAsset;\n readonly getFileFromAsset;\n\n // ./server\n readonly getAdminClient;\n readonly initSetup;\n\n // ./test_action\n readonly hideDynamicChannelsContent;\n readonly waitForAnimationEnd;\n readonly waitUntil;\n\n // ./mock_browser_api\n readonly stubNotification;\n readonly waitForNotification;\n\n // ./visual\n readonly matchSnapshot;\n\n // ./util\n readonly duration;\n readonly simpleEmailRe;\n readonly wait;\n\n // random\n readonly random;\n\n // unauthenticated page\n readonly loginPage;\n readonly landingLoginPage;\n readonly signupPage;\n readonly resetPasswordPage;\n\n readonly hasSeenLandingPage;\n\n constructor(browser: Browser, page: Page, isMobile: boolean) {\n // ./browser_context\n this.testBrowser = new TestBrowser(browser);\n\n // ./flag\n this.shouldHaveCallsEnabled = shouldHaveCallsEnabled;\n this.shouldHaveFeatureFlag = shouldHaveFeatureFlag;\n this.shouldRunInLinux = shouldRunInLinux;\n this.ensureLicense = ensureLicense;\n this.skipIfNoLicense = skipIfNoLicense;\n this.skipIfFeatureFlagNotSet = skipIfFeatureFlagNotSet;\n\n // ./file\n this.getBlobFromAsset = getBlobFromAsset;\n this.getFileFromAsset = getFileFromAsset;\n\n // ./server\n this.initSetup = initSetup;\n this.getAdminClient = getAdminClient;\n\n // ./test_action\n this.hideDynamicChannelsContent = hideDynamicChannelsContent;\n this.waitForAnimationEnd = waitForAnimationEnd;\n this.waitUntil = waitUntil;\n\n // unauthenticated page\n this.loginPage = new pages.LoginPage(page);\n this.landingLoginPage = new pages.LandingLoginPage(page, isMobile);\n this.signupPage = new pages.SignupPage(page);\n this.resetPasswordPage = new pages.ResetPasswordPage(page);\n\n // ./mock_browser_api\n this.stubNotification = stubNotification;\n this.waitForNotification = waitForNotification;\n\n // ./visual\n this.matchSnapshot = matchSnapshot;\n\n // ./util\n this.duration = duration;\n this.wait = wait;\n this.simpleEmailRe = simpleEmailRe;\n\n this.random = {\n id: getRandomId,\n channel: createRandomChannel,\n post: createRandomPost,\n team: createRandomTeam,\n user: createRandomUser,\n };\n\n this.hasSeenLandingPage = async () => {\n // Visit the base URL to be able to set the localStorage\n await page.goto('/');\n return await waitUntilLocalStorageIsSet(page, '__landingPageSeen__', 'true');\n };\n }\n}\n\nexport class AxeBuilderExtended {\n readonly builder: (page: Page, options?: AxeBuilderOptions) => AxeBuilder;\n\n // See https://github.com/dequelabs/axe-core/blob/master/doc/API.md#axe-core-tags\n readonly tags: string[] = ['wcag2a', 'wcag2aa'];\n\n constructor() {\n this.builder = (page: Page, options: AxeBuilderOptions = {}) => {\n // See https://github.com/dequelabs/axe-core/blob/master/doc/rule-descriptions.md#wcag-20-level-a--aa-rules\n const disabledRules: string[] = [];\n\n if (options.disableColorContrast) {\n // Disabled in pages due to impact to overall theme of Mattermost.\n // Option: make use of custom theme to improve color contrast.\n disabledRules.push('color-contrast');\n }\n\n if (options.disableLinkInTextBlock) {\n // Disabled in pages due to impact to overall theme of Mattermost.\n // Option: make use of custom theme to improve color contrast.\n disabledRules.push('link-in-text-block');\n }\n\n return new AxeBuilder({page}).withTags(this.tags).disableRules(disabledRules);\n };\n }\n\n violationFingerprints(accessibilityScanResults: AxeResults) {\n const fingerprints = accessibilityScanResults.violations.map((violation) => ({\n rule: violation.id,\n description: violation.description,\n helpUrl: violation.helpUrl,\n targets: violation.nodes.map((node) => {\n return {target: node.target, impact: node.impact, html: node.html};\n }),\n }));\n\n return JSON.stringify(fingerprints, null, 2);\n }\n}\n\nasync function waitUntilLocalStorageIsSet(page: Page, key: string, value: string, timeout = duration.ten_sec) {\n await waitUntil(\n () =>\n page.evaluate(\n ({key, value}) => {\n if (localStorage.getItem(key) === value) {\n return true;\n }\n localStorage.setItem(key, value);\n return false;\n },\n {key, value},\n ),\n {timeout},\n );\n}\n"],"names":["base","TestBrowser","shouldHaveCallsEnabled","shouldHaveFeatureFlag","shouldRunInLinux","ensureLicense","skipIfNoLicense","skipIfFeatureFlagNotSet","getBlobFromAsset","getFileFromAsset","initSetup","getAdminClient","hideDynamicChannelsContent","waitForAnimationEnd","waitUntil","pages","stubNotification","waitForNotification","matchSnapshot","duration","wait","simpleEmailRe","getRandomId","createRandomChannel","createRandomPost","createRandomTeam","createRandomUser","AxeBuilder"],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import { Locator, Page, ViewportSize } from '@playwright/test';
2
+ export type TestArgs = {
3
+ page: Page;
4
+ browserName: string;
5
+ viewport?: ViewportSize | null;
6
+ };
7
+ export type ScreenshotOptions = {
8
+ /**
9
+ * When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different
10
+ * treatment depending on their duration:
11
+ * - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
12
+ * - infinite animations are canceled to initial state, and then played over after the screenshot.
13
+ *
14
+ * Defaults to `"disabled"` that disables animations.
15
+ */
16
+ animations?: 'disabled' | 'allow';
17
+ /**
18
+ * When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`, text caret behavior will not be
19
+ * changed. Defaults to `"hide"`.
20
+ */
21
+ caret?: 'hide' | 'initial';
22
+ /**
23
+ * An object which specifies clipping of the resulting image.
24
+ */
25
+ clip?: {
26
+ /**
27
+ * x-coordinate of top-left corner of clip area
28
+ */
29
+ x: number;
30
+ /**
31
+ * y-coordinate of top-left corner of clip area
32
+ */
33
+ y: number;
34
+ /**
35
+ * width of clipping area
36
+ */
37
+ width: number;
38
+ /**
39
+ * height of clipping area
40
+ */
41
+ height: number;
42
+ };
43
+ /**
44
+ * When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Defaults to
45
+ * `false`.
46
+ */
47
+ fullPage?: boolean;
48
+ /**
49
+ * Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink
50
+ * box `#FF00FF` (customized by `maskColor`) that completely covers its bounding box.
51
+ */
52
+ mask?: Array<Locator>;
53
+ /**
54
+ * Specify the color of the overlay box for masked elements, in
55
+ * [CSS color format](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). Default color is pink `#FF00FF`.
56
+ */
57
+ maskColor?: string;
58
+ /**
59
+ * An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`. Default is
60
+ * configurable with `TestConfig.expect`. Unset by default.
61
+ */
62
+ maxDiffPixelRatio?: number;
63
+ /**
64
+ * An acceptable amount of pixels that could be different. Default is configurable with `TestConfig.expect`. Unset by
65
+ * default.
66
+ */
67
+ maxDiffPixels?: number;
68
+ /**
69
+ * Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images.
70
+ * Defaults to `false`.
71
+ */
72
+ omitBackground?: boolean;
73
+ /**
74
+ * When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this
75
+ * will keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so
76
+ * screenshots of high-dpi devices will be twice as large or even larger.
77
+ *
78
+ * Defaults to `"css"`.
79
+ */
80
+ scale?: 'css' | 'device';
81
+ /**
82
+ * An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the
83
+ * same pixel in compared images, between zero (strict) and one (lax), default is configurable with
84
+ * `TestConfig.expect`. Defaults to `0.2`.
85
+ */
86
+ threshold?: number;
87
+ /**
88
+ * Time to retry the assertion for in milliseconds. Defaults to `timeout` in `TestConfig.expect`.
89
+ */
90
+ timeout?: number;
91
+ };
@@ -0,0 +1,7 @@
1
+ import { Locator } from '@playwright/test';
2
+ export default class ChannelsAppBar {
3
+ readonly container: Locator;
4
+ readonly playbooksIcon: Locator;
5
+ constructor(container: Locator);
6
+ toBeVisible(): Promise<void>;
7
+ }
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var test = require('@playwright/test');
4
+
5
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
6
+ // See LICENSE.txt for license information.
7
+ class ChannelsAppBar {
8
+ container;
9
+ playbooksIcon;
10
+ constructor(container) {
11
+ this.container = container;
12
+ this.playbooksIcon = container.locator('#app-bar-icon-playbooks').getByRole('img');
13
+ }
14
+ async toBeVisible() {
15
+ await test.expect(this.container).toBeVisible();
16
+ }
17
+ }
18
+
19
+ module.exports = ChannelsAppBar;
20
+ //# sourceMappingURL=app_bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app_bar.js","sources":["../../../../src/ui/components/channels/app_bar.ts"],"sourcesContent":["// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {Locator, expect} from '@playwright/test';\n\nexport default class ChannelsAppBar {\n readonly container: Locator;\n\n readonly playbooksIcon;\n\n constructor(container: Locator) {\n this.container = container;\n\n this.playbooksIcon = container.locator('#app-bar-icon-playbooks').getByRole('img');\n }\n\n async toBeVisible() {\n await expect(this.container).toBeVisible();\n }\n}\n"],"names":["expect"],"mappings":";;;;AAAA;AACA;AAIc,MAAO,cAAc,CAAA;AACtB,IAAA,SAAS;AAET,IAAA,aAAa;AAEtB,IAAA,WAAA,CAAY,SAAkB,EAAA;AAC1B,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS;AAE1B,QAAA,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC;;AAGtF,IAAA,MAAM,WAAW,GAAA;QACb,MAAMA,WAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;;AAEjD;;;;"}
@@ -0,0 +1,52 @@
1
+ import { Locator } from '@playwright/test';
2
+ import ChannelsHeader from './header';
3
+ import ChannelsPostCreate from './post_create';
4
+ import ChannelsPostEdit from './post_edit';
5
+ import ChannelsPost from './post';
6
+ export default class ChannelsCenterView {
7
+ readonly container: Locator;
8
+ readonly header: ChannelsHeader;
9
+ readonly postCreate: ChannelsPostCreate;
10
+ readonly scheduledDraftOptions: ChannelsPostCreate;
11
+ readonly postBoxIndicator: Locator;
12
+ readonly scheduledDraftChannelIcon: Locator;
13
+ readonly scheduledDraftChannelInfoMessage: Locator;
14
+ readonly scheduledDraftChannelInfoMessageLocator: string;
15
+ readonly scheduledDraftChannelInfoMessageText: Locator;
16
+ readonly scheduledDraftSeeAllLink: Locator;
17
+ readonly postEdit: ChannelsPostEdit;
18
+ readonly editedPostIcon: (postID: string) => Locator;
19
+ constructor(container: Locator);
20
+ toBeVisible(): Promise<void>;
21
+ /**
22
+ * Click on "See all scheduled messages"
23
+ */
24
+ clickOnSeeAllscheduledDrafts(): Promise<void>;
25
+ /**
26
+ * Return the first post in the Center
27
+ */
28
+ getFirstPost(): Promise<ChannelsPost>;
29
+ /**
30
+ * Return the last post in the Center
31
+ */
32
+ getLastPost(): Promise<ChannelsPost>;
33
+ /**
34
+ * Return the ID of the last post in the Center
35
+ */
36
+ getLastPostID(): Promise<string | null>;
37
+ /**
38
+ * Return the Nth post in the Center from the top
39
+ * @param index
40
+ * @returns
41
+ */
42
+ getNthPost(index: number): Promise<ChannelsPost>;
43
+ /**
44
+ * Returns the Center post by post's id
45
+ * @param postId Just the ID without the prefix
46
+ */
47
+ getPostById(id: string): Promise<ChannelsPost>;
48
+ waitUntilLastPostContains(text: string, timeout?: number): Promise<void>;
49
+ waitUntilPostWithIdContains(id: string, text: string, timeout?: number): Promise<void>;
50
+ verifyscheduledDraftChannelInfo(): Promise<void>;
51
+ clickOnLastEditedPost(postID: string | null): Promise<void>;
52
+ }
@@ -0,0 +1,124 @@
1
+ 'use strict';
2
+
3
+ var test = require('@playwright/test');
4
+ var header = require('./header.js');
5
+ var post_create = require('./post_create.js');
6
+ var post_edit = require('./post_edit.js');
7
+ var post = require('./post.js');
8
+ var util = require('../../../util.js');
9
+ var asyncWaitUntil = require('async-wait-until');
10
+
11
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
12
+ // See LICENSE.txt for license information.
13
+ class ChannelsCenterView {
14
+ container;
15
+ header;
16
+ postCreate;
17
+ scheduledDraftOptions;
18
+ postBoxIndicator;
19
+ scheduledDraftChannelIcon;
20
+ scheduledDraftChannelInfoMessage;
21
+ scheduledDraftChannelInfoMessageLocator;
22
+ scheduledDraftChannelInfoMessageText;
23
+ scheduledDraftSeeAllLink;
24
+ postEdit;
25
+ editedPostIcon;
26
+ constructor(container) {
27
+ this.container = container;
28
+ this.scheduledDraftChannelInfoMessageLocator = 'span:has-text("Message scheduled for")';
29
+ this.header = new header(this.container.locator('.channel-header'));
30
+ this.postCreate = new post_create(container.getByTestId('post-create'));
31
+ this.scheduledDraftOptions = new post_create(container.locator('#dropdown_send_post_options'));
32
+ this.postEdit = new post_edit(container.locator('.post-edit__container'));
33
+ this.postBoxIndicator = container.locator('div.postBoxIndicator');
34
+ this.scheduledDraftChannelIcon = container.locator('#create_post i.icon-draft-indicator');
35
+ this.scheduledDraftChannelInfoMessage = container.locator('div.ScheduledPostIndicator span');
36
+ this.scheduledDraftChannelInfoMessageText = container.locator(this.scheduledDraftChannelInfoMessageLocator);
37
+ this.scheduledDraftSeeAllLink = container.locator('a:has-text("See all")');
38
+ this.editedPostIcon = (postID) => container.locator(`#postEdited_${postID}`);
39
+ }
40
+ async toBeVisible() {
41
+ await test.expect(this.container).toBeVisible();
42
+ await this.postCreate.toBeVisible();
43
+ }
44
+ /**
45
+ * Click on "See all scheduled messages"
46
+ */
47
+ async clickOnSeeAllscheduledDrafts() {
48
+ await this.scheduledDraftSeeAllLink.isVisible();
49
+ await this.scheduledDraftSeeAllLink.click();
50
+ }
51
+ /**
52
+ * Return the first post in the Center
53
+ */
54
+ async getFirstPost() {
55
+ const firstPost = this.container.getByTestId('postView').first();
56
+ await firstPost.waitFor();
57
+ return new post(firstPost);
58
+ }
59
+ /**
60
+ * Return the last post in the Center
61
+ */
62
+ async getLastPost() {
63
+ const lastPost = this.container.getByTestId('postView').last();
64
+ await lastPost.waitFor();
65
+ return new post(lastPost);
66
+ }
67
+ /**
68
+ * Return the ID of the last post in the Center
69
+ */
70
+ async getLastPostID() {
71
+ return this.container
72
+ .getByTestId('postView')
73
+ .last()
74
+ .getAttribute('id')
75
+ .then((id) => (id ? id.split('_')[1] : null));
76
+ }
77
+ /**
78
+ * Return the Nth post in the Center from the top
79
+ * @param index
80
+ * @returns
81
+ */
82
+ async getNthPost(index) {
83
+ const nthPost = this.container.getByTestId('postView').nth(index);
84
+ await nthPost.waitFor();
85
+ return new post(nthPost);
86
+ }
87
+ /**
88
+ * Returns the Center post by post's id
89
+ * @param postId Just the ID without the prefix
90
+ */
91
+ async getPostById(id) {
92
+ const postById = this.container.locator(`[id="post_${id}"]`);
93
+ await postById.waitFor();
94
+ return new post(postById);
95
+ }
96
+ async waitUntilLastPostContains(text, timeout = util.duration.ten_sec) {
97
+ await asyncWaitUntil.waitUntil(async () => {
98
+ const post = await this.getLastPost();
99
+ const content = await post.container.textContent();
100
+ return content?.includes(text);
101
+ }, { timeout });
102
+ }
103
+ async waitUntilPostWithIdContains(id, text, timeout = util.duration.ten_sec) {
104
+ await asyncWaitUntil.waitUntil(async () => {
105
+ const post = await this.getPostById(id);
106
+ const content = await post.container.textContent();
107
+ return content?.includes(text);
108
+ }, { timeout });
109
+ }
110
+ async verifyscheduledDraftChannelInfo() {
111
+ await this.postBoxIndicator.isVisible();
112
+ await this.scheduledDraftChannelIcon.isVisible();
113
+ const messageLocator = this.scheduledDraftChannelInfoMessage.first();
114
+ await test.expect(messageLocator).toContainText('Message scheduled for');
115
+ }
116
+ async clickOnLastEditedPost(postID) {
117
+ if (postID) {
118
+ await this.editedPostIcon(postID).click();
119
+ }
120
+ }
121
+ }
122
+
123
+ module.exports = ChannelsCenterView;
124
+ //# sourceMappingURL=center_view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"center_view.js","sources":["../../../../src/ui/components/channels/center_view.ts"],"sourcesContent":["// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {Locator, expect} from '@playwright/test';\n\nimport ChannelsHeader from './header';\nimport ChannelsPostCreate from './post_create';\nimport ChannelsPostEdit from './post_edit';\nimport ChannelsPost from './post';\n\nimport {duration} from '@/util';\nimport {waitUntil} from '@/test_action';\n\nexport default class ChannelsCenterView {\n readonly container: Locator;\n\n readonly header;\n readonly postCreate;\n readonly scheduledDraftOptions;\n readonly postBoxIndicator;\n readonly scheduledDraftChannelIcon;\n readonly scheduledDraftChannelInfoMessage;\n readonly scheduledDraftChannelInfoMessageLocator;\n readonly scheduledDraftChannelInfoMessageText;\n readonly scheduledDraftSeeAllLink;\n readonly postEdit;\n readonly editedPostIcon;\n\n constructor(container: Locator) {\n this.container = container;\n this.scheduledDraftChannelInfoMessageLocator = 'span:has-text(\"Message scheduled for\")';\n this.header = new ChannelsHeader(this.container.locator('.channel-header'));\n this.postCreate = new ChannelsPostCreate(container.getByTestId('post-create'));\n this.scheduledDraftOptions = new ChannelsPostCreate(container.locator('#dropdown_send_post_options'));\n this.postEdit = new ChannelsPostEdit(container.locator('.post-edit__container'));\n this.postBoxIndicator = container.locator('div.postBoxIndicator');\n this.scheduledDraftChannelIcon = container.locator('#create_post i.icon-draft-indicator');\n this.scheduledDraftChannelInfoMessage = container.locator('div.ScheduledPostIndicator span');\n this.scheduledDraftChannelInfoMessageText = container.locator(this.scheduledDraftChannelInfoMessageLocator);\n this.scheduledDraftSeeAllLink = container.locator('a:has-text(\"See all\")');\n this.editedPostIcon = (postID: string) => container.locator(`#postEdited_${postID}`);\n }\n\n async toBeVisible() {\n await expect(this.container).toBeVisible();\n await this.postCreate.toBeVisible();\n }\n\n /**\n * Click on \"See all scheduled messages\"\n */\n async clickOnSeeAllscheduledDrafts() {\n await this.scheduledDraftSeeAllLink.isVisible();\n await this.scheduledDraftSeeAllLink.click();\n }\n\n /**\n * Return the first post in the Center\n */\n async getFirstPost() {\n const firstPost = this.container.getByTestId('postView').first();\n await firstPost.waitFor();\n return new ChannelsPost(firstPost);\n }\n\n /**\n * Return the last post in the Center\n */\n async getLastPost() {\n const lastPost = this.container.getByTestId('postView').last();\n await lastPost.waitFor();\n return new ChannelsPost(lastPost);\n }\n\n /**\n * Return the ID of the last post in the Center\n */\n async getLastPostID() {\n return this.container\n .getByTestId('postView')\n .last()\n .getAttribute('id')\n .then((id) => (id ? id.split('_')[1] : null));\n }\n\n /**\n * Return the Nth post in the Center from the top\n * @param index\n * @returns\n */\n async getNthPost(index: number) {\n const nthPost = this.container.getByTestId('postView').nth(index);\n await nthPost.waitFor();\n return new ChannelsPost(nthPost);\n }\n\n /**\n * Returns the Center post by post's id\n * @param postId Just the ID without the prefix\n */\n async getPostById(id: string) {\n const postById = this.container.locator(`[id=\"post_${id}\"]`);\n await postById.waitFor();\n return new ChannelsPost(postById);\n }\n\n async waitUntilLastPostContains(text: string, timeout = duration.ten_sec) {\n await waitUntil(\n async () => {\n const post = await this.getLastPost();\n const content = await post.container.textContent();\n return content?.includes(text);\n },\n {timeout},\n );\n }\n\n async waitUntilPostWithIdContains(id: string, text: string, timeout = duration.ten_sec) {\n await waitUntil(\n async () => {\n const post = await this.getPostById(id);\n const content = await post.container.textContent();\n\n return content?.includes(text);\n },\n {timeout},\n );\n }\n\n async verifyscheduledDraftChannelInfo() {\n await this.postBoxIndicator.isVisible();\n await this.scheduledDraftChannelIcon.isVisible();\n const messageLocator = this.scheduledDraftChannelInfoMessage.first();\n await expect(messageLocator).toContainText('Message scheduled for');\n }\n\n async clickOnLastEditedPost(postID: string | null) {\n if (postID) {\n await this.editedPostIcon(postID).click();\n }\n }\n}\n"],"names":["ChannelsHeader","ChannelsPostCreate","ChannelsPostEdit","expect","ChannelsPost","duration","waitUntil"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Locator } from '@playwright/test';
2
+ export default class DeletePostConfirmationDialog {
3
+ readonly container: Locator;
4
+ readonly cancelButton: Locator;
5
+ readonly confirmButton: Locator;
6
+ constructor(container: Locator);
7
+ toBeVisible(): Promise<void>;
8
+ notToBeVisible(): Promise<void>;
9
+ cancelDeletion(): Promise<void>;
10
+ confirmDeletion(): Promise<void>;
11
+ }
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ var test = require('@playwright/test');
4
+
5
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
6
+ // See LICENSE.txt for license information.
7
+ class DeletePostConfirmationDialog {
8
+ container;
9
+ cancelButton;
10
+ confirmButton;
11
+ constructor(container) {
12
+ this.container = container;
13
+ this.cancelButton = container.locator('button.btn.btn-tertiary');
14
+ this.confirmButton = container.locator('button#deletePostModalButton');
15
+ }
16
+ async toBeVisible() {
17
+ await test.expect(this.container).toBeVisible();
18
+ await test.expect(this.cancelButton).toBeVisible();
19
+ await test.expect(this.confirmButton).toBeVisible();
20
+ }
21
+ async notToBeVisible() {
22
+ await test.expect(this.container).not.toBeVisible();
23
+ await test.expect(this.cancelButton).not.toBeVisible();
24
+ await test.expect(this.confirmButton).not.toBeVisible();
25
+ }
26
+ async cancelDeletion() {
27
+ await this.cancelButton.click();
28
+ }
29
+ async confirmDeletion() {
30
+ await this.confirmButton.click();
31
+ }
32
+ }
33
+
34
+ module.exports = DeletePostConfirmationDialog;
35
+ //# sourceMappingURL=delete_post_confirmation_dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete_post_confirmation_dialog.js","sources":["../../../../src/ui/components/channels/delete_post_confirmation_dialog.ts"],"sourcesContent":["// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {Locator, expect} from '@playwright/test';\n\nexport default class DeletePostConfirmationDialog {\n readonly container: Locator;\n\n readonly cancelButton;\n readonly confirmButton;\n\n constructor(container: Locator) {\n this.container = container;\n\n this.cancelButton = container.locator('button.btn.btn-tertiary');\n this.confirmButton = container.locator('button#deletePostModalButton');\n }\n\n async toBeVisible() {\n await expect(this.container).toBeVisible();\n await expect(this.cancelButton).toBeVisible();\n await expect(this.confirmButton).toBeVisible();\n }\n\n async notToBeVisible() {\n await expect(this.container).not.toBeVisible();\n await expect(this.cancelButton).not.toBeVisible();\n await expect(this.confirmButton).not.toBeVisible();\n }\n\n async cancelDeletion() {\n await this.cancelButton.click();\n }\n\n async confirmDeletion() {\n await this.confirmButton.click();\n }\n}\n"],"names":["expect"],"mappings":";;;;AAAA;AACA;AAIc,MAAO,4BAA4B,CAAA;AACpC,IAAA,SAAS;AAET,IAAA,YAAY;AACZ,IAAA,aAAa;AAEtB,IAAA,WAAA,CAAY,SAAkB,EAAA;AAC1B,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS;QAE1B,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,yBAAyB,CAAC;QAChE,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,8BAA8B,CAAC;;AAG1E,IAAA,MAAM,WAAW,GAAA;QACb,MAAMA,WAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;QAC1C,MAAMA,WAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE;QAC7C,MAAMA,WAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE;;AAGlD,IAAA,MAAM,cAAc,GAAA;QAChB,MAAMA,WAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE;QAC9C,MAAMA,WAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE;QACjD,MAAMA,WAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE;;AAGtD,IAAA,MAAM,cAAc,GAAA;AAChB,QAAA,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE;;AAGnC,IAAA,MAAM,eAAe,GAAA;AACjB,QAAA,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;;AAEvC;;;;"}
@@ -0,0 +1,8 @@
1
+ import { Locator } from '@playwright/test';
2
+ export default class DeletePostModal {
3
+ readonly container: Locator;
4
+ readonly confirmButton: Locator;
5
+ constructor(container: Locator);
6
+ toBeVisible(): Promise<void>;
7
+ confirm(): Promise<void>;
8
+ }
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var test = require('@playwright/test');
4
+
5
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
6
+ // See LICENSE.txt for license information.
7
+ class DeletePostModal {
8
+ container;
9
+ confirmButton;
10
+ constructor(container) {
11
+ this.container = container;
12
+ this.confirmButton = container.locator('#deletePostModalButton');
13
+ }
14
+ async toBeVisible() {
15
+ await test.expect(this.container).toBeVisible();
16
+ }
17
+ async confirm() {
18
+ await this.confirmButton.waitFor();
19
+ await this.confirmButton.click();
20
+ // Wait for the modal to disappear
21
+ await test.expect(this.container).not.toBeVisible();
22
+ }
23
+ }
24
+
25
+ module.exports = DeletePostModal;
26
+ //# sourceMappingURL=delete_post_modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete_post_modal.js","sources":["../../../../src/ui/components/channels/delete_post_modal.ts"],"sourcesContent":["// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\nimport {Locator, expect} from '@playwright/test';\n\nexport default class DeletePostModal {\n readonly container: Locator;\n readonly confirmButton: Locator;\n\n constructor(container: Locator) {\n this.container = container;\n this.confirmButton = container.locator('#deletePostModalButton');\n }\n\n async toBeVisible() {\n await expect(this.container).toBeVisible();\n }\n\n async confirm() {\n await this.confirmButton.waitFor();\n await this.confirmButton.click();\n\n // Wait for the modal to disappear\n await expect(this.container).not.toBeVisible();\n }\n}\n"],"names":["expect"],"mappings":";;;;AAAA;AACA;AAIc,MAAO,eAAe,CAAA;AACvB,IAAA,SAAS;AACT,IAAA,aAAa;AAEtB,IAAA,WAAA,CAAY,SAAkB,EAAA;AAC1B,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS;QAC1B,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,wBAAwB,CAAC;;AAGpE,IAAA,MAAM,WAAW,GAAA;QACb,MAAMA,WAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;;AAG9C,IAAA,MAAM,OAAO,GAAA;AACT,QAAA,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE;AAClC,QAAA,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;;QAGhC,MAAMA,WAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE;;AAErD;;;;"}
@@ -0,0 +1,16 @@
1
+ import { Locator } from '@playwright/test';
2
+ export default class EmojiGifPicker {
3
+ readonly container: Locator;
4
+ readonly gifTab: Locator;
5
+ readonly gifSearchInput: Locator;
6
+ readonly gifPickerItems: Locator;
7
+ constructor(container: Locator);
8
+ toBeVisible(): Promise<void>;
9
+ openGifTab(): Promise<void>;
10
+ searchGif(name: string): Promise<void>;
11
+ getNthGif(n: number): Promise<{
12
+ src: string;
13
+ alt: string;
14
+ img: Locator;
15
+ }>;
16
+ }