dceky 1.0.0-beta.5 → 1.0.2

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 (199) hide show
  1. package/.eslintrc.js +93 -0
  2. package/README.md +41 -0
  3. package/cypress/e2e/profile-test.cy.ts +10 -0
  4. package/cypress/fixtures/example.json +5 -0
  5. package/cypress/support/commands.ts +37 -0
  6. package/cypress/support/e2e.ts +17 -0
  7. package/cypress.config.ts +9 -0
  8. package/docs/GlobalsAndProfiles.md +23 -0
  9. package/lib/setup/addToGitIgnore.d.ts +6 -0
  10. package/lib/setup/addToGitIgnore.js +46 -0
  11. package/lib/setup/addToGitIgnore.js.map +1 -0
  12. package/lib/setup/checkRequiredFiles.d.ts +6 -0
  13. package/lib/setup/checkRequiredFiles.js +58 -0
  14. package/lib/setup/checkRequiredFiles.js.map +1 -0
  15. package/lib/setup/genCommandImportFile.d.ts +7 -0
  16. package/lib/setup/genCommandImportFile.js +66 -0
  17. package/lib/setup/genCommandImportFile.js.map +1 -0
  18. package/lib/setup/genConfiguration/helpers/resolveDependents.d.ts +13 -0
  19. package/lib/setup/genConfiguration/helpers/resolveDependents.js +50 -0
  20. package/lib/setup/genConfiguration/helpers/resolveDependents.js.map +1 -0
  21. package/lib/setup/genConfiguration/helpers/splitEnv.d.ts +10 -0
  22. package/lib/setup/genConfiguration/helpers/splitEnv.js +27 -0
  23. package/lib/setup/genConfiguration/helpers/splitEnv.js.map +1 -0
  24. package/lib/setup/genConfiguration/index.d.ts +15 -0
  25. package/lib/setup/genConfiguration/index.js +86 -0
  26. package/lib/setup/genConfiguration/index.js.map +1 -0
  27. package/lib/setup/genConfiguration/types/DependentValue.d.ts +11 -0
  28. package/lib/setup/genConfiguration/types/DependentValue.js +3 -0
  29. package/lib/setup/genConfiguration/types/DependentValue.js.map +1 -0
  30. package/lib/setup/genConfiguration/types/GlobalsOrProfile.d.ts +9 -0
  31. package/lib/setup/genConfiguration/types/GlobalsOrProfile.js +3 -0
  32. package/lib/setup/genConfiguration/types/GlobalsOrProfile.js.map +1 -0
  33. package/lib/setup/genConfiguration/types/SplitEnv.d.ts +13 -0
  34. package/lib/setup/genConfiguration/types/SplitEnv.js +3 -0
  35. package/lib/setup/genConfiguration/types/SplitEnv.js.map +1 -0
  36. package/lib/setup/genConfigurationFile.d.ts +2 -0
  37. package/lib/setup/genConfigurationFile.js +63 -0
  38. package/lib/setup/genConfigurationFile.js.map +1 -0
  39. package/lib/setup/genDynamicConfigFile.d.ts +5 -0
  40. package/lib/setup/genDynamicConfigFile.js +28 -0
  41. package/lib/setup/genDynamicConfigFile.js.map +1 -0
  42. package/lib/setup/index.d.ts +1 -0
  43. package/lib/setup/index.js +16 -0
  44. package/lib/setup/index.js.map +1 -0
  45. package/lib/setup/setupCypressDependencies.d.ts +6 -0
  46. package/lib/setup/setupCypressDependencies.js +40 -0
  47. package/lib/setup/setupCypressDependencies.js.map +1 -0
  48. package/lib/src/commands/assertDoesNotHaveClass.d.ts +20 -0
  49. package/lib/src/commands/assertDoesNotHaveClass.js +17 -0
  50. package/lib/src/commands/assertDoesNotHaveClass.js.map +1 -0
  51. package/lib/src/commands/assertHasClass.d.ts +20 -0
  52. package/lib/src/commands/assertHasClass.js +17 -0
  53. package/lib/src/commands/assertHasClass.js.map +1 -0
  54. package/lib/src/commands/assertNumElements.d.ts +19 -0
  55. package/lib/src/commands/assertNumElements.js +17 -0
  56. package/lib/src/commands/assertNumElements.js.map +1 -0
  57. package/lib/src/commands/extractDataFromClass.d.ts +18 -0
  58. package/lib/src/commands/extractDataFromClass.js +25 -0
  59. package/lib/src/commands/extractDataFromClass.js.map +1 -0
  60. package/lib/src/commands/extractDataFromClassByContents.d.ts +19 -0
  61. package/lib/src/commands/extractDataFromClassByContents.js +26 -0
  62. package/lib/src/commands/extractDataFromClassByContents.js.map +1 -0
  63. package/lib/src/commands/getJSON.d.ts +16 -0
  64. package/lib/src/commands/getJSON.js +21 -0
  65. package/lib/src/commands/getJSON.js.map +1 -0
  66. package/lib/src/commands/getNumElements.d.ts +15 -0
  67. package/lib/src/commands/getNumElements.js +19 -0
  68. package/lib/src/commands/getNumElements.js.map +1 -0
  69. package/lib/src/commands/handleHarvardKey.d.ts +15 -0
  70. package/lib/src/commands/handleHarvardKey.js +53 -0
  71. package/lib/src/commands/handleHarvardKey.js.map +1 -0
  72. package/lib/src/commands/launchAs.d.ts +25 -0
  73. package/lib/src/commands/launchAs.js +66 -0
  74. package/lib/src/commands/launchAs.js.map +1 -0
  75. package/lib/src/commands/launchLTIUsingToken.d.ts +21 -0
  76. package/lib/src/commands/launchLTIUsingToken.js +68 -0
  77. package/lib/src/commands/launchLTIUsingToken.js.map +1 -0
  78. package/lib/src/commands/navigateToHref.d.ts +15 -0
  79. package/lib/src/commands/navigateToHref.js +35 -0
  80. package/lib/src/commands/navigateToHref.js.map +1 -0
  81. package/lib/src/commands/runScript.d.ts +15 -0
  82. package/lib/src/commands/runScript.js +20 -0
  83. package/lib/src/commands/runScript.js.map +1 -0
  84. package/lib/src/commands/typeInto.d.ts +24 -0
  85. package/lib/src/commands/typeInto.js +41 -0
  86. package/lib/src/commands/typeInto.js.map +1 -0
  87. package/lib/src/commands/visitCanvasGETEndpoint.d.ts +20 -0
  88. package/lib/src/commands/visitCanvasGETEndpoint.js +26 -0
  89. package/lib/src/commands/visitCanvasGETEndpoint.js.map +1 -0
  90. package/lib/src/commands/waitForElementVisible.d.ts +16 -0
  91. package/lib/src/commands/waitForElementVisible.js +19 -0
  92. package/lib/src/commands/waitForElementVisible.js.map +1 -0
  93. package/lib/src/genConfiguration/helpers/resolveDependents.d.ts +13 -0
  94. package/lib/src/genConfiguration/helpers/resolveDependents.js +50 -0
  95. package/lib/src/genConfiguration/helpers/resolveDependents.js.map +1 -0
  96. package/lib/src/genConfiguration/helpers/splitEnv.d.ts +10 -0
  97. package/lib/src/genConfiguration/helpers/splitEnv.js +27 -0
  98. package/lib/src/genConfiguration/helpers/splitEnv.js.map +1 -0
  99. package/{src/genConfiguration.ts → lib/src/genConfiguration/index.d.ts} +3 -6
  100. package/lib/src/genConfiguration/index.js +88 -0
  101. package/lib/src/genConfiguration/index.js.map +1 -0
  102. package/lib/src/genConfiguration/types/DependentValue.d.ts +11 -0
  103. package/lib/src/genConfiguration/types/DependentValue.js +3 -0
  104. package/lib/src/genConfiguration/types/DependentValue.js.map +1 -0
  105. package/lib/src/genConfiguration/types/GlobalsOrProfile.d.ts +9 -0
  106. package/lib/src/genConfiguration/types/GlobalsOrProfile.js +3 -0
  107. package/lib/src/genConfiguration/types/GlobalsOrProfile.js.map +1 -0
  108. package/lib/src/genConfiguration/types/SplitEnv.d.ts +13 -0
  109. package/lib/src/genConfiguration/types/SplitEnv.js +3 -0
  110. package/lib/src/genConfiguration/types/SplitEnv.js.map +1 -0
  111. package/lib/{index.d.ts → src/index.d.ts} +1 -1
  112. package/lib/{index.js → src/index.js} +6 -3
  113. package/lib/src/index.js.map +1 -0
  114. package/lib/src/init.d.ts +6 -0
  115. package/lib/src/init.js +45 -0
  116. package/lib/src/init.js.map +1 -0
  117. package/lib/start/constants/AVAILABLE_BROWSERS.d.ts +9 -0
  118. package/lib/start/constants/AVAILABLE_BROWSERS.js +27 -0
  119. package/lib/start/constants/AVAILABLE_BROWSERS.js.map +1 -0
  120. package/lib/start/helpers/exec.d.ts +8 -0
  121. package/lib/start/helpers/exec.js +18 -0
  122. package/lib/start/helpers/exec.js.map +1 -0
  123. package/lib/start/helpers/extractArgValue.d.ts +10 -0
  124. package/lib/start/helpers/extractArgValue.js +39 -0
  125. package/lib/start/helpers/extractArgValue.js.map +1 -0
  126. package/lib/start/helpers/findProfilesByNames.d.ts +16 -0
  127. package/lib/start/helpers/findProfilesByNames.js +35 -0
  128. package/lib/start/helpers/findProfilesByNames.js.map +1 -0
  129. package/lib/start/helpers/parseCommaSeparated.d.ts +8 -0
  130. package/lib/start/helpers/parseCommaSeparated.js +23 -0
  131. package/lib/start/helpers/parseCommaSeparated.js.map +1 -0
  132. package/lib/start/helpers/print.d.ts +38 -0
  133. package/lib/start/helpers/print.js +145 -0
  134. package/lib/start/helpers/print.js.map +1 -0
  135. package/lib/start/helpers/prompt.d.ts +8 -0
  136. package/lib/start/helpers/prompt.js +25 -0
  137. package/lib/start/helpers/prompt.js.map +1 -0
  138. package/lib/start/helpers/showChooser.d.ts +21 -0
  139. package/lib/start/helpers/showChooser.js +116 -0
  140. package/lib/start/helpers/showChooser.js.map +1 -0
  141. package/lib/start/helpers/validateBrowsers.d.ts +8 -0
  142. package/lib/start/helpers/validateBrowsers.js +36 -0
  143. package/lib/start/helpers/validateBrowsers.js.map +1 -0
  144. package/lib/start/index.d.ts +7 -0
  145. package/lib/start/index.js +139 -0
  146. package/lib/start/index.js.map +1 -0
  147. package/lib/start/types/ChooserOption.d.ts +10 -0
  148. package/lib/start/types/ChooserOption.js +3 -0
  149. package/lib/start/types/ChooserOption.js.map +1 -0
  150. package/package.json +28 -8
  151. package/setup/addToGitIgnore.ts +47 -0
  152. package/setup/checkRequiredFiles.ts +62 -0
  153. package/setup/genCommandImportFile.ts +75 -0
  154. package/setup/genDynamicConfigFile.ts +28 -0
  155. package/setup/index.ts +11 -0
  156. package/setup/setupCypressDependencies.ts +38 -0
  157. package/src/commands/assertDoesNotHaveClass.ts +51 -0
  158. package/src/commands/assertHasClass.ts +51 -0
  159. package/src/commands/assertNumElements.ts +50 -0
  160. package/src/commands/extractDataFromClass.ts +52 -0
  161. package/src/commands/extractDataFromClassByContents.ts +55 -0
  162. package/src/commands/getJSON.ts +45 -0
  163. package/src/commands/getNumElements.ts +45 -0
  164. package/src/commands/handleHarvardKey.ts +91 -0
  165. package/src/commands/launchAs.ts +120 -0
  166. package/src/commands/launchLTIUsingToken.ts +115 -0
  167. package/src/commands/navigateToHref.ts +60 -0
  168. package/src/commands/runScript.ts +44 -0
  169. package/src/commands/typeInto.ts +88 -0
  170. package/src/commands/visitCanvasGETEndpoint.ts +61 -0
  171. package/src/commands/waitForElementVisible.ts +49 -0
  172. package/src/genConfiguration/helpers/resolveDependents.ts +47 -0
  173. package/src/genConfiguration/helpers/splitEnv.ts +30 -0
  174. package/src/genConfiguration/index.ts +94 -0
  175. package/src/genConfiguration/types/DependentValue.ts +14 -0
  176. package/src/genConfiguration/types/GlobalsOrProfile.ts +12 -0
  177. package/src/genConfiguration/types/SplitEnv.ts +18 -0
  178. package/src/index.ts +7 -4
  179. package/src/init.ts +36 -27
  180. package/start/constants/AVAILABLE_BROWSERS.ts +28 -0
  181. package/start/helpers/exec.ts +17 -0
  182. package/start/helpers/extractArgValue.ts +42 -0
  183. package/start/helpers/findProfilesByNames.ts +39 -0
  184. package/start/helpers/parseCommaSeparated.ts +23 -0
  185. package/start/helpers/print.ts +155 -0
  186. package/start/helpers/prompt.ts +23 -0
  187. package/start/helpers/showChooser.ts +140 -0
  188. package/start/helpers/validateBrowsers.ts +35 -0
  189. package/start/index.ts +163 -0
  190. package/start/types/ChooserOption.ts +11 -0
  191. package/tsconfig.json +3 -4
  192. package/.eslintrc.json +0 -58
  193. package/lib/genConfiguration.d.ts +0 -8
  194. package/lib/genConfiguration.js +0 -13
  195. package/lib/genConfiguration.js.map +0 -1
  196. package/lib/index.js.map +0 -1
  197. package/lib/init.d.ts +0 -13
  198. package/lib/init.js +0 -19
  199. package/lib/init.js.map +0 -1
