dceky 1.0.23 → 1.0.25

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 (135) hide show
  1. package/lib/src/commands/getCredentialValue.d.ts +18 -0
  2. package/lib/{commands/assertHasClass.js → src/commands/getCredentialValue.js} +8 -6
  3. package/lib/src/commands/getCredentialValue.js.map +1 -0
  4. package/lib/src/commands/getCredentialValues.d.ts +18 -0
  5. package/lib/{commands/getTitle.js → src/commands/getCredentialValues.js} +5 -9
  6. package/lib/src/commands/getCredentialValues.js.map +1 -0
  7. package/lib/src/commands/getProfileValue.d.ts +15 -0
  8. package/lib/{commands/getId.js → src/commands/getProfileValue.js} +5 -10
  9. package/lib/src/commands/getProfileValue.js.map +1 -0
  10. package/lib/src/commands/handleHarvardKey.js +36 -33
  11. package/lib/src/commands/handleHarvardKey.js.map +1 -1
  12. package/lib/src/commands/index.js +6 -0
  13. package/lib/src/commands/index.js.map +1 -1
  14. package/lib/src/commands/launchAs.js +70 -68
  15. package/lib/src/commands/launchAs.js.map +1 -1
  16. package/lib/src/commands/logIntoPorta.js +46 -43
  17. package/lib/src/commands/logIntoPorta.js.map +1 -1
  18. package/lib/src/genConfiguration/index.js +7 -4
  19. package/lib/src/genConfiguration/index.js.map +1 -1
  20. package/package.json +2 -2
  21. package/src/commands/getCredentialValue.ts +45 -0
  22. package/src/commands/getCredentialValues.ts +43 -0
  23. package/src/commands/getProfileValue.ts +40 -0
  24. package/src/commands/handleHarvardKey.ts +41 -38
  25. package/src/commands/index.ts +6 -0
  26. package/src/commands/launchAs.ts +90 -88
  27. package/src/commands/logIntoPorta.ts +61 -57
  28. package/src/genConfiguration/index.ts +11 -4
  29. package/cypress/e2e/profile-test.cy.ts +0 -10
  30. package/cypress/fixtures/example.json +0 -5
  31. package/cypress/support/commands.ts +0 -37
  32. package/cypress/support/e2e.ts +0 -17
  33. package/lib/commands/assertDoesNotHaveClass.d.ts +0 -18
  34. package/lib/commands/assertDoesNotHaveClass.js +0 -17
  35. package/lib/commands/assertDoesNotHaveClass.js.map +0 -1
  36. package/lib/commands/assertHasClass.d.ts +0 -18
  37. package/lib/commands/assertHasClass.js.map +0 -1
  38. package/lib/commands/assertNumElements.d.ts +0 -18
  39. package/lib/commands/assertNumElements.js +0 -17
  40. package/lib/commands/assertNumElements.js.map +0 -1
  41. package/lib/commands/clickWithRetry.d.ts +0 -19
  42. package/lib/commands/clickWithRetry.js +0 -29
  43. package/lib/commands/clickWithRetry.js.map +0 -1
  44. package/lib/commands/genTextOfLength.d.ts +0 -20
  45. package/lib/commands/genTextOfLength.js +0 -20
  46. package/lib/commands/genTextOfLength.js.map +0 -1
  47. package/lib/commands/getAttribute.d.ts +0 -20
  48. package/lib/commands/getAttribute.js +0 -22
  49. package/lib/commands/getAttribute.js.map +0 -1
  50. package/lib/commands/getClassName.d.ts +0 -15
  51. package/lib/commands/getClassName.js +0 -21
  52. package/lib/commands/getClassName.js.map +0 -1
  53. package/lib/commands/getCurrentDateInfo.d.ts +0 -21
  54. package/lib/commands/getCurrentDateInfo.js +0 -25
  55. package/lib/commands/getCurrentDateInfo.js.map +0 -1
  56. package/lib/commands/getId.d.ts +0 -15
  57. package/lib/commands/getId.js.map +0 -1
  58. package/lib/commands/getNumElements.d.ts +0 -14
  59. package/lib/commands/getNumElements.js +0 -19
  60. package/lib/commands/getNumElements.js.map +0 -1
  61. package/lib/commands/getSpecialChars.d.ts +0 -14
  62. package/lib/commands/getSpecialChars.js +0 -16
  63. package/lib/commands/getSpecialChars.js.map +0 -1
  64. package/lib/commands/getTitle.d.ts +0 -13
  65. package/lib/commands/getTitle.js.map +0 -1
  66. package/lib/commands/handleHarvardKey.d.ts +0 -18
  67. package/lib/commands/handleHarvardKey.js +0 -56
  68. package/lib/commands/handleHarvardKey.js.map +0 -1
  69. package/lib/commands/handleHarvardKey2.d.ts +0 -14
  70. package/lib/commands/handleHarvardKey2.js +0 -88
  71. package/lib/commands/handleHarvardKey2.js.map +0 -1
  72. package/lib/commands/launchAs.d.ts +0 -20
  73. package/lib/commands/launchAs.js +0 -60
  74. package/lib/commands/launchAs.js.map +0 -1
  75. package/lib/commands/launchLTIUsingToken.d.ts +0 -19
  76. package/lib/commands/launchLTIUsingToken.js +0 -74
  77. package/lib/commands/launchLTIUsingToken.js.map +0 -1
  78. package/lib/commands/listSelectLabels.d.ts +0 -15
  79. package/lib/commands/listSelectLabels.js +0 -24
  80. package/lib/commands/listSelectLabels.js.map +0 -1
  81. package/lib/commands/listSelectValues.d.ts +0 -15
  82. package/lib/commands/listSelectValues.js +0 -26
  83. package/lib/commands/listSelectValues.js.map +0 -1
  84. package/lib/commands/navigateToHref.d.ts +0 -19
  85. package/lib/commands/navigateToHref.js +0 -23
  86. package/lib/commands/navigateToHref.js.map +0 -1
  87. package/lib/commands/padWithZeros.d.ts +0 -20
  88. package/lib/commands/padWithZeros.js +0 -24
  89. package/lib/commands/padWithZeros.js.map +0 -1
  90. package/lib/commands/runScript.d.ts +0 -16
  91. package/lib/commands/runScript.js +0 -25
  92. package/lib/commands/runScript.js.map +0 -1
  93. package/lib/commands/typeInto.d.ts +0 -20
  94. package/lib/commands/typeInto.js +0 -28
  95. package/lib/commands/typeInto.js.map +0 -1
  96. package/lib/commands/uniquify.d.ts +0 -15
  97. package/lib/commands/uniquify.js +0 -25
  98. package/lib/commands/uniquify.js.map +0 -1
  99. package/lib/commands/visitCanvasEndpoint.d.ts +0 -27
  100. package/lib/commands/visitCanvasEndpoint.js +0 -35
  101. package/lib/commands/visitCanvasEndpoint.js.map +0 -1
  102. package/lib/commands/visitCanvasGETEndpoint.d.ts +0 -20
  103. package/lib/commands/visitCanvasGETEndpoint.js +0 -26
  104. package/lib/commands/visitCanvasGETEndpoint.js.map +0 -1
  105. package/lib/commands/waitForAtLeastOneElementPresent.d.ts +0 -23
  106. package/lib/commands/waitForAtLeastOneElementPresent.js +0 -27
  107. package/lib/commands/waitForAtLeastOneElementPresent.js.map +0 -1
  108. package/lib/commands/waitForElementVisible.d.ts +0 -14
  109. package/lib/commands/waitForElementVisible.js +0 -20
  110. package/lib/commands/waitForElementVisible.js.map +0 -1
  111. package/lib/index.js.map +0 -1
  112. package/lib/init.d.ts +0 -6
  113. package/lib/init.js +0 -69
  114. package/lib/init.js.map +0 -1
  115. package/lib/postinstall/helpers/exec.d.ts +0 -8
  116. package/lib/postinstall/helpers/exec.js +0 -18
  117. package/lib/postinstall/helpers/exec.js.map +0 -1
  118. package/lib/setup/checkRequiredFiles.d.ts +0 -6
  119. package/lib/setup/checkRequiredFiles.js +0 -60
  120. package/lib/setup/checkRequiredFiles.js.map +0 -1
  121. package/lib/setup/genEmptyGlobalFile.d.ts +0 -7
  122. package/lib/setup/genEmptyGlobalFile.js +0 -41
  123. package/lib/setup/genEmptyGlobalFile.js.map +0 -1
  124. package/lib/src/commands/launchLTIUsingToken.d.ts +0 -21
  125. package/lib/src/commands/launchLTIUsingToken.js +0 -76
  126. package/lib/src/commands/launchLTIUsingToken.js.map +0 -1
  127. package/lib/src/commands/visitCanvasGETEndpoint.d.ts +0 -20
  128. package/lib/src/commands/visitCanvasGETEndpoint.js +0 -26
  129. package/lib/src/commands/visitCanvasGETEndpoint.js.map +0 -1
  130. package/lib/src/init.d.ts +0 -6
  131. package/lib/src/init.js +0 -71
  132. package/lib/src/init.js.map +0 -1
  133. package/lib/src/node.d.ts +0 -2
  134. package/lib/src/node.js +0 -10
  135. package/lib/src/node.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/genConfiguration/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/genConfiguration/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dceky",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "description": "Cypress toolkit for Harvard DCE",
