@momentum-design/components 0.0.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.
Files changed (235) hide show
  1. package/.eslintrc.js +16 -0
  2. package/CONTRIBUTING.md +5 -0
  3. package/README.md +39 -0
  4. package/SCRIPTS.md +15 -0
  5. package/TESTING.md +38 -0
  6. package/config/api-extractor.json +33 -0
  7. package/config/custom-elements-manifest.config.js +28 -0
  8. package/config/esbuild/configs/browser.js +21 -0
  9. package/config/esbuild/configs/e2e.js +10 -0
  10. package/config/esbuild/esbuild-e2e.config.js +22 -0
  11. package/config/esbuild/esbuild.config.js +9 -0
  12. package/config/playwright/playwright.config.ts +107 -0
  13. package/config/playwright/public/index.css +43 -0
  14. package/config/playwright/public/index.html +26 -0
  15. package/config/playwright/setup/Components.page.ts +163 -0
  16. package/config/playwright/setup/constants.ts +27 -0
  17. package/config/playwright/setup/index.ts +42 -0
  18. package/config/playwright/setup/steps/accessibility.ts +9 -0
  19. package/config/playwright/setup/types.ts +5 -0
  20. package/config/playwright/setup/utils/accessibility.ts +70 -0
  21. package/config/playwright/setup/utils/visual-regression.ts +35 -0
  22. package/config/plop/actions/AddComponent.ts +21 -0
  23. package/config/plop/actions/AddToComponentExports.ts +16 -0
  24. package/config/plop/actions/AddToComponentImports.ts +16 -0
  25. package/config/plop/constants/index.ts +31 -0
  26. package/config/plop/esbuild.config.plop.js +4 -0
  27. package/config/plop/generators/component/index.ts +25 -0
  28. package/config/plop/plopfile.ts +6 -0
  29. package/config/plop/prompts/index.ts +8 -0
  30. package/config/plop/templates/add/component/index.ts.hbs +12 -0
  31. package/config/plop/templates/add/component/{{componentName}}.component.ts.hbs +22 -0
  32. package/config/plop/templates/add/component/{{componentName}}.constants.ts.hbs +5 -0
  33. package/config/plop/templates/add/component/{{componentName}}.e2e-test.ts.hbs +67 -0
  34. package/config/plop/templates/add/component/{{componentName}}.fixtures.ts.hbs +13 -0
  35. package/config/plop/templates/add/component/{{componentName}}.stories.ts.hbs +18 -0
  36. package/config/plop/templates/add/component/{{componentName}}.styles.ts.hbs +8 -0
  37. package/config/plop/tsconfig.plop.json +11 -0
  38. package/config/storybook/MomentumStorybookTheme.js +41 -0
  39. package/config/storybook/main.js +21 -0
  40. package/config/storybook/manager.js +17 -0
  41. package/config/storybook/preview.js +63 -0
  42. package/config/storybook/provider/iconProvider.js +8 -0
  43. package/config/storybook/provider/themeProvider.js +31 -0
  44. package/config/storybook/public/background-graphic.png +0 -0
  45. package/config/storybook/public/fonts/Inter.var.woff2 +0 -0
  46. package/config/storybook/public/momentum-logo.png +0 -0
  47. package/config/storybook/themes/index.js +14 -0
  48. package/config/storybook/themes/themes.css +15 -0
  49. package/data/custom-elements.json +677 -0
  50. package/dist/browser/index.js +366 -0
  51. package/dist/browser/index.js.map +7 -0
  52. package/dist/components/avatar/avatar.component.d.ts +28 -0
  53. package/dist/components/avatar/avatar.component.js +79 -0
  54. package/dist/components/avatar/avatar.constants.d.ts +7 -0
  55. package/dist/components/avatar/avatar.constants.js +14 -0
  56. package/dist/components/avatar/avatar.styles.d.ts +2 -0
  57. package/dist/components/avatar/avatar.styles.js +20 -0
  58. package/dist/components/avatar/avatar.types.d.ts +1 -0
  59. package/dist/components/avatar/avatar.types.js +2 -0
  60. package/dist/components/avatar/index.d.ts +7 -0
  61. package/dist/components/avatar/index.js +7 -0
  62. package/dist/components/badge/badge.component.d.ts +51 -0
  63. package/dist/components/badge/badge.component.js +114 -0
  64. package/dist/components/badge/badge.constants.d.ts +8 -0
  65. package/dist/components/badge/badge.constants.js +15 -0
  66. package/dist/components/badge/badge.styles.d.ts +2 -0
  67. package/dist/components/badge/badge.styles.js +26 -0
  68. package/dist/components/badge/badge.types.d.ts +1 -0
  69. package/dist/components/badge/badge.types.js +2 -0
  70. package/dist/components/badge/index.d.ts +7 -0
  71. package/dist/components/badge/index.js +7 -0
  72. package/dist/components/icon/icon.component.d.ts +63 -0
  73. package/dist/components/icon/icon.component.js +158 -0
  74. package/dist/components/icon/icon.constants.d.ts +6 -0
  75. package/dist/components/icon/icon.constants.js +12 -0
  76. package/dist/components/icon/icon.styles.d.ts +2 -0
  77. package/dist/components/icon/icon.styles.js +15 -0
  78. package/dist/components/icon/icon.utils.d.ts +2 -0
  79. package/dist/components/icon/icon.utils.js +13 -0
  80. package/dist/components/icon/index.d.ts +7 -0
  81. package/dist/components/icon/index.js +7 -0
  82. package/dist/components/iconprovider/iconprovider.component.d.ts +34 -0
  83. package/dist/components/iconprovider/iconprovider.component.js +71 -0
  84. package/dist/components/iconprovider/iconprovider.constants.d.ts +7 -0
  85. package/dist/components/iconprovider/iconprovider.constants.js +14 -0
  86. package/dist/components/iconprovider/iconprovider.context.d.ts +9 -0
  87. package/dist/components/iconprovider/iconprovider.context.js +9 -0
  88. package/dist/components/iconprovider/index.d.ts +7 -0
  89. package/dist/components/iconprovider/index.js +7 -0
  90. package/dist/components/text/fonts.styles.d.ts +1 -0
  91. package/dist/components/text/fonts.styles.js +100 -0
  92. package/dist/components/text/index.d.ts +7 -0
  93. package/dist/components/text/index.js +7 -0
  94. package/dist/components/text/text.component.d.ts +29 -0
  95. package/dist/components/text/text.component.js +41 -0
  96. package/dist/components/text/text.constants.d.ts +9 -0
  97. package/dist/components/text/text.constants.js +28 -0
  98. package/dist/components/text/text.styles.d.ts +2 -0
  99. package/dist/components/text/text.styles.js +17 -0
  100. package/dist/components/text/text.types.d.ts +1 -0
  101. package/dist/components/text/text.types.js +2 -0
  102. package/dist/components/text/text.utils.d.ts +20 -0
  103. package/dist/components/text/text.utils.js +50 -0
  104. package/dist/components/themeprovider/index.d.ts +7 -0
  105. package/dist/components/themeprovider/index.js +7 -0
  106. package/dist/components/themeprovider/themeprovider.component.d.ts +48 -0
  107. package/dist/components/themeprovider/themeprovider.component.js +86 -0
  108. package/dist/components/themeprovider/themeprovider.constants.d.ts +10 -0
  109. package/dist/components/themeprovider/themeprovider.constants.js +31 -0
  110. package/dist/components/themeprovider/themeprovider.context.d.ts +9 -0
  111. package/dist/components/themeprovider/themeprovider.context.js +13 -0
  112. package/dist/components/themeprovider/themeprovider.styles.d.ts +2 -0
  113. package/dist/components/themeprovider/themeprovider.styles.js +13 -0
  114. package/dist/components/themeprovider/themeprovider.types.d.ts +5 -0
  115. package/dist/components/themeprovider/themeprovider.types.js +2 -0
  116. package/dist/components/themeprovider/themeprovider.utils.d.ts +9 -0
  117. package/dist/components/themeprovider/themeprovider.utils.js +10 -0
  118. package/dist/index.d.ts +8 -0
  119. package/dist/index.js +19 -0
  120. package/dist/models/component/component.component.d.ts +38 -0
  121. package/dist/models/component/component.component.js +45 -0
  122. package/dist/models/component/component.types.d.ts +15 -0
  123. package/dist/models/component/component.types.js +2 -0
  124. package/dist/models/component/index.d.ts +3 -0
  125. package/dist/models/component/index.js +5 -0
  126. package/dist/models/index.d.ts +4 -0
  127. package/dist/models/index.js +8 -0
  128. package/dist/models/provider/index.d.ts +2 -0
  129. package/dist/models/provider/index.js +5 -0
  130. package/dist/models/provider/provider.component.d.ts +70 -0
  131. package/dist/models/provider/provider.component.js +56 -0
  132. package/dist/models/provider/provider.styles.d.ts +2 -0
  133. package/dist/models/provider/provider.styles.js +14 -0
  134. package/dist/utils/provider/index.d.ts +13 -0
  135. package/dist/utils/provider/index.js +14 -0
  136. package/dist/utils/styles/index.d.ts +2 -0
  137. package/dist/utils/styles/index.js +14 -0
  138. package/dist/utils/tag-name/constants.d.ts +7 -0
  139. package/dist/utils/tag-name/constants.js +10 -0
  140. package/dist/utils/tag-name/index.d.ts +4 -0
  141. package/dist/utils/tag-name/index.js +10 -0
  142. package/dist/utils/types.d.ts +1 -0
  143. package/dist/utils/types.js +2 -0
  144. package/jest.config.js +3 -0
  145. package/package.json +78 -0
  146. package/scripts/copyFonts.js +31 -0
  147. package/scripts/copyIcons.js +31 -0
  148. package/scripts/copyTokens.js +24 -0
  149. package/src/components/avatar/__screenshots__/mdc-avatar.png +0 -0
  150. package/src/components/avatar/avatar.component.ts +74 -0
  151. package/src/components/avatar/avatar.constants.ts +12 -0
  152. package/src/components/avatar/avatar.e2e-test.ts +70 -0
  153. package/src/components/avatar/avatar.stories.ts +25 -0
  154. package/src/components/avatar/avatar.styles.ts +20 -0
  155. package/src/components/avatar/avatar.types.ts +1 -0
  156. package/src/components/avatar/index.ts +12 -0
  157. package/src/components/badge/__screenshots__/mdc-badge.png +0 -0
  158. package/src/components/badge/badge.component.ts +121 -0
  159. package/src/components/badge/badge.constants.ts +13 -0
  160. package/src/components/badge/badge.e2e-test.ts +68 -0
  161. package/src/components/badge/badge.stories.ts +33 -0
  162. package/src/components/badge/badge.styles.ts +26 -0
  163. package/src/components/badge/badge.types.ts +1 -0
  164. package/src/components/badge/index.ts +12 -0
  165. package/src/components/icon/__screenshots__/mdc-icon-default.png +0 -0
  166. package/src/components/icon/__screenshots__/mdc-icon-scale.png +0 -0
  167. package/src/components/icon/icon.component.ts +155 -0
  168. package/src/components/icon/icon.constants.ts +10 -0
  169. package/src/components/icon/icon.e2e-test.ts +101 -0
  170. package/src/components/icon/icon.stories.ts +34 -0
  171. package/src/components/icon/icon.styles.ts +15 -0
  172. package/src/components/icon/icon.utils.ts +13 -0
  173. package/src/components/icon/index.ts +12 -0
  174. package/src/components/iconprovider/__screenshots__/mdc-iconprovider.png +0 -0
  175. package/src/components/iconprovider/iconprovider.component.ts +76 -0
  176. package/src/components/iconprovider/iconprovider.constants.ts +12 -0
  177. package/src/components/iconprovider/iconprovider.context.ts +16 -0
  178. package/src/components/iconprovider/iconprovider.e2e-test.ts +65 -0
  179. package/src/components/iconprovider/iconprovider.stories.ts +27 -0
  180. package/src/components/iconprovider/iconprovider.stories.utils.ts +27 -0
  181. package/src/components/iconprovider/index.ts +12 -0
  182. package/src/components/text/__screenshots__/mdc-text-body-large.png +0 -0
  183. package/src/components/text/__screenshots__/mdc-text-body-regular.png +0 -0
  184. package/src/components/text/__screenshots__/mdc-text-body-small.png +0 -0
  185. package/src/components/text/__screenshots__/mdc-text-heading-1.png +0 -0
  186. package/src/components/text/__screenshots__/mdc-text-heading-2.png +0 -0
  187. package/src/components/text/__screenshots__/mdc-text-heading-3.png +0 -0
  188. package/src/components/text/__screenshots__/mdc-text-heading-4.png +0 -0
  189. package/src/components/text/__screenshots__/mdc-text-heading-5.png +0 -0
  190. package/src/components/text/__screenshots__/mdc-text-heading-6.png +0 -0
  191. package/src/components/text/__screenshots__/mdc-text-heading-7.png +0 -0
  192. package/src/components/text/__screenshots__/mdc-text-image-title.png +0 -0
  193. package/src/components/text/__screenshots__/mdc-text-label.png +0 -0
  194. package/src/components/text/fonts.styles.ts +99 -0
  195. package/src/components/text/index.ts +12 -0
  196. package/src/components/text/text.component.ts +51 -0
  197. package/src/components/text/text.constants.ts +27 -0
  198. package/src/components/text/text.e2e-test.ts +76 -0
  199. package/src/components/text/text.stories.ts +29 -0
  200. package/src/components/text/text.styles.ts +17 -0
  201. package/src/components/text/text.types.ts +13 -0
  202. package/src/components/text/text.utils.ts +51 -0
  203. package/src/components/themeprovider/__screenshots__/mdc-themeprovider-darkWebex.png +0 -0
  204. package/src/components/themeprovider/__screenshots__/mdc-themeprovider-lightWebex.png +0 -0
  205. package/src/components/themeprovider/index.ts +12 -0
  206. package/src/components/themeprovider/themeprovider.component.ts +91 -0
  207. package/src/components/themeprovider/themeprovider.constants.ts +32 -0
  208. package/src/components/themeprovider/themeprovider.context.ts +18 -0
  209. package/src/components/themeprovider/themeprovider.e2e-test.ts +89 -0
  210. package/src/components/themeprovider/themeprovider.stories.styles.css +22 -0
  211. package/src/components/themeprovider/themeprovider.stories.ts +38 -0
  212. package/src/components/themeprovider/themeprovider.stories.utils.ts +23 -0
  213. package/src/components/themeprovider/themeprovider.styles.ts +13 -0
  214. package/src/components/themeprovider/themeprovider.types.ts +7 -0
  215. package/src/components/themeprovider/themeprovider.utils.ts +16 -0
  216. package/src/index.ts +22 -0
  217. package/src/models/component/component.component.ts +46 -0
  218. package/src/models/component/component.types.ts +16 -0
  219. package/src/models/component/index.ts +7 -0
  220. package/src/models/index.ts +11 -0
  221. package/src/models/provider/index.ts +3 -0
  222. package/src/models/provider/provider.component.ts +87 -0
  223. package/src/models/provider/provider.styles.ts +14 -0
  224. package/src/stories/colors.mdx +32 -0
  225. package/src/stories/icons.mdx +13 -0
  226. package/src/stories/typography.mdx +20 -0
  227. package/src/utils/mixins/DisabledMixin.ts +19 -0
  228. package/src/utils/mixins/TabIndexMixin.ts +19 -0
  229. package/src/utils/provider/index.ts +21 -0
  230. package/src/utils/styles/index.ts +13 -0
  231. package/src/utils/tag-name/constants.ts +10 -0
  232. package/src/utils/tag-name/index.ts +15 -0
  233. package/src/utils/types.ts +1 -0
  234. package/tsconfig.json +45 -0
  235. package/tsconfig.module.json +47 -0