@@ -0,0 +1,47 @@
1
+ /* eslint-disable no-console */
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
3
+ import path from 'path';
4
+
5
+ /**
6
+ * Ensure gitignore includes the necessary entries for Cypress results
7
+ * @author Yuen Ler Chow
8
+ */
9
+ const addToGitIgnore = (): void => {
10
+ const root = path.join(__dirname, '../..');
11
+
12
+ const gitignorePath = path.join(root, '.gitignore');
13
+
14
+ const entries = [
15
+ 'cypress-results/',
16
+ 'cypress/downloads',
17
+ 'cypress/screenshots',
18
+ 'cypress/videos',
19
+ ];
20
+
21
+ let gitignoreContent = '';
22
+ if (existsSync(gitignorePath)) {
23
+ gitignoreContent = readFileSync(gitignorePath, 'utf8');
24
+ }
25
+
26
+ // Check which entries are missing
27
+ const missingEntries = entries.filter((entry) => {
28
+ // Check if entry exists (with or without newline)
29
+ const regex = new RegExp(`^${entry.replace(/\//g, '\\/')}$`, 'm');
30
+ return !regex.test(gitignoreContent);
31
+ });
32
+
33
+ // Add missing entries
34
+ if (missingEntries.length > 0) {
35
+ if (gitignoreContent && !gitignoreContent.endsWith('\n')) {
36
+ gitignoreContent += '\n';
37
+ }
38
+ gitignoreContent += '\n# Cypress parallel test results (added by dceky)\n';
39
+ missingEntries.forEach((entry) => {
40
+ gitignoreContent += `${entry}\n`;
41
+ });
42
+ writeFileSync(gitignorePath, gitignoreContent, 'utf8');
43
+ console.log(`Added ${missingEntries.length} entries to .gitignore`);
44
+ }
45
+ };
46
+
47
+ export default addToGitIgnore;
@@ -0,0 +1,62 @@
1
+ /* eslint-disable no-console */
2
+ import { existsSync } from 'fs';
3
+ import path from 'path';
4
+
5
+ /**
6
+ * Ensure required configuration files exist in the consumer repo
7
+ * @author Yuen Ler Chow
8
+ */
9
+ const checkRequiredFiles = (): void => {
10
+ const root = path.join(__dirname, '../..');
11
+
12
+ const globalsPath = path.join(root, 'cypress/globals');
13
+ const profilesPath = path.join(root, 'cypress/profiles');
14
+
15
+ // Common file extensions to check
16
+ const extensions = ['.js', '.ts', '.json', '.mjs', '.cjs'];
17
+
18
+ // Required global files
19
+ const requiredGlobals = [
20
+ 'GlobalCredentials',
21
+ 'GlobalResources',
22
+ 'GlobalValues',
23
+ ];
24
+
25
+ // Determine profile file name (default is stage)
26
+ const profileName = process.env.CYPRESS_PROFILE || 'stage';
27
+ const requiredProfile = `${profileName}.Profile`;
28
+
29
+ // Check for missing files
30
+ const missingFiles: string[] = [];
31
+
32
+ // Check global files
33
+ requiredGlobals.forEach((file) => {
34
+ const filePath = path.join(globalsPath, file);
35
+ const found = extensions.some((ext) => {
36
+ return existsSync(`${filePath}${ext}`);
37
+ });
38
+ if (!found) {
39
+ missingFiles.push(`cypress/globals/${file}.ts`);
40
+ }
41
+ });
42
+
43
+ // Check profile file
44
+ const profileFilePath = path.join(profilesPath, requiredProfile);
45
+ const profileFound = extensions.some((ext) => {
46
+ return existsSync(`${profileFilePath}${ext}`);
47
+ });
48
+ if (!profileFound) {
49
+ missingFiles.push(`cypress/profiles/${requiredProfile}.ts`);
50
+ }
51
+
52
+ if (missingFiles.length > 0) {
53
+ console.error('\nMissing required configuration files in this project:');
54
+ missingFiles.forEach((file) => {
55
+ console.error(` - ${file}`);
56
+ });
57
+ console.error('\nPlease create these files before running setup.');
58
+ process.exit(1);
59
+ }
60
+ };
61
+
62
+ export default checkRequiredFiles;
@@ -0,0 +1,75 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ /**
5
+ * Generate an index.ts file that imports and runs all command files in cypress/commands
6
+ * This should be called from cypress.config.js
7
+ * @author Yuen Ler Chow
8
+ */
9
+ const genCommandImportFile = () => {
10
+ const root = path.join(__dirname, '../..');
11
+
12
+ const cypressCommandsDir = path.join(root, 'cypress/commands');
13
+ const outputFile = path.join(cypressCommandsDir, 'index.ts');
14
+ const topOfFileComment = '// Auto-generated by dceky - do not edit manually';
15
+
16
+ // Check if the directory exists
17
+ if (!fs.existsSync(cypressCommandsDir)) {
18
+ // Create the directory
19
+ fs.mkdirSync(cypressCommandsDir, { recursive: true });
20
+ // Create an empty file so init doesn't fail
21
+ fs.writeFileSync(outputFile, `${topOfFileComment}\n`);
22
+ return outputFile;
23
+ }
24
+
25
+ // Get all files in the directory
26
+ const files = fs.readdirSync(cypressCommandsDir);
27
+ const commandFiles: string[] = [];
28
+
29
+ // Filter out non-JS/TS files and process each file
30
+ files.forEach((file) => {
31
+ // Skip non-JS/TS files (like .d.ts, .map, etc.)
32
+ if (!file.endsWith('.js') && !file.endsWith('.ts')) {
33
+ return;
34
+ }
35
+
36
+ // Skip index files
37
+ if (file === 'index.js' || file === 'index.ts') {
38
+ return;
39
+ }
40
+
41
+ // Determine the file's path
42
+ const filePath = path.join(cypressCommandsDir, file);
43
+
44
+ // Check if it's a file (not a directory)
45
+ const stats = fs.statSync(filePath);
46
+ if (!stats.isFile()) {
47
+ return;
48
+ }
49
+
50
+ // Store the file name
51
+ commandFiles.push(file);
52
+ });
53
+
54
+ // Generate require statements and function calls
55
+ const requires: string[] = [];
56
+ const calls: string[] = [];
57
+
58
+ commandFiles.forEach((file) => {
59
+ const requirePath = `./${file}`;
60
+ // Create a safe variable name (replace non-alphanumeric with underscore)
61
+ const importName = file.replace(/\.(js|ts)$/, '');
62
+ const varName = importName.replace(/[^a-zA-Z0-9]/g, '_');
63
+
64
+ requires.push(`const ${varName} = require('${requirePath}');`);
65
+ calls.push(`${varName}.default();`);
66
+ });
67
+
68
+ // Build the final content
69
+ const content = `${topOfFileComment}\n${requires.join('\n')}\n\n${calls.join('\n')}`;
70
+
71
+ // Write to the output file
72
+ fs.writeFileSync(outputFile, content, 'utf8');
73
+ };
74
+
75
+ export default genCommandImportFile;
@@ -0,0 +1,28 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ /**
5
+ * Generate the dynamic configuration file
6
+ */
7
+ const genDynamicConfigFile = (): string => {
8
+ const root = path.join(__dirname, '../..');
9
+
10
+ const outputFile = path.join(root, 'cypress.config.ts');
11
+
12
+ // Create the dynamic configuration file
13
+ const dynamicConfigFile = [
14
+ '// Auto-generated by dceky - do not edit manually',
15
+ '',
16
+ 'import { genConfiguration } from \'dceky\';',
17
+ '',
18
+ 'export default genConfiguration();',
19
+ '',
20
+ ].join('\n');
21
+
22
+ // Write the configuration file directly
23
+ fs.writeFileSync(outputFile, dynamicConfigFile, 'utf8');
24
+
25
+ return outputFile;
26
+ };
27
+
28
+ export default genDynamicConfigFile;
package/setup/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ import genCommandImportFile from './genCommandImportFile';
2
+ import genDynamicConfigFile from './genDynamicConfigFile';
3
+ import addToGitIgnore from './addToGitIgnore';
4
+ import setupCypressDependencies from './setupCypressDependencies';
5
+ import checkRequiredFiles from './checkRequiredFiles';
6
+
7
+ checkRequiredFiles();
8
+ genCommandImportFile();
9
+ genDynamicConfigFile();
10
+ addToGitIgnore();
11
+ setupCypressDependencies();
@@ -0,0 +1,38 @@
1
+ /* eslint-disable no-console */
2
+ import path from 'path';
3
+
4
+ /**
5
+ * Ensure required packages exist in the consumer repo
6
+ * @author Yuen Ler Chow
7
+ */
8
+ const setupCypressDependencies = (): void => {
9
+ const root = path.join(__dirname, '../..');
10
+
11
+ const requiredPkgs = [
12
+ 'cypress-parallel',
13
+ 'cypress-multi-reporters',
14
+ 'mochawesome',
15
+ 'mochawesome-merge',
16
+ 'mochawesome-report-generator',
17
+ ];
18
+
19
+ const missingPkgs = requiredPkgs.filter((pkg) => {
20
+ try {
21
+ // Resolve from the consumer project root
22
+ require.resolve(pkg, { paths: [root] });
23
+ return false;
24
+ } catch {
25
+ return true;
26
+ }
27
+ });
28
+
29
+ if (missingPkgs.length > 0) {
30
+ const installCmd = `npm i -D ${missingPkgs.join(' ')}`;
31
+ console.error(`\nMissing required devDependencies in this project: ${missingPkgs.join(', ')}`);
32
+ console.error('Run the following command, then try again:');
33
+ console.error(`\n${installCmd}\n`);
34
+ process.exit(1);
35
+ }
36
+ };
37
+
38
+ export default setupCypressDependencies;
@@ -0,0 +1,51 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /*----------------------------------------*/
4
+ /* ---------------- Type ---------------- */
5
+ /*----------------------------------------*/
6
+
7
+ declare global {
8
+ namespace Cypress {
9
+ interface Chainable {
10
+ /**
11
+ * Assert that an element does not have a specific className
12
+ * @author Yuen Ler Chow
13
+ * @param opts object containing all arguments
14
+ * @param opts.item the css selector for finding the element
15
+ * @param opts.className the className to check for
16
+ * @return Cypress chainable containing the element that was checked
17
+ */
18
+ assertDoesNotHaveClass(
19
+ opts: {
20
+ item: string,
21
+ className: string,
22
+ },
23
+ ): Chainable<JQuery<HTMLElement>>;
24
+ }
25
+ }
26
+ }
27
+
28
+ /*----------------------------------------*/
29
+ /* --------------- Command -------------- */
30
+ /*----------------------------------------*/
31
+
32
+ const assertDoesNotHaveClass = () => {
33
+ Cypress.Commands.add(
34
+ 'assertDoesNotHaveClass',
35
+ (
36
+ opts: {
37
+ item: string,
38
+ className: string,
39
+ },
40
+ ) => {
41
+ cy.log(`Assert ${opts.item} does not have class ${opts.className}`);
42
+ return cy.get(opts.item).should('not.have.class', opts.className);
43
+ },
44
+ );
45
+ };
46
+
47
+ /*----------------------------------------*/
48
+ /* --------------- Export --------------- */
49
+ /*----------------------------------------*/
50
+
51
+ export default assertDoesNotHaveClass;
@@ -0,0 +1,51 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /*----------------------------------------*/
4
+ /* ---------------- Type ---------------- */
5
+ /*----------------------------------------*/
6
+
7
+ declare global {
8
+ namespace Cypress {
9
+ interface Chainable {
10
+ /**
11
+ * Assert that an element has a specific className
12
+ * @author Yuen Ler Chow
13
+ * @param opts object containing all arguments
14
+ * @param opts.item the css selector for finding the element
15
+ * @param opts.className the className to check for
16
+ * @return Cypress chainable containing the element that was checked
17
+ */
18
+ assertHasClass(
19
+ opts: {
20
+ item: string,
21
+ className: string,
22
+ },
23
+ ): Chainable<JQuery<HTMLElement>>;
24
+ }
25
+ }
26
+ }
27
+
28
+ /*----------------------------------------*/
29
+ /* --------------- Command -------------- */
30
+ /*----------------------------------------*/
31
+
32
+ const assertHasClass = () => {
33
+ Cypress.Commands.add(
34
+ 'assertHasClass',
35
+ (
36
+ opts: {
37
+ item: string,
38
+ className: string,
39
+ },
40
+ ) => {
41
+ cy.log(`Assert ${opts.item} has class ${opts.className}`);
42
+ return cy.get(opts.item).should('have.class', opts.className);
43
+ },
44
+ );
45
+ };
46
+
47
+ /*----------------------------------------*/
48
+ /* --------------- Export --------------- */
49
+ /*----------------------------------------*/
50
+
51
+ export default assertHasClass;
@@ -0,0 +1,50 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /*----------------------------------------*/
4
+ /* ---------------- Type ---------------- */
5
+ /*----------------------------------------*/
6
+
7
+ declare global {
8
+ namespace Cypress {
9
+ interface Chainable {
10
+ /**
11
+ * Assert a certain number of elements
12
+ * @author Yuen Ler Chow
13
+ * @param opts object containing all arguments
14
+ * @param opts.item a CSS selector corresponding to the item
15
+ * @param opts.num the precise number of elements expected
16
+ */
17
+ assertNumElements(
18
+ opts: {
19
+ item: string,
20
+ num: number,
21
+ }
22
+ ): Chainable<Element>;
23
+ }
24
+ }
25
+ }
26
+
27
+ /*----------------------------------------*/
28
+ /* --------------- Command -------------- */
29
+ /*----------------------------------------*/
30
+
31
+ const assertNumElements = () => {
32
+ Cypress.Commands.add(
33
+ 'assertNumElements',
34
+ (
35
+ opts: {
36
+ item: string,
37
+ num: number,
38
+ },
39
+ ) => {
40
+ cy.log(`Assert ${opts.num} elements match ${opts.item}`);
41
+ cy.get(opts.item).should('have.length', opts.num);
42
+ },
43
+ );
44
+ };
45
+
46
+ /*----------------------------------------*/
47
+ /* --------------- Export --------------- */
48
+ /*----------------------------------------*/
49
+
50
+ export default assertNumElements;
@@ -0,0 +1,52 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /*----------------------------------------*/
4
+ /* ---------------- Type ---------------- */
5
+ /*----------------------------------------*/
6
+
7
+ declare global {
8
+ namespace Cypress {
9
+ interface Chainable {
10
+ /**
11
+ * Obtain data from a class attribute that starts with a specific prefix
12
+ * and return it
13
+ * @author Allison Zhang
14
+ * @param selector the css selector for finding the element
15
+ * @param classPrefix the prefix to look for in the class attribute
16
+ * @returns the extracted data
17
+ * @example cy.extractDataFromClass('.item', 'data-').then((data) => { ... })
18
+ */
19
+ extractDataFromClass(
20
+ selector: string,
21
+ classPrefix: string,
22
+ ): Chainable<string[]>;
23
+ }
24
+ }
25
+ }
26
+
27
+ /*----------------------------------------*/
28
+ /* --------------- Command -------------- */
29
+ /*----------------------------------------*/
30
+
31
+ const extractDataFromClass = () => {
32
+ Cypress.Commands.add('extractDataFromClass', (selector: string, classPrefix: string) => {
33
+ return (
34
+ cy
35
+ .get(selector)
36
+ .invoke('attr', 'class')
37
+ .then((classAttr: string) => {
38
+ const classList = classAttr.split(' ');
39
+ const data = classList
40
+ .filter((className) => { return className.startsWith(classPrefix); })
41
+ .map((className) => { return className.replace(classPrefix, ''); });
42
+ return data;
43
+ })
44
+ );
45
+ });
46
+ };
47
+
48
+ /*----------------------------------------*/
49
+ /* --------------- Export --------------- */
50
+ /*----------------------------------------*/
51
+
52
+ export default extractDataFromClass;
@@ -0,0 +1,55 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /*----------------------------------------*/
4
+ /* ---------------- Type ---------------- */
5
+ /*----------------------------------------*/
6
+
7
+ declare global {
8
+ namespace Cypress {
9
+ interface Chainable {
10
+ /**
11
+ * Obtain data from a class attribute that starts with a specific prefix
12
+ * and with specific contents, and return it
13
+ * @author Allison Zhang
14
+ * @param contents the contents of the element to find
15
+ * @param selector the css selector for finding the element
16
+ * @param classPrefix the prefix to look for in the class attribute
17
+ * @returns the extracted data
18
+ * @example cy.extractDataFromClassByContents('Submit', '.button', 'btn-').then((data) => { ... })
19
+ */
20
+ extractDataFromClassByContents(
21
+ contents: string,
22
+ selector: string,
23
+ classPrefix: string,
24
+ ): Chainable<string[]>;
25
+ }
26
+ }
27
+ }
28
+
29
+ /*----------------------------------------*/
30
+ /* --------------- Command -------------- */
31
+ /*----------------------------------------*/
32
+
33
+ const extractDataFromClassByContents = () => {
34
+ Cypress.Commands.add('extractDataFromClassByContents', (contents: string, selector: string, classPrefix: string) => {
35
+ return (
36
+ cy
37
+ .get(selector)
38
+ .contains(contents)
39
+ .invoke('attr', 'class')
40
+ .then((classAttr: string) => {
41
+ const classList = classAttr.split(' ');
42
+ const data = classList
43
+ .filter((className) => { return className.startsWith(classPrefix); })
44
+ .map((className) => { return className.replace(classPrefix, ''); });
45
+ return data;
46
+ })
47
+ );
48
+ });
49
+ };
50
+
51
+ /*----------------------------------------*/
52
+ /* --------------- Export --------------- */
53
+ /*----------------------------------------*/
54
+
55
+ export default extractDataFromClassByContents;
@@ -0,0 +1,45 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /*----------------------------------------*/
4
+ /* ---------------- Type ---------------- */
5
+ /*----------------------------------------*/
6
+
7
+ declare global {
8
+ namespace Cypress {
9
+ interface Chainable {
10
+ /**
11
+ * Obtain JSON data from a request and return it.
12
+ * @author Allison Zhang
13
+ * @param url the URL to fetch the JSON data from
14
+ * @returns the JSON data
15
+ * @example cy.getJSON('https://api.example.com/data').then((data) => { ... })
16
+ */
17
+ getJSON(
18
+ url: string,
19
+ ): Chainable<any>;
20
+ }
21
+ }
22
+ }
23
+
24
+ /*----------------------------------------*/
25
+ /* --------------- Command -------------- */
26
+ /*----------------------------------------*/
27
+
28
+ const getJSON = () => {
29
+ Cypress.Commands.add('getJSON', (url: string) => {
30
+ return (
31
+ cy
32
+ .request(url)
33
+ .its('body')
34
+ .then((body) => {
35
+ return body;
36
+ })
37
+ );
38
+ });
39
+ };
40
+
41
+ /*----------------------------------------*/
42
+ /* --------------- Export --------------- */
43
+ /*----------------------------------------*/
44
+
45
+ export default getJSON;
@@ -0,0 +1,45 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /*----------------------------------------*/
4
+ /* ---------------- Type ---------------- */
5
+ /*----------------------------------------*/
6
+
7
+ declare global {
8
+ namespace Cypress {
9
+ interface Chainable {
10
+ /**
11
+ * Get number of elements
12
+ * @author Yuen Ler Chow
13
+ * @param selector a CSS selector corresponding to the item to count
14
+ * @return Cypress chainable containing the number of elements matching the selector
15
+ */
16
+ getNumElements(
17
+ selector: string,
18
+ ): Chainable<number>;
19
+ }
20
+ }
21
+ }
22
+
23
+ /*----------------------------------------*/
24
+ /* --------------- Command -------------- */
25
+ /*----------------------------------------*/
26
+
27
+ const getNumElements = () => {
28
+ Cypress.Commands.add(
29
+ 'getNumElements',
30
+ (
31
+ selector: string,
32
+ ) => {
33
+ cy.log(`Count elements matching ${selector}`);
34
+ return cy.get(selector).then(($elements: JQuery<HTMLElement>) => {
35
+ return Cypress.$($elements).length;
36
+ });
37
+ },
38
+ );
39
+ };
40
+
41
+ /*----------------------------------------*/
42
+ /* --------------- Export --------------- */
43
+ /*----------------------------------------*/
44
+
45
+ export default getNumElements;