5
5
  "main": "./lib/src/index.js",
6
6
  "types": "./lib/src/index.d.ts",
@@ -52,6 +52,6 @@
52
52
  "typescript": "^5.9.3"
53
53
  },
54
54
  "peerDependencies": {
55
- "cypress": "^x.x.x"
55
+ "cypress": "^15.11.0"
56
56
  }
57
57
  }
@@ -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
+ * Alias for cy.env for retrieving a single environment variable
12
+ * Obtains a credential value from the Cypress env depending on
13
+ * the provided key.
14
+ * @author Allison Zhang
15
+ * @param key the key of the environment variable to retrieve
16
+ * @return The value of the specified environment variable
17
+ * the corresponding environment variable values from global credentials
18
+ */
19
+ getCredentialValue(
20
+ key: string,
21
+ ): Chainable<any>;
22
+ }
23
+ }
24
+ }
25
+
26
+ /*----------------------------------------*/
27
+ /* --------------- Command -------------- */
28
+ /*----------------------------------------*/
29
+
30
+ const getCredentialValue = () => {
31
+ Cypress.Commands.add(
32
+ 'getCredentialValue',
33
+ (key) => {
34
+ return cy.env([key]).then(({ [key]: value }) => {
35
+ return cy.wrap(value);
36
+ });
37
+ },
38
+ );
39
+ };
40
+
41
+ /*----------------------------------------*/
42
+ /* --------------- Export --------------- */
43
+ /*----------------------------------------*/
44
+
45
+ export default getCredentialValue;
@@ -0,0 +1,43 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /*----------------------------------------*/
4
+ /* ---------------- Type ---------------- */
5
+ /*----------------------------------------*/
6
+
7
+ declare global {
8
+ namespace Cypress {
9
+ interface Chainable {
10
+ /**
11
+ * Alias for cy.env for retrieving multiple environment variables at once
12
+ * Obtains multiple credential values from the Cypress env depending on
13
+ * the provided keys.
14
+ * @author Allison Zhang
15
+ * @param keys the keys of the environment variables to retrieve
16
+ * @return Object where keys are the provided keys and the values are
17
+ * the corresponding environment variable values from global credentials
18
+ */
19
+ getCredentialValues(
20
+ keys: string[],
21
+ ): Chainable<Record<string, any>>;
22
+ }
23
+ }
24
+ }
25
+
26
+ /*----------------------------------------*/
27
+ /* --------------- Command -------------- */
28
+ /*----------------------------------------*/
29
+
30
+ const getCredentialValues = () => {
31
+ Cypress.Commands.add(
32
+ 'getCredentialValues',
33
+ (keys) => {
34
+ return cy.env(keys);
35
+ },
36
+ );
37
+ };
38
+
39
+ /*----------------------------------------*/
40
+ /* --------------- Export --------------- */
41
+ /*----------------------------------------*/
42
+
43
+ export default getCredentialValues;
@@ -0,0 +1,40 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /*----------------------------------------*/
4
+ /* ---------------- Type ---------------- */
5
+ /*----------------------------------------*/
6
+
7
+ declare global {
8
+ namespace Cypress {
9
+ interface Chainable {
10
+ /**
11
+ * Alias for Cypress.expose
12
+ * @author Allison Zhang
13
+ * @param key the key of the environment variable to retrieve
14
+ * @return Environment variable from the exposed environment
15
+ */
16
+ getProfileValue(
17
+ key: string,
18
+ ): ObjectLike;
19
+ }
20
+ }
21
+ }
22
+
23
+ /*----------------------------------------*/
24
+ /* --------------- Command -------------- */
25
+ /*----------------------------------------*/
26
+
27
+ const getProfileValue = () => {
28
+ Cypress.Commands.add(
29
+ 'getProfileValue',
30
+ (key) => {
31
+ return Cypress.expose(key);
32
+ },
33
+ );
34
+ };
35
+
36
+ /*----------------------------------------*/
37
+ /* --------------- Export --------------- */
38
+ /*----------------------------------------*/
39
+
40
+ export default getProfileValue;
@@ -32,52 +32,55 @@ const handleHarvardKey = () => {
32
32
  ) => {
33
33
  cy.log('🔓 Handling HarvardKey authentication via UI');
34
34
 
35
- const userInfo = Cypress.env(name);
36
- if (!userInfo) {
37
- throw new Error(`Could not find ${name} in environment variables`);
38
- }
35
+ // Get user credentials from environment variables
36
+ cy.env([name]).then((environment) => {
37
+ const userInfo = environment[name];
38
+ if (!userInfo) {
39
+ throw new Error(`Could not find ${name} in environment variables`);
40
+ }
39
41
 
40
- // Destructure the user info object
41
- const { username, password } = userInfo;
42
+ // Destructure the user info object
43
+ const { username, password } = userInfo;
42
44
 
43
- // Get the Harvard login URL using originWithKaixa with auto-initialized functions
44
- cy.origin('https://apps.cirrusidentity.com', () => {
45
- Cypress.require('dceky');
46
- // To go the login screen
47
- // Clicking the button doesn't work for some reason, so we access the href attribute instead
48
- return cy.navigateToHref('#idp_1001962798_button');
49
- }).then((fullUrl: string) => {
50
- // Navigate to the Harvard login page using originWithKaixa
51
- cy.origin('https://harvard.idp.cirrusidentity.com', {
52
- args: { username, password, fullUrl },
53
- }, (args) => {
45
+ // Get the Harvard login URL using originWithKaixa with auto-initialized functions
46
+ cy.origin('https://apps.cirrusidentity.com', () => {
54
47
  Cypress.require('dceky');
55
- const {
56
- username: harvardUsername,
57
- password: harvardPassword,
58
- fullUrl: harvardLoginUrl,
59
- } = args;
48
+ // To go the login screen
49
+ // Clicking the button doesn't work for some reason, so we access the href attribute instead
50
+ return cy.navigateToHref('#idp_1001962798_button');
51
+ }).then((fullUrl: string) => {
52
+ // Navigate to the Harvard login page using originWithKaixa
53
+ cy.origin('https://harvard.idp.cirrusidentity.com', {
54
+ args: { username, password, fullUrl },
55
+ }, (args) => {
56
+ Cypress.require('dceky');
57
+ const {
58
+ username: harvardUsername,
59
+ password: harvardPassword,
60
+ fullUrl: harvardLoginUrl,
61
+ } = args;
60
62
 
61
- cy.on('uncaught:exception', (e: Error) => {
62
- // Ignore known HarvardKey errors
63
- if (!e.message.includes('ready is not defined')) {
64
- return true;
65
- }
66
- return false;
67
- });
63
+ cy.on('uncaught:exception', (e: Error) => {
64
+ // Ignore known HarvardKey errors
65
+ if (!e.message.includes('ready is not defined')) {
66
+ return true;
67
+ }
68
+ return false;
69
+ });
68
70
 
69
- // Visit the Harvard login page
70
- cy.visit(harvardLoginUrl);
71
+ // Visit the Harvard login page
72
+ cy.visit(harvardLoginUrl);
71
73
 
72
- // Wait for and fill in the login form
73
- cy.waitForElementVisible('#username');
74
- cy.waitForElementVisible('#password');
74
+ // Wait for and fill in the login form
75
+ cy.waitForElementVisible('#username');
76
+ cy.waitForElementVisible('#password');
75
77
 
76
- cy.typeInto({ item: '#username', text: harvardUsername });
77
- cy.typeInto({ item: '#password', text: harvardPassword });
78
+ cy.typeInto({ item: '#username', text: harvardUsername });
79
+ cy.typeInto({ item: '#password', text: harvardPassword });
78
80
 
79
- // Submit the form
80
- cy.get('input[type="submit"], button[type="submit"], .btn-primary').click();
81
+ // Submit the form
82
+ cy.get('input[type="submit"], button[type="submit"], .btn-primary').click();
83
+ });
81
84
  });
82
85
  });
83
86
  },
@@ -29,6 +29,9 @@ import uniquify from './uniquify';
29
29
  import visitCanvasEndpoint from './visitCanvasEndpoint';
30
30
  import waitForAtLeastOneElementPresent from './waitForAtLeastOneElementPresent';
31
31
  import waitForElementVisible from './waitForElementVisible';
32
+ import getProfileValue from './getProfileValue';
33
+ import getCredentialValue from './getCredentialValue';
34
+ import getCredentialValues from './getCredentialValues';
32
35
 
33
36
  /**
34
37
  * Initialize custom commands
@@ -66,6 +69,9 @@ const commands = () => {
66
69
  visitCanvasEndpoint();
67
70
  waitForAtLeastOneElementPresent();
68
71
  waitForElementVisible();
72
+ getProfileValue();
73
+ getCredentialValue();
74
+ getCredentialValues();
69
75
  };
70
76
 
71
77
  export default commands;
@@ -58,7 +58,7 @@ const launchAs = () => {
58
58
 
59
59
  // Get courseId from environment variables if not provided
60
60
  if (!courseId) {
61
- const envCourseId = Cypress.env('courseId');
61
+ const envCourseId = Cypress.expose('courseId');
62
62
  if (!envCourseId) {
63
63
  throw new Error('Could not find courseId in environment variables');
64
64
  }
@@ -66,102 +66,104 @@ const launchAs = () => {
66
66
  }
67
67
 
68
68
  // Get appName from environment variables if not provided
69
- appName = appName || Cypress.env('appName');
69
+ appName = appName || Cypress.expose('appName');
70
70
  if (!appName) {
71
71
  throw new Error('Could not find appName in environment variables');
72
72
  }
73
73
 
74
74
  // Get user accessToken from environment variables
75
- const userInfo = Cypress.env(name);
76
- if (!userInfo) {
77
- throw new Error(`Could not find ${name} in environment variables`);
78
- }
79
- const { accessToken } = userInfo;
80
- if (!accessToken) {
81
- throw new Error(`Could not find accessToken for ${name} in environment variables`);
82
- }
83
-
84
- // List external tools in the course
85
- return (
86
- cy
87
- .request({
88
- method: 'GET',
89
- url: `https://canvas.harvard.edu/api/v1/courses/${courseId}/external_tools`,
90
- body: {
91
- per_page: 200,
92
- access_token: accessToken,
93
- },
94
- })
95
- .then((response) => {
96
- // Extract tools from the body
97
- const externalTools = response.body;
98
-
99
- // Find the external tool of interest
100
- const matchingTool = externalTools.find((externalTool: any) => {
101
- // Skip non-nav items
102
- if (
103
- // No nav
104
- !externalTool.course_navigation
105
- // No nav information
106
- || typeof externalTool.course_navigation !== 'object'
107
- ) {
108
- return false;
109
- }
75
+ cy.env([name]).then((environment) => {
76
+ const userInfo = environment[name];
77
+ if (!userInfo) {
78
+ throw new Error(`Could not find ${name} in environment variables`);
79
+ }
80
+ const { accessToken } = userInfo;
81
+ if (!accessToken) {
82
+ throw new Error(`Could not find accessToken for ${name} in environment variables`);
83
+ }
110
84
 
111
- // Skip non-labeled items
112
- if (!externalTool.course_navigation.text) {
113
- return false;
85
+ // List external tools in the course
86
+ return (
87
+ cy
88
+ .request({
89
+ method: 'GET',
90
+ url: `https://canvas.harvard.edu/api/v1/courses/${courseId}/external_tools`,
91
+ body: {
92
+ per_page: 200,
93
+ access_token: accessToken,
94
+ },
95
+ })
96
+ .then((response) => {
97
+ // Extract tools from the body
98
+ const externalTools = response.body;
99
+
100
+ // Find the external tool of interest
101
+ const matchingTool = externalTools.find((externalTool: any) => {
102
+ // Skip non-nav items
103
+ if (
104
+ // No nav
105
+ !externalTool.course_navigation
106
+ // No nav information
107
+ || typeof externalTool.course_navigation !== 'object'
108
+ ) {
109
+ return false;
110
+ }
111
+
112
+ // Skip non-labeled items
113
+ if (!externalTool.course_navigation.text) {
114
+ return false;
115
+ }
116
+
117
+ // Skip if the app name does not match the expected name
118
+ const thisAppName = (
119
+ externalTool
120
+ .course_navigation
121
+ .text
122
+ .trim()
123
+ .toLowerCase()
124
+ );
125
+ return thisAppName === appName.trim().toLowerCase();
126
+ });
127
+
128
+ // Make sure we found the app
129
+ if (!matchingTool) {
130
+ throw new Error(`Could not find any apps named "${appName}" in course ${courseId}`);
114
131
  }
115
132
 
116
- // Skip if the app name does not match the expected name
117
- const thisAppName = (
118
- externalTool
119
- .course_navigation
120
- .text
121
- .trim()
122
- .toLowerCase()
133
+ // Get the toolId for the matching tool
134
+ const toolId = matchingTool?.id || 0;
135
+ return cy.wrap(toolId);
136
+ })
137
+ .then((toolId) => {
138
+ // Request sessionless launch URL
139
+ return (
140
+ cy
141
+ .request({
142
+ method: 'GET',
143
+ url: `https://canvas.harvard.edu/api/v1/courses/${courseId}/external_tools/sessionless_launch?id=${toolId}`,
144
+ body: {
145
+ per_page: 200,
146
+ access_token: accessToken,
147
+ },
148
+ })
149
+ .its('body')
123
150
  );
124
- return thisAppName === appName.trim().toLowerCase();
125
- });
126
-
127
- // Make sure we found the app
128
- if (!matchingTool) {
129
- throw new Error(`Could not find any apps named "${appName}" in course ${courseId}`);
130
- }
131
-
132
- // Get the toolId for the matching tool
133
- const toolId = matchingTool?.id || 0;
134
- return cy.wrap(toolId);
135
- })
136
- .then((toolId) => {
137
- // Request sessionless launch URL
138
- return (
139
- cy
140
- .request({
141
- method: 'GET',
142
- url: `https://canvas.harvard.edu/api/v1/courses/${courseId}/external_tools/sessionless_launch?id=${toolId}`,
143
- body: {
144
- per_page: 200,
145
- access_token: accessToken,
146
- },
147
- })
148
- .its('body')
149
- );
150
- })
151
- .then((sessionlessLaunchInfo) => {
152
- cy.on('uncaught:exception', (e: Error) => {
153
- // Ignore known LTI launch errors
154
- if (!e.message.includes('postMessage')) {
155
- return true;
156
- }
157
- return false;
158
- });
159
-
160
- // Launch via the sessionless launch URL
161
- const launchURL = sessionlessLaunchInfo.url;
162
- cy.visit(launchURL);
163
- })
164
- );
151
+ })
152
+ .then((sessionlessLaunchInfo) => {
153
+ cy.on('uncaught:exception', (e: Error) => {
154
+ // Ignore known LTI launch errors
155
+ if (!e.message.includes('postMessage')) {
156
+ return true;
157
+ }
158
+ return false;
159
+ });
160
+
161
+ // Launch via the sessionless launch URL
162
+ const launchURL = sessionlessLaunchInfo.url;
163
+ cy.visit(launchURL);
164
+ })
165
+ );
166
+ });
165
167
  },
166
168
  );
167
169
  };
@@ -73,84 +73,88 @@ const logIntoPorta = () => {
73
73
  ) => {
74
74
  cy.log('🔓 Handling HarvardKey authentication via API');
75
75
 
76
- const userInfo = Cypress.env(name);
77
- if (!userInfo) {
78
- throw new Error(`Could not find ${name} in environment variables`);
79
- }
80
- const { username, password } = userInfo;
81
-
82
- // Check if username and password are set
83
- if (!username || !password) {
84
- throw new Error(`Credential "${name}" is missing username and/or password`);
85
- }
86
-
87
- const htmlHeaders = { accept: 'text/html' };
88
-
89
- // Request 1: GET Cirrus Identity discovery page
90
- cy.request({
91
- url: LOGIN_PAGE,
92
- followRedirect: true,
93
- failOnStatusCode: false,
94
- headers: htmlHeaders,
95
- }).then((discoveryRes) => {
96
- // Parse discovery page for HarvardKey IdP button href
97
- const btnMatch = discoveryRes.body.match(
98
- new RegExp(`href=["']([^"']+)["'][^>]*id=["']${HARVARDKEY_IDP_BUTTON_ID}["']`),
99
- );
100
- if (!btnMatch) {
101
- throw new Error('Could not find HarvardKey IdP button link on discovery page');
76
+ // Get user credentials from environment variables
77
+ cy.env([name]).then((environment) => {
78
+ const userInfo = environment[name];
79
+
80
+ if (!userInfo) {
81
+ throw new Error(`Could not find ${name} in environment variables`);
82
+ }
83
+ const { username, password } = userInfo;
84
+
85
+ // Check if username and password are set
86
+ if (!username || !password) {
87
+ throw new Error(`Credential "${name}" is missing username and/or password`);
102
88
  }
103
89
 
104
- const idpUrl = `${IDP_BASE_URL}${btnMatch[1]}`;
90
+ const htmlHeaders = { accept: 'text/html' };
105
91
 
106
- // Request 2: GET HarvardKey IdP login page
92
+ // Request 1: GET Cirrus Identity discovery page
107
93
  cy.request({
108
- url: idpUrl,
94
+ url: LOGIN_PAGE,
109
95
  followRedirect: true,
110
96
  failOnStatusCode: false,
111
97
  headers: htmlHeaders,
112
- }).then((loginPageRes) => {
113
- // Parse login form action and hidden fields
114
- const {
115
- action: loginFormUrl,
116
- fields: loginHiddenFields,
117
- } = getFormData(loginPageRes.body);
118
- if (!loginFormUrl) {
119
- throw new Error('Could not find login form action on HarvardKey page');
98
+ }).then((discoveryRes) => {
99
+ // Parse discovery page for HarvardKey IdP button href
100
+ const btnMatch = discoveryRes.body.match(
101
+ new RegExp(`href=["']([^"']+)["'][^>]*id=["']${HARVARDKEY_IDP_BUTTON_ID}["']`),
102
+ );
103
+ if (!btnMatch) {
104
+ throw new Error('Could not find HarvardKey IdP button link on discovery page');
120
105
  }
121
106
 
122
- // Request 3: POST credentials to HarvardKey login form
107
+ const idpUrl = `${IDP_BASE_URL}${btnMatch[1]}`;
108
+
109
+ // Request 2: GET HarvardKey IdP login page
123
110
  cy.request({
124
- method: 'POST',
125
- url: loginFormUrl,
126
- form: true,
111
+ url: idpUrl,
127
112
  followRedirect: true,
128
113
  failOnStatusCode: false,
129
114
  headers: htmlHeaders,
130
- body: {
131
- ...loginHiddenFields,
132
- username,
133
- password,
134
- },
135
- }).then((authRes) => {
136
- // Parse SAML form from login response
115
+ }).then((loginPageRes) => {
116
+ // Parse login form action and hidden fields
137
117
  const {
138
- action: samlFormUrl,
139
- fields: samlHiddenFields,
140
- } = getFormData(authRes.body, 'form[action*="saml2-acs"]');
141
- if (!samlFormUrl) {
142
- throw new Error('Could not find SAML form in login response');
118
+ action: loginFormUrl,
119
+ fields: loginHiddenFields,
120
+ } = getFormData(loginPageRes.body);
121
+ if (!loginFormUrl) {
122
+ throw new Error('Could not find login form action on HarvardKey page');
143
123
  }
144
124
 
145
- // Request 4: POST SAML assertion to ACS
146
- return cy.request({
125
+ // Request 3: POST credentials to HarvardKey login form
126
+ cy.request({
147
127
  method: 'POST',
148
- url: samlFormUrl,
128
+ url: loginFormUrl,
149
129
  form: true,
150
130
  followRedirect: true,
151
131
  failOnStatusCode: false,
152
132
  headers: htmlHeaders,
153
- body: samlHiddenFields,
133
+ body: {
134
+ ...loginHiddenFields,
135
+ username,
136
+ password,
137
+ },
138
+ }).then((authRes) => {
139
+ // Parse SAML form from login response
140
+ const {
141
+ action: samlFormUrl,
142
+ fields: samlHiddenFields,
143
+ } = getFormData(authRes.body, 'form[action*="saml2-acs"]');
144
+ if (!samlFormUrl) {
145
+ throw new Error('Could not find SAML form in login response');
146
+ }
147
+
148
+ // Request 4: POST SAML assertion to ACS
149
+ return cy.request({
150
+ method: 'POST',
151
+ url: samlFormUrl,
152
+ form: true,
153
+ followRedirect: true,
154
+ failOnStatusCode: false,
155
+ headers: htmlHeaders,
156
+ body: samlHiddenFields,
157
+ });
154
158
  });
155
159
  });
156
160
  });
@@ -65,7 +65,6 @@ const genConfiguration = () => {
65
65
 
66
66
  // NOTE: Order matters (later overrides earlier)
67
67
  const sources: GlobalsOrProfile[] = [
68
- GlobalCredentials,
69
68
  GlobalResources,
70
69
  GlobalValues,
71
70
  profileModules,
@@ -92,13 +91,20 @@ const genConfiguration = () => {
92
91
  const dependents: GlobalsOrProfile = resolveDependents(dependentValues, basics);
93
92
 
94
93
  // Add basics, depends, and profileName into the final env
95
- const finalEnv: GlobalsOrProfile = {
94
+ const exposed: GlobalsOrProfile = {
96
95
  ...basics,
97
96
  ...dependents,
98
97
  profileName,
99
98
  };
100
99
 
101
- let baseUrl = finalEnv.baseURL;
100
+ // Add all global values and credentials into the final env
101
+ // Does not support dependent values in GlobalCredentials, TODO: Fix
102
+ const securedEnv = {
103
+ ...GlobalCredentials,
104
+ ...exposed,
105
+ };
106
+
107
+ let baseUrl = exposed.baseURL;
102
108
  if (!baseUrl?.startsWith('http')) {
103
109
  baseUrl = `https://${baseUrl}`;
104
110
  }
@@ -109,7 +115,8 @@ const genConfiguration = () => {
109
115
  experimentalWebKitSupport: true,
110
116
  experimentalOriginDependencies: true,
111
117
  baseUrl,
112
- env: finalEnv,
118
+ expose: exposed,
119
+ env: securedEnv,
113
120
  },
114
121
  });
115
122
  };