package/.eslintrc.js ADDED
@@ -0,0 +1,16 @@
1
+ const config = require('../../../.eslintrc.js');
2
+
3
+ module.exports = {
4
+ ...config,
5
+ extends: [
6
+ ...config.extends,
7
+ 'plugin:lit/recommended',
8
+ ],
9
+ parserOptions: { project: './tsconfig.json' },
10
+ rules: {
11
+ ...config.rules,
12
+ '@typescript-eslint/no-floating-promises': 'error',
13
+ 'no-redeclare': 'off',
14
+ 'implicit-arrow-linebreak': 'off',
15
+ },
16
+ };
@@ -0,0 +1,5 @@
1
+ # @momentum-design/components - Contributing Guide
2
+
3
+ ## Contributing
4
+
5
+ This component package was generated with a script, please report any issues.
package/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # @momentum-design/components
2
+
3
+ [![license: mit](https://img.shields.io/badge/License-MIT-blueviolet?style=flat-square)](https://github.com/momentum-design/momentum-design/blob/main/LICENSE)
4
+ ![State](https://img.shields.io/badge/State-Alpha-blue?style=flat-square)
5
+
6
+ ## Overview
7
+
8
+ This package is Work In Progress - there is no guarantee for consistency, stability till properly released.
9
+ There will be breaking changes coming up - it is not recommended to consume this package in this early stage.
10
+
11
+ ## Steps to run this package
12
+
13
+ - Follow the steps mentioned in the [first time setup](https://github.com/momentum-design/momentum-design/blob/main/CONTRIBUTING.md#first-time-setup).
14
+ - Build all dependencies to run components package
15
+ ```
16
+ yarn telemetry build
17
+ yarn token-builder build
18
+ yarn tokens build
19
+ yarn common build
20
+ yarn builder build
21
+ yarn fonts build
22
+ yarn icons build
23
+ ```
24
+ - Run this to start storybook and develop components
25
+ ```
26
+ yarn components dev
27
+ ```
28
+
29
+ ## Contributing
30
+
31
+ See [our contributing guide](./CONTRIBUTING.md)
32
+
33
+ ## Scripts
34
+
35
+ See [our script documentation](./SCRIPTS.md)
36
+
37
+ ## Testing
38
+
39
+ See [our testing documentation](./TESTING.md)
package/SCRIPTS.md ADDED
@@ -0,0 +1,15 @@
1
+ # @momentum-design/components - Scripts Guide
2
+
3
+ ## Scripts
4
+
5
+ ### dev
6
+ - Run the Components Development tool locally
7
+
8
+ ### build
9
+ - Builds to ./dist for export - only `dist` folder is published to NPM
10
+
11
+ ### test
12
+ - Executes all tests
13
+
14
+ ### analyze
15
+ - Runs linting and typescript, as well as all other static analysis scripts
package/TESTING.md ADDED
@@ -0,0 +1,38 @@
1
+ # Testing
2
+
3
+ ## Unit Testing
4
+
5
+ ## E2E Testing
6
+
7
+ Testing of the mounted, built component in real browsers.
8
+ E2E Testing is done with the help of [Playwright](https://playwright.dev/).
9
+
10
+ ### Scope
11
+
12
+ * Testing visual consistency of a component
13
+ * Does the component display correctly in x browser (consistency and responsiveness)?
14
+ * Does the components functions work correctly in x browser?
15
+ * Is the component accessible in x browser?
16
+ * Are interactions with the component working as expected in x browser?
17
+
18
+ ### Browser List to test
19
+
20
+ * Chrome
21
+ * Firefox
22
+ * Edge
23
+ * Safari/webkit
24
+
25
+ ### Local development
26
+
27
+ For the best local development experience, the following E2E setup testing is recommended:
28
+
29
+ 1. Open 2 terminals
30
+ 2. In the first terminal, run `yarn components test:e2e:setup`
31
+ * This will spin up the local dev environment with dev server
32
+ * Wait till a `Serving!` message appears
33
+ 3. In the second terminal, run `yarn components test:e2e`
34
+ * This allows to run all E2E tests
35
+ * To run a specific E2E test, run `yarn components test:e2e XXX.e2e-test.ts`
36
+ * To run the tests in `headed mode`, run `yarn components test:e2e -- --headed`
37
+
38
+ You can keep the first terminal open, while running/developing E2E tests in the second terminal.
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Config file for API Extractor. For more info, please visit: https://api-extractor.com
3
+ */
4
+ {
5
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
6
+
7
+ /**
8
+ * Optionally specifies another JSON config file that this file extends from. This provides a way for
9
+ * standard settings to be shared across multiple projects.
10
+ *
11
+ * If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains
12
+ * the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be
13
+ * resolved using NodeJS require().
14
+ *
15
+ * SUPPORTED TOKENS: none
16
+ * DEFAULT VALUE: ""
17
+ */
18
+ "extends": "../../../../config/api-extractor/api-extractor-base.json",
19
+
20
+
21
+ /**
22
+ * (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor
23
+ * analyzes the symbols exported by this module.
24
+ *
25
+ * The file extension must be ".d.ts" and not ".ts".
26
+ *
27
+ * The path is resolved relative to the folder of the config file that contains the setting; to change this,
28
+ * prepend a folder token such as "<projectFolder>".
29
+ *
30
+ * SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
31
+ */
32
+ "mainEntryPointFilePath": "<projectFolder>/dist/index.d.ts"
33
+ }
@@ -0,0 +1,28 @@
1
+ module.exports = {
2
+ /** Globs to analyze */
3
+ globs: ['src/components/**/*.component.ts'],
4
+ /** Globs to exclude */
5
+ exclude: [
6
+ '*.js',
7
+ ],
8
+ /** Directory to output CEM to */
9
+ outdir: 'data',
10
+ /** Run in dev mode, provides extra logging */
11
+ dev: false,
12
+ /** Run in watch mode, runs on file changes */
13
+ watch: true,
14
+ /** Include third party custom elements manifests */
15
+ dependencies: false,
16
+ /** Output CEM path to `package.json`, defaults to true */
17
+ packagejson: false,
18
+ /** Enable special handling for litelement */
19
+ litelement: true,
20
+ /** Enable special handling for catalyst */
21
+ catalyst: false,
22
+ /** Enable special handling for fast */
23
+ fast: false,
24
+ /** Enable special handling for stencil */
25
+ stencil: false,
26
+ /** Provide custom plugins */
27
+ plugins: [],
28
+ };
@@ -0,0 +1,21 @@
1
+ const { join } = require('path');
2
+
3
+ const projectPath = process.cwd();
4
+ const outPath = join('dist', 'browser', 'index.js');
5
+
6
+ // todo: define browser targets here:
7
+ const browsers = ['chrome114', 'firefox114'];
8
+
9
+ const buildConfig = {
10
+ bundle: true,
11
+ entryPoints: [`${join(projectPath, 'src', 'index.ts')}`],
12
+ minify: true,
13
+ sourcemap: true,
14
+ outfile: `${join(projectPath, outPath)}`,
15
+ target: browsers,
16
+ };
17
+
18
+ module.exports = {
19
+ config: buildConfig,
20
+ outPath,
21
+ };
@@ -0,0 +1,10 @@
1
+ const { join } = require('path');
2
+
3
+ const projectPath = process.cwd();
4
+ const publicPath = join(projectPath, 'config', 'playwright', 'public');
5
+ const port = 4000;
6
+
7
+ module.exports = {
8
+ publicPath,
9
+ port,
10
+ };
@@ -0,0 +1,22 @@
1
+ /* eslint-disable @typescript-eslint/no-floating-promises */
2
+ const esbuild = require('esbuild');
3
+ const chalk = require('chalk');
4
+ const { join } = require('path');
5
+ const { config, outPath } = require('./configs/browser');
6
+ const { publicPath, port } = require('./configs/e2e');
7
+
8
+ const iife = async () => {
9
+ const ctx = await esbuild.context({
10
+ ...config,
11
+ outfile: `${join(publicPath, outPath)}`,
12
+ });
13
+
14
+ await ctx.watch();
15
+ await ctx.serve({
16
+ servedir: publicPath,
17
+ port,
18
+ });
19
+ console.log(chalk.cyan('Serving at http://localhost:4000'));
20
+ };
21
+
22
+ iife();
@@ -0,0 +1,9 @@
1
+ /* eslint-disable @typescript-eslint/no-floating-promises */
2
+ const esbuild = require('esbuild');
3
+ const { config } = require('./configs/browser');
4
+
5
+ const iife = async () => {
6
+ await esbuild.build(config);
7
+ };
8
+
9
+ iife();
@@ -0,0 +1,107 @@
1
+ import type { PlaywrightTestConfig } from '@playwright/test';
2
+ import { devices } from '@playwright/test';
3
+ import { port } from '../esbuild/configs/e2e';
4
+ /**
5
+ * Read environment variables from file.
6
+ * https://github.com/motdotla/dotenv
7
+ */
8
+ // require('dotenv').config();
9
+
10
+ const url = `http://localhost:${port}`;
11
+
12
+ /**
13
+ * See https://playwright.dev/docs/test-configuration.
14
+ */
15
+ const config: PlaywrightTestConfig = {
16
+ testDir: '../../src',
17
+ testMatch: /.*\.e2e-test\.ts/,
18
+ /* Maximum time one test can run for. */
19
+ timeout: 30 * 1000,
20
+ expect: {
21
+ /**
22
+ * Maximum time expect() should wait for the condition to be met.
23
+ * For example in `await expect(locator).toHaveText();`
24
+ */
25
+ timeout: 5000,
26
+ },
27
+ /* Run tests in files in parallel */
28
+ fullyParallel: true,
29
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
30
+ forbidOnly: !!process.env.CI,
31
+ /* Retry on CI only */
32
+ retries: process.env.CI ? 2 : 0,
33
+ /* Opt out of parallel tests on CI. */
34
+ workers: process.env.CI ? 1 : undefined,
35
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
36
+ reporter: 'html',
37
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
38
+ use: {
39
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
40
+ actionTimeout: 0,
41
+ /* Base URL to use in actions like `await page.goto('/')`. */
42
+ baseURL: url,
43
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
44
+ trace: 'retain-on-failure',
45
+ },
46
+
47
+ snapshotPathTemplate: '{testDir}/{testFileDir}/__screenshots__/{arg}{ext}',
48
+
49
+ /* Configure projects for major browsers */
50
+ projects: [
51
+ {
52
+ name: 'Google Chrome',
53
+ use: {
54
+ ...devices['Desktop Chrome'],
55
+ channel: 'chrome',
56
+ },
57
+ },
58
+ // {
59
+ // name: 'firefox',
60
+ // use: {
61
+ // ...devices['Desktop Firefox'],
62
+ // },
63
+ // },
64
+
65
+ // {
66
+ // name: 'webkit',
67
+ // use: {
68
+ // ...devices['Desktop Safari'],
69
+ // },
70
+ // },
71
+
72
+ /* Test against mobile viewports. */
73
+ // {
74
+ // name: 'Mobile Chrome',
75
+ // use: {
76
+ // ...devices['Pixel 5'],
77
+ // },
78
+ // },
79
+ // {
80
+ // name: 'Mobile Safari',
81
+ // use: {
82
+ // ...devices['iPhone 12'],
83
+ // },
84
+ // },
85
+
86
+ /* Test against branded browsers. */
87
+ // {
88
+ // name: 'Microsoft Edge',
89
+ // use: {
90
+ // channel: 'msedge',
91
+ // },
92
+ // },
93
+ ],
94
+
95
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
96
+ outputDir: 'test-results/',
97
+
98
+ /* Run your local dev server before starting the tests */
99
+ webServer: {
100
+ command: 'yarn test:e2e:setup',
101
+ url,
102
+ timeout: 240 * 1000,
103
+ reuseExistingServer: true,
104
+ },
105
+ };
106
+
107
+ export default config;
@@ -0,0 +1,43 @@
1
+ @font-face {
2
+ font-family: "Momentum";
3
+ src: url("/dist/fonts/Inter.var.woff2") format("woff2");
4
+ }
5
+
6
+ body {
7
+ position: fixed;
8
+ height: 100%;
9
+ width: 100%;
10
+ margin: 0;
11
+ padding: 0;
12
+ }
13
+
14
+ #root {
15
+ height: 100%;
16
+ width: 100%;
17
+ background: var(--mds-color-theme-background-solid-primary-normal);
18
+ }
19
+
20
+ .themeWrapper {
21
+ display: flex;
22
+ flex-direction: column;
23
+ width: calc(30%);
24
+ height: auto;
25
+ background: var(--mds-color-theme-background-solid-primary-normal);
26
+ color: var(--mds-color-theme-text-primary-normal);
27
+ padding: 10px;
28
+ border: 1px solid var(--mds-color-theme-text-primary-normal)
29
+ }
30
+
31
+ .themeWrapper+.themeWrapper {
32
+ margin-top: 10px;
33
+ }
34
+
35
+ .colorBox {
36
+ width: 100%;
37
+ height: 10px;
38
+ border-radius: 5px;
39
+ }
40
+
41
+ .colorBox+.colorBox {
42
+ margin-top: 10px;
43
+ }
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <title>Momentum Components Dev Page</title>
9
+ <script type="module" src="/dist/browser/index.js"></script>
10
+ <link rel="stylesheet" href="index.css">
11
+ <link rel="stylesheet" href="/dist/complete.css">
12
+ <link rel="stylesheet" href="/dist/dark-stable.css">
13
+ <link rel="stylesheet" href="/dist/light-stable.css">
14
+ </head>
15
+
16
+ <body>
17
+ <mdc-themeprovider theme="mds-theme-stable-darkWebex"
18
+ themes="mds-theme-stable-darkWebex mds-theme-stable-lightWebex">
19
+ <mdc-iconprovider url="/dist/icons/svg">
20
+ <div id="root">
21
+ </div>
22
+ </mdc-iconprovider>
23
+ </mdc-themeprovider>
24
+ </body>
25
+
26
+ </html>
@@ -0,0 +1,163 @@
1
+ /* eslint-disable no-redeclare */
2
+ import { Page, expect, Locator, TestInfo } from '@playwright/test';
3
+ import type { ThemeName } from '../../../src/components/themeprovider/themeprovider.types';
4
+ import utils from '../../../src/components/themeprovider/themeprovider.utils';
5
+ import Accessibility from './utils/accessibility';
6
+ import VisualRegression from './utils/visual-regression';
7
+
8
+ const componentsDevPageTitle = 'Momentum Components Dev Page';
9
+ const htmlRootElementSelector = '#root';
10
+
11
+ interface MountOptions {
12
+ html: string;
13
+ clearDocument?: boolean;
14
+ }
15
+
16
+ interface ComponentsPage {
17
+ accessibility: Accessibility;
18
+ visualRegression: VisualRegression;
19
+ page: Page;
20
+ testInfo: TestInfo
21
+ }
22
+
23
+ /**
24
+ * Components Page Object Model
25
+ *
26
+ * This object model includes basic functionalities like setup, teardown, mount, etc.
27
+ * used for Momentum components E2E testing
28
+ */
29
+ class ComponentsPage {
30
+ constructor(page: Page, testInfo: TestInfo) {
31
+ this.page = page;
32
+ this.testInfo = testInfo;
33
+
34
+ // creates utility objects on components page and inject dependencies:
35
+ this.accessibility = new Accessibility(this.page, this.testInfo);
36
+ this.visualRegression = new VisualRegression(this.page);
37
+ }
38
+
39
+ /**
40
+ * Sets the theme on the global theme provider
41
+ * for e2e tests. This allows testing
42
+ * with specified themes.
43
+ * @param theme - themeName to be used for setting theme on themeprovider
44
+ */
45
+ async setGlobalTheme(theme: ThemeName) {
46
+ const themeClass = utils.getFullQualifiedTheme(theme);
47
+ await this.page.evaluate(
48
+ (args) => {
49
+ const themeProvider = window.document.querySelector('body mdc-themeprovider');
50
+ if (themeProvider) {
51
+ themeProvider.setAttribute('theme', args.themeClass);
52
+ }
53
+ },
54
+ { themeClass },
55
+ );
56
+ }
57
+
58
+ /**
59
+ * **Setup function**
60
+ *
61
+ * to run before the test to navigate correctly
62
+ */
63
+ async setup() {
64
+ await this.navigate();
65
+ }
66
+
67
+ /**
68
+ * **TearDown function**
69
+ *
70
+ * to run after the test
71
+ */
72
+ async tearDown() {
73
+ await this.page.close();
74
+ }
75
+
76
+ /**
77
+ * **Navigate function**
78
+ *
79
+ * Path urls are allowed
80
+ *
81
+ * If no url provided, it navigates to baseURL
82
+ *
83
+ * - Go to the provided url
84
+ * - Await till page has been loaded
85
+ */
86
+ async navigate(url?: string) {
87
+ await this.page.goto(url || '');
88
+ await expect(this.page).toHaveTitle(componentsDevPageTitle);
89
+ }
90
+
91
+ /**
92
+ * Mount a html string to the index.html which gets displayed
93
+ *
94
+ * @param options - a object with options, including the `html` string to mount
95
+ */
96
+ async mount({ html, clearDocument = false }: MountOptions) {
97
+ await this.page.evaluate(
98
+ (args) => {
99
+ function htmlToElement(htmlString: string): Element {
100
+ const template = document.createElement('template');
101
+ template.innerHTML = htmlString.trim();
102
+ return template.content.firstChild as Element;
103
+ }
104
+ const rootElement = window.document.querySelector(args.htmlRootElementSelector);
105
+ if (rootElement) {
106
+ // delete children of textContent before mounting the passed in html:
107
+ if (args.clearDocument) {
108
+ rootElement.textContent = '';
109
+ }
110
+ rootElement.appendChild(htmlToElement(args.html));
111
+ }
112
+ },
113
+ { html, htmlRootElementSelector, clearDocument },
114
+ );
115
+ }
116
+
117
+ /**
118
+ * Wait for the event `eventName` to be fired on a HTMLElement, queried by the passed in `locator`
119
+ * @param locator - Playwright locator
120
+ * @param eventName - eventName to wait for to be fired on queried HTMLElement
121
+ * @returns Promise, which resolves when event `eventName` gets fired
122
+ */
123
+ async waitForEvent(locator: Locator, eventName: string) {
124
+ return locator.evaluate(
125
+ (element: HTMLElement, args) => new Promise((resolve: (value?: unknown) => void) => {
126
+ element.addEventListener(args.eventName, () => {
127
+ resolve();
128
+ });
129
+ }),
130
+ { eventName },
131
+ );
132
+ }
133
+
134
+ /**
135
+ * Set a attribute on a HTMLElement, queried by the passed in `locator`
136
+ * @param locator - Playwright locator
137
+ * @param qualifiedName - qualifiedName of the attribute to be set
138
+ * @param value - value of the attribute to be set
139
+ */
140
+ async setAttribute(locator: Locator, qualifiedName: string, value: any) {
141
+ await locator.evaluate(
142
+ (element: HTMLElement, args) => {
143
+ element.setAttribute(args.qualifiedName, args.value);
144
+ },
145
+ { qualifiedName, value },
146
+ );
147
+ }
148
+
149
+ /**
150
+ * Remove a attribute of a HTMLElement, queried by the passed in `locator`
151
+ * @param locator - Playwright locator
152
+ * @param qualifiedName - qualifiedName of the attribute to be removed
153
+ */
154
+ async removeAttribute(locator: Locator, qualifiedName: string) {
155
+ await locator.evaluate(
156
+ (element: HTMLElement, args) => {
157
+ element.removeAttribute(args.qualifiedName);
158
+ },
159
+ { qualifiedName },
160
+ );
161
+ }
162
+ }
163
+ export default ComponentsPage;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Accessibility constants
3
+ *
4
+ * WCAG_TAGS_TO_CHECK which should be checked,
5
+ * see full list here (Axe-core Tags): https://www.deque.com/axe/core-documentation/api-documentation/#axe-core-tags
6
+ * Note: WCAG Tags are cummulative, such that when confirming WCAG 2.2 AA,
7
+ * the less strict tags have to be added as well, like wcag2a, wcag2aa, wcag21aa
8
+ *
9
+ * RULES_TO_DISABLE which should not be checked,
10
+ * see full list here: https://github.com/dequelabs/axe-core/blob/master/doc/rule-descriptions.md
11
+ */
12
+ const ACCESSIBILITY = {
13
+ WCAG_TAGS_TO_CHECK: ['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'],
14
+ RULES_TO_DISABLE: [],
15
+ };
16
+
17
+ const VISUAL_REGRESSION = {
18
+ THRESHOLD: 0,
19
+ MAX_DIFF_PIXELS_RATIO: 0.03,
20
+ FILE_EXTENSION: 'png',
21
+ };
22
+
23
+ const CONSTANTS = {
24
+ ACCESSIBILITY,
25
+ VISUAL_REGRESSION,
26
+ };
27
+ export default CONSTANTS;
@@ -0,0 +1,42 @@
1
+ import { test as base } from '@playwright/test';
2
+ import { THEME_NAMES } from '../../../src/components/themeprovider/themeprovider.constants';
3
+ import type { ThemeName } from '../../../src/components/themeprovider/themeprovider.types';
4
+ import ComponentsPage from './Components.page';
5
+
6
+ type Options = {
7
+ /**
8
+ * Theme to choose
9
+ */
10
+ theme: ThemeName
11
+ };
12
+
13
+ type Fixtures = {
14
+ /**
15
+ * componentsPage fixture - to be used to group momentum e2e utils
16
+ */
17
+ componentsPage: ComponentsPage;
18
+ };
19
+
20
+ // Extend base test by providing our fixtures based on Page Object Models
21
+ // This new "test" can be used in multiple test files, and each of them will get the fixtures.
22
+ export const test = base.extend<Fixtures & Options>({
23
+ theme: [THEME_NAMES.DARK_WEBEX, { option: true }],
24
+
25
+ componentsPage: async ({ page, theme }, use, testInfo) => {
26
+ const componentsPage = new ComponentsPage(page, testInfo);
27
+
28
+ if (theme) {
29
+ await componentsPage.setGlobalTheme(theme);
30
+ }
31
+ // navigate to the baseURL at the beginning
32
+ await componentsPage.setup();
33
+
34
+ // Use the fixture value in the test:
35
+ await use(componentsPage);
36
+
37
+ // Clean up at the end of the test:
38
+ await componentsPage.tearDown();
39
+ },
40
+ });
41
+
42
+ export { ComponentsPage };
@@ -0,0 +1,9 @@
1
+ import { ComponentsPage, test } from '..';
2
+
3
+ const automaticA11yCheckStep = (componentsPage: ComponentsPage) => test.step('check for A11y violations', async () => {
4
+ await componentsPage.accessibility.checkForA11yViolations();
5
+ });
6
+
7
+ export default {
8
+ automaticA11yCheckStep,
9
+ };
@@ -0,0 +1,5 @@
1
+ import { Locator, PageScreenshotOptions } from '@playwright/test';
2
+
3
+ export type ScreenShotOptions = PageScreenshotOptions & {
4
+ element?: Locator;
5
+ };