@suffolklitlab/alkiln 4.0.0-pre-api.7 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -9
- package/README.md +10 -2
- package/action.yml +8 -6
- package/lib/docassemble/docassemble_api_interface.js +2 -1
- package/lib/docassemble/get_base_interview_url.js +19 -0
- package/lib/index.js +0 -2
- package/lib/scope.js +158 -87
- package/lib/steps.js +10 -10
- package/lib/utils/langs.js +2 -2
- package/lib/utils/session_vars.js +54 -80
- package/package.json +4 -5
- package/tests/features/establishing_steps.feature +2 -2
- package/tests/features/observation_steps.feature +1 -1
- package/tests/features/reports.feature +23 -55
- package/tests/features/story_table_formats.feature +1 -1
- package/tests/features/story_tables.feature +1 -1
- package/tests/unit_tests/getMatchingRows.test.js +28 -0
- package/tests/unit_tests/matches.fixtures.js +13 -1
- package/tests/unit_tests/session_vars.test.js +46 -0
- package/tests/unit_tests/tables.fixtures.js +12 -2
- package/lib/utils/env_vars.js +0 -177
- package/tests/unit_tests/env_vars.test.js +0 -53
package/lib/steps.js
CHANGED
|
@@ -19,7 +19,7 @@ const { v4: uuidv4 } = require('uuid');
|
|
|
19
19
|
|
|
20
20
|
// Ours
|
|
21
21
|
const scope = require('./scope');
|
|
22
|
-
const
|
|
22
|
+
const session_vars = require('./utils/session_vars');
|
|
23
23
|
|
|
24
24
|
/* Of Note:
|
|
25
25
|
- We're using `*=` because sometimes da text has funny characters in it that are hard to anticipate
|
|
@@ -717,7 +717,7 @@ When('I tap to continue', { timeout: -1 }, async () => {
|
|
|
717
717
|
// --- VARIABLES-BASED STEPS ---
|
|
718
718
|
|
|
719
719
|
When(/I set the var(?:iable)? "([^"]+)" to "([^"]+)"/, { timeout: -1 }, async ( var_name, set_to ) => {
|
|
720
|
-
/* Set
|
|
720
|
+
/* Set a non-story table variable (with or without a choice associated with it) to a value. Set:
|
|
721
721
|
* - Buttons associated with variables
|
|
722
722
|
* - Dropdowns
|
|
723
723
|
* - Checkboxes (multiple choice checkboxes must be set to "true" or "false")
|
|
@@ -725,7 +725,7 @@ When(/I set the var(?:iable)? "([^"]+)" to "([^"]+)"/, { timeout: -1 }, async (
|
|
|
725
725
|
* - Text inputs
|
|
726
726
|
* - Textareas
|
|
727
727
|
*
|
|
728
|
-
*
|
|
728
|
+
* Variations:
|
|
729
729
|
* 1. I set the var "benefits['SSI']" to "false"
|
|
730
730
|
* 1. I set the var "rent_interval" to "weekly"
|
|
731
731
|
*/
|
|
@@ -736,7 +736,7 @@ When(/I set the var(?:iable)? "([^"]+)" to "([^"]+)"/, { timeout: -1 }, async (
|
|
|
736
736
|
});
|
|
737
737
|
|
|
738
738
|
Then(/I upload "([^"]+)" to "([^"]+)"/, { timeout: -1 }, async ( filenames, var_name ) => {
|
|
739
|
-
/* Uploads
|
|
739
|
+
/* Uploads file (docx, jpg, etc) in same folder to input var. Can actually use
|
|
740
740
|
* 'I set the var "" to ""', but this is more explicit if it's desired. */
|
|
741
741
|
return wrapPromiseWithTimeout(
|
|
742
742
|
scope.steps.set_regular_var( scope, var_name, filenames ),
|
|
@@ -867,9 +867,9 @@ After(async function(scenario) {
|
|
|
867
867
|
await scope.setReportScenarioStatus( scope, { status: scenario.result.status });
|
|
868
868
|
|
|
869
869
|
if (scenario.result.status !== `PASSED`) {
|
|
870
|
-
if (
|
|
870
|
+
if ( session_vars.get_debug() ) {
|
|
871
871
|
console.log( `Non-passed status occurred while running test:`, scenario.result.status );
|
|
872
|
-
// If there's a page visible, give us time to examine it
|
|
872
|
+
// If there's a page visible (locally), give us time to examine it
|
|
873
873
|
if ( scope.page ) { await scope.page.waitForTimeout( 60 * 1000 ); }
|
|
874
874
|
}
|
|
875
875
|
|
|
@@ -909,15 +909,15 @@ After(async function(scenario) {
|
|
|
909
909
|
// Consider, instead, catching the reload error for a bad restart and just
|
|
910
910
|
// re-trying at that point.
|
|
911
911
|
try {
|
|
912
|
-
await scope.page.goto(`${
|
|
912
|
+
await scope.page.goto(`${ session_vars.get_da_server_url() }/user/sign-out`, {waitUntil: `domcontentloaded`});
|
|
913
913
|
} catch ( err ) {
|
|
914
|
-
if (
|
|
914
|
+
if ( session_vars.DEBUG ) {
|
|
915
915
|
console.log( `Trying to reset for the next test a second time because the first time failed.` );
|
|
916
916
|
}
|
|
917
917
|
|
|
918
918
|
try {
|
|
919
|
-
await scope.page.goto(`${
|
|
920
|
-
|
|
919
|
+
await scope.page.goto(`${ session_vars.get_da_server_url() }/user/sign-out`, {waitUntil: `domcontentloaded`});
|
|
920
|
+
|
|
921
921
|
} catch ( err ) {
|
|
922
922
|
await scope.addToReport(scope, {
|
|
923
923
|
type: `warning`,
|
package/lib/utils/langs.js
CHANGED
|
@@ -4,7 +4,7 @@ let _path = require('path');
|
|
|
4
4
|
let fs = require('fs');
|
|
5
5
|
let glob = require('glob');
|
|
6
6
|
|
|
7
|
-
let
|
|
7
|
+
let session_vars = require('./session_vars');
|
|
8
8
|
|
|
9
9
|
// Get the glob filepaths to find all the test files
|
|
10
10
|
let dir_root = process.env.INIT_CWD; // Path to root of project
|
|
@@ -12,7 +12,7 @@ let test_glob = process.argv[2]; // String of glob (regex for filepaths)
|
|
|
12
12
|
let filepaths = glob.sync( _path.resolve( dir_root, test_glob ) );
|
|
13
13
|
let flag = '_lang_';
|
|
14
14
|
|
|
15
|
-
let langs =
|
|
15
|
+
let langs = session_vars.get_languages();
|
|
16
16
|
|
|
17
17
|
// Generate new language files
|
|
18
18
|
for ( let full_path of filepaths ) { // Handle old language files before creating new ones.
|
|
@@ -16,69 +16,22 @@ require('dotenv').config();
|
|
|
16
16
|
* much easier to test.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
const session_vars = {
|
|
20
|
-
PLAYGROUND_ID: process.env.PLAYGROUND_ID, // Need to get rid of this in favor of API
|
|
21
|
-
};
|
|
19
|
+
const session_vars = {};
|
|
22
20
|
|
|
23
21
|
module.exports = session_vars;
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
*
|
|
29
|
-
* @throws ReferenceError with a message for all missing variables.
|
|
30
|
-
*/
|
|
31
|
-
session_vars.validateEnvironment = function() {
|
|
32
|
-
|
|
33
|
-
// We are checking for BASE_URL, but we are referring it as SERVER_URL as that
|
|
34
|
-
// is the name used in GitHub secrets, which is what most devs will be using.
|
|
35
|
-
|
|
36
|
-
let errorMessage = '';
|
|
37
|
-
|
|
38
|
-
// Since this code will most often be run in GitHub, I'm going to build a single error message that outlines all missing variables. Otherwise, a developer
|
|
39
|
-
// will have to run their pipeline an incredible number of times to discover all the missing variables.
|
|
40
|
-
if (!process.env.DOCASSEMBLE_DEVELOPER_API_KEY)
|
|
41
|
-
{
|
|
42
|
-
errorMessage += `\nThe DOCASSEMBLE_DEVELOPER_API_KEY GitHub secret must be defined. The DOCASSEMBLE_DEVELOPER_API_KEY is a docassemble API key you created for your server's testing account. It should have developer permissions.`
|
|
43
|
-
}
|
|
44
|
-
if (!process.env.PLAYGROUND_ID)
|
|
45
|
-
{
|
|
46
|
-
errorMessage += '\nThe PLAYGROUND_ID GitHub secret must be defined. The PLAYGROUND_ID is the ID of the Docassemble suite to run.'
|
|
47
|
-
}
|
|
48
|
-
if (!process.env.SERVER_URL && !process.env.BASE_URL)
|
|
49
|
-
{
|
|
50
|
-
errorMessage += `\nThe SERVER_URL GitHub secret must be defined. The SERVER_URL is the URL of the Docassemble Server where the tests should be run.`;
|
|
51
|
-
}
|
|
52
|
-
if (!process.env.REPO_URL)
|
|
53
|
-
{
|
|
54
|
-
errorMessage += `\nThe REPO_URL GitHub secret must be defined. The REPO_URL is the URL to the Git repo whose Actions are being run.`;
|
|
55
|
-
}
|
|
56
|
-
if (!process.env.BRANCH_PATH && !process.env.BRANCH_NAME)
|
|
57
|
-
{
|
|
58
|
-
errorMessage += `\nThe BRANCH_NAME environment variable must be defined. The BRANCH_NAME is the name of the repository branch that should be pulled into the docassemble project.`;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
errorMessage = errorMessage.trim();
|
|
62
|
-
|
|
63
|
-
if (errorMessage !== '') {
|
|
64
|
-
throw new ReferenceError(errorMessage);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
session_vars.validateEnvironment();
|
|
23
|
+
session_vars.get_debug = function () { return process.env.DEBUG || null; };
|
|
24
|
+
session_vars.get_dev_api_key = function () { return process.env.DOCASSEMBLE_DEVELOPER_API_KEY || null; };
|
|
25
|
+
session_vars.get_repo_url = function () { return process.env.REPO_URL || null; };
|
|
69
26
|
|
|
70
|
-
session_vars.get_dev_api_key = function () { return process.env.DOCASSEMBLE_DEVELOPER_API_KEY; };
|
|
71
27
|
session_vars.get_da_server_url = function () {
|
|
72
|
-
|
|
73
|
-
|
|
28
|
+
try {
|
|
29
|
+
let url = process.env.SERVER_URL || process.env.BASE_URL;
|
|
30
|
+
return url.replace(/\/$/g, ''); // Remove any trailing slash for safety
|
|
31
|
+
} catch ( error ) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
74
34
|
};
|
|
75
|
-
session_vars.get_debug = function () { return process.env.DEBUG; };
|
|
76
|
-
session_vars.get_repo_url = function () { return process.env.REPO_URL; };
|
|
77
|
-
// missing/moving functionality:
|
|
78
|
-
// getBaseInterviewURL
|
|
79
|
-
// Project name setting/getting
|
|
80
|
-
// Playground id functionality needs to be transfered to api requests
|
|
81
|
-
|
|
82
35
|
|
|
83
36
|
session_vars.get_branch_name = function () {
|
|
84
37
|
/* Get the name of the repository's branch that is being tested */
|
|
@@ -102,29 +55,6 @@ session_vars.get_project_base_name = function () {
|
|
|
102
55
|
return sanitized_name;
|
|
103
56
|
};
|
|
104
57
|
|
|
105
|
-
// // Notes: We were using `new_session=1` in the url args, but it wasn't
|
|
106
|
-
// // always working. The idea was to save each session so we could look
|
|
107
|
-
// // back on it if needed. Aside from the fact that you usually need to log in
|
|
108
|
-
// // to make the sessions retrievable (though if you're using `interview_list()`
|
|
109
|
-
// // you can get them anyway), it also has inconsistent behavior when
|
|
110
|
-
// // `sessions are unique`` or `temporary session` or use `interview_list()`
|
|
111
|
-
// // and/or respond immediately with a `command()`. Three ways to avoid this:
|
|
112
|
-
// // 1. x Start a new browser instead of just a new page each time. Lengthens the tests.
|
|
113
|
-
// // 1. √ Visit `/user/sign-out` (needed even if the user is not logged in)
|
|
114
|
-
// // 1. x (seems to be causing a 'Unable to locate interview session' error
|
|
115
|
-
// // instead) Use `reset=2` instead , which will not save the previous session at all. It
|
|
116
|
-
// // Will not just restart any existing interview sessions, it will also
|
|
117
|
-
// // clear out the browser session's memory of what other interviews the user has
|
|
118
|
-
// // visited in the same browser session_vars.
|
|
119
|
-
// session_vars.getBaseInterviewURL = function () {
|
|
120
|
-
// /* Return the part of the interview URL that comes before the filename.
|
|
121
|
-
// * Depends on the project name, which may have been changed. */
|
|
122
|
-
// let new_session = `/interview?new_session=1&i=docassemble.playground`;
|
|
123
|
-
// return `${ session_vars.BASE_URL }${ new_session }${ session_vars.PLAYGROUND_ID }${ session_vars.getProjectName() }%3A`;
|
|
124
|
-
// };
|
|
125
|
-
// // session_vars.BASE_INTERVIEW_URL = session_vars.getBaseInterviewURL();
|
|
126
|
-
|
|
127
|
-
|
|
128
58
|
session_vars.get_languages = function () {
|
|
129
59
|
/* Returns an array of strings, names of languages that should be tested. */
|
|
130
60
|
|
|
@@ -186,3 +116,47 @@ session_vars.delete_project_name = function () {
|
|
|
186
116
|
return false;
|
|
187
117
|
}
|
|
188
118
|
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Ensure all required environment variables exist. Add each missing variable
|
|
122
|
+
* to an error that will be thrown at the end.
|
|
123
|
+
*
|
|
124
|
+
* @throws ReferenceError with a message for all missing variables.
|
|
125
|
+
*/
|
|
126
|
+
session_vars.validateEnvironment = function() {
|
|
127
|
+
/** Throw a useful error for the developer if any of the required env vars
|
|
128
|
+
* are missing. For most devs, these will be GitHub secrets. */
|
|
129
|
+
|
|
130
|
+
// Note: We are checking for BASE_URL, but we are referring it as SERVER_URL as that
|
|
131
|
+
// is the name used in GitHub secrets, which is what most devs will be using.
|
|
132
|
+
|
|
133
|
+
let errorMessage = '';
|
|
134
|
+
|
|
135
|
+
// Since this code will most often be run in GitHub, I'm going to build a single error message that outlines all missing variables. Otherwise, a developer
|
|
136
|
+
// will have to run their pipeline an incredible number of times to discover all the missing variables.
|
|
137
|
+
if ( !session_vars.get_dev_api_key() )
|
|
138
|
+
{
|
|
139
|
+
errorMessage += `\nThe DOCASSEMBLE_DEVELOPER_API_KEY GitHub secret must be defined. The DOCASSEMBLE_DEVELOPER_API_KEY is a docassemble API key you created for your server's testing account. It should have developer permissions.`
|
|
140
|
+
}
|
|
141
|
+
if ( !session_vars.get_da_server_url() )
|
|
142
|
+
{
|
|
143
|
+
errorMessage += `\nThe SERVER_URL GitHub secret must be defined. The SERVER_URL is the URL of the Docassemble Server where the tests should be run.`;
|
|
144
|
+
}
|
|
145
|
+
if ( !session_vars.get_repo_url() )
|
|
146
|
+
{
|
|
147
|
+
errorMessage += `\nThe REPO_URL GitHub secret must be defined. The REPO_URL is the URL to the Git repo whose Actions are being run.`;
|
|
148
|
+
}
|
|
149
|
+
// The branch name is always automatically defined in Github, it'll be missing only if you're running locally and missing an env var.
|
|
150
|
+
if ( !session_vars.get_branch_name() )
|
|
151
|
+
{
|
|
152
|
+
errorMessage += `\nThe BRANCH_NAME environment variable must be defined. The BRANCH_NAME is the name of the repository branch that should be pulled into the docassemble project.`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
errorMessage = errorMessage.trim();
|
|
156
|
+
|
|
157
|
+
if (errorMessage !== '') {
|
|
158
|
+
throw new ReferenceError(errorMessage);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
session_vars.validateEnvironment();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suffolklitlab/alkiln",
|
|
3
|
-
"version": "4.0.0
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Integrated automated end-to-end testing with docassemble, puppeteer, and cucumber.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
|
-
"url": "git+https://github.com/SuffolkLITLab/
|
|
20
|
+
"url": "git+https://github.com/SuffolkLITLab/ALKiln.git"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"docassemble",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"author": "",
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"bugs": {
|
|
33
|
-
"url": "https://github.com/SuffolkLITLab/
|
|
33
|
+
"url": "https://github.com/SuffolkLITLab/ALKiln/issues"
|
|
34
34
|
},
|
|
35
|
-
"homepage": "https://suffolklitlab.
|
|
35
|
+
"homepage": "https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/automated_integrated_testing/",
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@cucumber/cucumber": "^7.3.2",
|
|
38
38
|
"axios": "^0.24.0",
|
|
@@ -48,7 +48,6 @@
|
|
|
48
48
|
"bin": {
|
|
49
49
|
"alkiln-setup": "./lib/docassemble/setup.js",
|
|
50
50
|
"alkiln-takedown": "./lib/docassemble/takedown.js",
|
|
51
|
-
"alkiln-cucumber": "./lib/index.js",
|
|
52
51
|
"alkiln-langs": "./lib/utils/langs.js"
|
|
53
52
|
}
|
|
54
53
|
}
|
|
@@ -4,13 +4,13 @@ Feature: Establishing steps
|
|
|
4
4
|
Steps that establish things about the state of the test
|
|
5
5
|
# In tag names, 'e' is for 'establishing'
|
|
6
6
|
|
|
7
|
-
@slow @e1
|
|
7
|
+
@slow @e1 @wait
|
|
8
8
|
Scenario: I am able to set a custom wait time that allows steps to run longer than the half minute default
|
|
9
9
|
Given I start the interview at "all_tests"
|
|
10
10
|
And the max seconds for each step in this scenario is 40
|
|
11
11
|
And I wait 35 seconds
|
|
12
12
|
|
|
13
|
-
@slow @e2
|
|
13
|
+
@slow @e2 @wait
|
|
14
14
|
Scenario: I am able to set a custom wait time before an interview has been loaded
|
|
15
15
|
Given the max seconds for each step in this scenario is 40
|
|
16
16
|
And I start the interview at "all_tests"
|
|
@@ -96,7 +96,7 @@ Scenario: Test "Then I don’t continue" with an apostrophe
|
|
|
96
96
|
Then I don’t continue
|
|
97
97
|
And I will be told an answer is invalid
|
|
98
98
|
|
|
99
|
-
@fast @o9
|
|
99
|
+
@fast @o9 @table
|
|
100
100
|
Scenario: I can match JSON page var to str
|
|
101
101
|
Given I start the interview at "all_tests.yml"
|
|
102
102
|
And I get to "showifs" with this data:
|
|
@@ -138,7 +138,7 @@ Scenario: Fail with missing link with url
|
|
|
138
138
|
And I start the interview at "all_tests"
|
|
139
139
|
Then I should see the link to "http://missing-url.com"
|
|
140
140
|
|
|
141
|
-
@slow @rf13 @error
|
|
141
|
+
@slow @rf13 @error @table
|
|
142
142
|
Scenario: Fail with link with given text does not lead to correct url
|
|
143
143
|
Given the final Scenario status should be "failed"
|
|
144
144
|
Given the Scenario report should include:
|
|
@@ -166,7 +166,7 @@ Scenario: Fail with link with given text does not lead to correct url
|
|
|
166
166
|
And I should see the link to "http://ecosia.org/"
|
|
167
167
|
Then the "Link to external page" link leads to "http://wrong-url.com"
|
|
168
168
|
|
|
169
|
-
@slow @rf14 @error
|
|
169
|
+
@slow @rf14 @error @table
|
|
170
170
|
Scenario: Fail with link unexpectedly opens in same window
|
|
171
171
|
Given the final Scenario status should be "failed"
|
|
172
172
|
Given the Scenario report should include:
|
|
@@ -194,7 +194,7 @@ Scenario: Fail with link unexpectedly opens in same window
|
|
|
194
194
|
And I should see the link to "http://ecosia.org/"
|
|
195
195
|
Then the "Link to external page" link opens in the same window
|
|
196
196
|
|
|
197
|
-
@fast @rf15 @error
|
|
197
|
+
@fast @rf15 @error @table
|
|
198
198
|
Scenario: Fail with link unexpectedly opens in a new window
|
|
199
199
|
Given the final Scenario status should be "failed"
|
|
200
200
|
Given the Scenario report should include:
|
|
@@ -223,7 +223,7 @@ Scenario: Fail with link unexpectedly opens in a new window
|
|
|
223
223
|
Then the "Link: reload the page" link opens in a new window
|
|
224
224
|
|
|
225
225
|
## Don't currently have a broken link to test and this Step is not officially supported
|
|
226
|
-
#@fast @rf16 @error
|
|
226
|
+
#@fast @rf16 @error @table
|
|
227
227
|
#Scenario: Fail with link leads to a broken page
|
|
228
228
|
# Given the final Scenario status should be "failed"
|
|
229
229
|
# Given the Scenario report should include:
|
|
@@ -321,7 +321,7 @@ Scenario: Fail with system error after Step using wrong file name as trigger
|
|
|
321
321
|
# """
|
|
322
322
|
# And I start the interview at "wrong_yaml_filename"
|
|
323
323
|
|
|
324
|
-
@fast @rf22
|
|
324
|
+
@fast @rf22 @table
|
|
325
325
|
Scenario: I can't match JSON page var to str
|
|
326
326
|
Given the final Scenario status should be "failed"
|
|
327
327
|
Given the Scenario report should include:
|
|
@@ -376,6 +376,16 @@ Scenario: Fail with 2 wrong signin secrets
|
|
|
376
376
|
"""
|
|
377
377
|
Given I sign in with the email "WRONG_EMAIL_NAME" and the password "WRONG_PASSWORD_NAME"
|
|
378
378
|
|
|
379
|
+
@fast @rf25 @upload
|
|
380
|
+
Scenario: Fail with could not find files
|
|
381
|
+
Given the final Scenario status should be "failed"
|
|
382
|
+
Given the Scenario report should include:
|
|
383
|
+
"""
|
|
384
|
+
Could not find "nonexistant1.pdf, nonexistant2.pdf"
|
|
385
|
+
"""
|
|
386
|
+
Given I start the interview at "all_tests"
|
|
387
|
+
And I upload "nonexistant1.pdf, nonexistant2.pdf" to "upload_files_visible"
|
|
388
|
+
|
|
379
389
|
# scope.js
|
|
380
390
|
# I upload "___" to "___"
|
|
381
391
|
# No need to test wrong var name
|
|
@@ -384,6 +394,7 @@ Scenario: Fail with 2 wrong signin secrets
|
|
|
384
394
|
#
|
|
385
395
|
# I sign
|
|
386
396
|
|
|
397
|
+
|
|
387
398
|
# ===============================
|
|
388
399
|
# Reports for Scenarios with warnings
|
|
389
400
|
# ===============================
|
|
@@ -448,70 +459,27 @@ Scenario: Report still shows page id when I tap to continue without setting any
|
|
|
448
459
|
# Next page (showifs ID SHOULD BE SHOWN IN REPORT)
|
|
449
460
|
Then the question id should be "buttons yesnomaybe"
|
|
450
461
|
|
|
451
|
-
@slow @rp2
|
|
462
|
+
@slow @rp2 @table
|
|
452
463
|
Scenario: Report lists unused table rows
|
|
453
464
|
Given the final Scenario status should be "passed"
|
|
454
465
|
Given the Scenario report should include:
|
|
455
466
|
"""
|
|
456
|
-
|
|
457
|
-
---------------
|
|
458
|
-
Scenario: Report lists unused table rows
|
|
459
|
-
Tags: @reports @slow @rp2
|
|
460
|
-
---------------
|
|
461
|
-
screen id: upload-files
|
|
462
|
-
screen id: group-of-complex-fields
|
|
463
|
-
| single_quote_dict['single_quote_key']['sq_two'] | true | |
|
|
464
|
-
| double_quote_dict[\"double_quote_key\"]['dq_two'] | true | |
|
|
465
|
-
|
|
466
|
-
Rows that got set:
|
|
467
|
-
And I get to the question id "direct standard fields" with this data:
|
|
468
|
-
| var | value | trigger |
|
|
469
|
-
| double_quote_dict[\"double_quote_key\"]['dq_two'] | true | |
|
|
470
|
-
| single_quote_dict['single_quote_key']['sq_two'] | true | |
|
|
471
467
|
Unused rows:
|
|
472
468
|
| extra_2 | extra 2 | |
|
|
473
469
|
| extra_out_of_alphabetical_order | extra 1 | |
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
| radio_yesno | False | false |
|
|
478
|
-
| radio_other | radio_other_opt_3 | |
|
|
479
|
-
| text_input | Regular text input field value | |
|
|
480
|
-
| textarea | Multiline text\narea value | |
|
|
481
|
-
| dropdown_test | dropdown_opt_2 | |
|
|
482
|
-
|
|
483
|
-
Rows that got set:
|
|
484
|
-
And I get to the question id "showifs" with this data:
|
|
485
|
-
| var | value | trigger |
|
|
486
|
-
| checkboxes_other['checkbox_other_opt_1'] | true | |
|
|
487
|
-
| dropdown_test | dropdown_opt_2 | |
|
|
488
|
-
| radio_other | radio_other_opt_3 | |
|
|
489
|
-
| radio_yesno | False | false |
|
|
490
|
-
| text_input | Regular text input field value | |
|
|
491
|
-
| textarea | Multiline text\narea value | |
|
|
470
|
+
"""
|
|
471
|
+
Given the Scenario report should include:
|
|
472
|
+
"""
|
|
492
473
|
Unused rows:
|
|
493
474
|
| extra_3 | extra 3 | |
|
|
494
475
|
| extra_4 | extra 4 | |
|
|
495
476
|
| extra_5 | extra 5 | |
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
| buttons_yesnomaybe | True | |
|
|
500
|
-
screen id: buttons-other
|
|
501
|
-
| buttons_other | button_2 | |
|
|
502
|
-
screen id: button-continue
|
|
503
|
-
| button_continue | True | |
|
|
504
|
-
|
|
505
|
-
Rows that got set:
|
|
506
|
-
And I get to the question id "screen features" with this data:
|
|
507
|
-
| var | value | trigger |
|
|
508
|
-
| button_continue | True | |
|
|
509
|
-
| buttons_other | button_2 | |
|
|
510
|
-
| buttons_yesnomaybe | True | |
|
|
477
|
+
"""
|
|
478
|
+
Given the Scenario report should include:
|
|
479
|
+
"""
|
|
511
480
|
Unused rows:
|
|
512
481
|
| extra_6 | extra 6 | |
|
|
513
482
|
| extra_7 | extra 7 | |
|
|
514
|
-
|
|
515
483
|
"""
|
|
516
484
|
And I start the interview at "all_tests"
|
|
517
485
|
And I get to "direct standard fields" with this data:
|
|
@@ -7,6 +7,8 @@ const fields = require('./fields.fixtures.js');
|
|
|
7
7
|
const matches = require('./matches.fixtures.js');
|
|
8
8
|
const scope = require('../../lib/scope.js');
|
|
9
9
|
const getMatchingRows = scope.getMatchingRows;
|
|
10
|
+
// Match state var instantiated in steps.js. TODO: Add tests for such rows.
|
|
11
|
+
scope.row_needs_trigger_flag = `ALKiln: no trigger variable needed`;
|
|
10
12
|
|
|
11
13
|
// TODO: Add tests for reports
|
|
12
14
|
|
|
@@ -188,6 +190,32 @@ describe(`For mulitple rows with the same proxies`, async function() {
|
|
|
188
190
|
}
|
|
189
191
|
});
|
|
190
192
|
|
|
193
|
+
// Missing table row for loop
|
|
194
|
+
describe(`For a second proxy loop page,`, async function() {
|
|
195
|
+
for ( let test_i = 0; test_i < fields.proxies_multi.length; test_i++ ) {
|
|
196
|
+
let field = fields.proxies_multi[ test_i ];
|
|
197
|
+
let curr_matches = matches.proxies_missing_loop[ test_i ];
|
|
198
|
+
let name = getSafeName( field );
|
|
199
|
+
it( `does not find any matches when table row for second loop page is missing`, async function() {
|
|
200
|
+
let result = await getMatchingRows( scope, { field, var_data: tables.proxies_missing_loop });
|
|
201
|
+
expect( result ).to.deep.equal( curr_matches );
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Missing trigger matches second loop
|
|
207
|
+
describe(`For a second proxy loop page,`, async function() {
|
|
208
|
+
for ( let test_i = 0; test_i < fields.proxies_multi.length; test_i++ ) {
|
|
209
|
+
let field = fields.proxies_multi[ test_i ];
|
|
210
|
+
let curr_matches = matches.proxies_missing_trigger[ test_i ];
|
|
211
|
+
let name = getSafeName( field );
|
|
212
|
+
it( `matches with a missing trigger row with the correct variable name`, async function() {
|
|
213
|
+
let result = await getMatchingRows( scope, { field, var_data: tables.proxies_missing_trigger });
|
|
214
|
+
expect( result ).to.deep.equal( curr_matches );
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
191
219
|
|
|
192
220
|
// ============================
|
|
193
221
|
// Signature
|
|
@@ -15,7 +15,7 @@ matches.standard = [
|
|
|
15
15
|
[],
|
|
16
16
|
[ { var: 'radio_other', value: 'radio_other_opt_2' } ],
|
|
17
17
|
[],
|
|
18
|
-
[ { var: 'text_input', value: 'Some one-line text' }, { var: 'text_input', value: 'Some conflicting text' } ],
|
|
18
|
+
[ { var: 'text_input', value: 'Some one-line text', "original": { var: 'text_input', value: 'Some one-line text' } }, { var: 'text_input', value: 'Some conflicting text', "original": { var: 'text_input', value: 'Some conflicting text' } } ],
|
|
19
19
|
[ { var: 'textarea', value: 'Some\nmulti-line\ntext' } ],
|
|
20
20
|
[ { 'var': 'date_input','value':'today-1' } ],
|
|
21
21
|
[ { var: 'dropdown_test', value: 'dropdown_opt_2' } ],
|
|
@@ -111,6 +111,18 @@ matches.proxies_multi = [
|
|
|
111
111
|
[]
|
|
112
112
|
];
|
|
113
113
|
|
|
114
|
+
// Missing table row for second loop
|
|
115
|
+
matches.proxies_missing_loop = [
|
|
116
|
+
[],
|
|
117
|
+
[]
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
// Missing trigger matches second loop
|
|
121
|
+
matches.proxies_missing_trigger = [
|
|
122
|
+
[{ "trigger": "", "var": "x[i].name.first", "value": "Firstname", "original": { "trigger": "", "var": "x[i].name.first", "value": "Firstname" }}],
|
|
123
|
+
[]
|
|
124
|
+
];
|
|
125
|
+
|
|
114
126
|
|
|
115
127
|
// ============================
|
|
116
128
|
// Signature
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const chai = require('chai');
|
|
2
|
+
const expect = chai.expect;
|
|
3
|
+
|
|
4
|
+
const session_vars = require("../../lib/utils/session_vars.js");
|
|
5
|
+
const validateEnvironment = session_vars.validateEnvironment;
|
|
6
|
+
|
|
7
|
+
describe('When the `session_vars` object uses', function () {
|
|
8
|
+
describe('validateEnvironment, it', function() {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* All required variables should be defined in .env. For reference, those variables are the following:
|
|
12
|
+
*
|
|
13
|
+
* DOCASSEMBLE_DEVELOPER_API_KEY
|
|
14
|
+
* BASE_URL
|
|
15
|
+
* REPO_URL
|
|
16
|
+
*/
|
|
17
|
+
it("successfully completes when all required env vars exist", function() {
|
|
18
|
+
session_vars.validateEnvironment();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* This test has an ordering dependency with the test below. I'm not certain if I am getting lucky or if I need to explicitly declare the order.
|
|
23
|
+
*/
|
|
24
|
+
it("throws a reference error when any var is missing", function() {
|
|
25
|
+
delete process.env.DOCASSEMBLE_DEVELOPER_API_KEY;
|
|
26
|
+
|
|
27
|
+
expect(session_vars.validateEnvironment).to.throw(ReferenceError, /DOCASSEMBLE_DEVELOPER_API_KEY/);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Delete all environment variables before validating the variables.
|
|
32
|
+
*/
|
|
33
|
+
it("names all missing variables in the error, not just one", function() {
|
|
34
|
+
delete process.env.DOCASSEMBLE_DEVELOPER_API_KEY;
|
|
35
|
+
delete process.env.BASE_URL;
|
|
36
|
+
delete process.env.SERVER_URL;
|
|
37
|
+
delete process.env.REPO_URL;
|
|
38
|
+
|
|
39
|
+
// This test just tests that the variable names show up in a fixed order.
|
|
40
|
+
expect(session_vars.validateEnvironment).to.throw(
|
|
41
|
+
ReferenceError,
|
|
42
|
+
/DOCASSEMBLE_DEVELOPER_API_KEY.*\n.*SERVER_URL.*\n.*REPO_URL/
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -21,8 +21,8 @@ tables.standard = [
|
|
|
21
21
|
{ "var": "date_input","value":"today-1" },
|
|
22
22
|
{ "var": "radio_yesno", "value": "False" },
|
|
23
23
|
{ "var": "radio_other", "value": "radio_other_opt_2" },
|
|
24
|
-
{ "var": "text_input", "value": "Some one-line text" },
|
|
25
|
-
{ "var": "text_input","value":"Some conflicting text" },
|
|
24
|
+
{ "var": "text_input", "value": "Some one-line text", "original": { "var": "text_input", "value": "Some one-line text" } },
|
|
25
|
+
{ "var": "text_input","value":"Some conflicting text", "original": { "var": "text_input","value":"Some conflicting text" } },
|
|
26
26
|
{ "var": "textarea", "value": "Some\nmulti-line\ntext" },
|
|
27
27
|
{ "var": "dropdown_test", "value": "dropdown_opt_2" }, // May want to change `checked`
|
|
28
28
|
];
|
|
@@ -373,6 +373,16 @@ tables.proxies_multi = [
|
|
|
373
373
|
{ "trigger": "proxy_list[2].name.first", "var": "x[i].name.first", "value": "Firstname", },
|
|
374
374
|
];
|
|
375
375
|
|
|
376
|
+
// Missing table row for second loop
|
|
377
|
+
tables.proxies_missing_loop = [
|
|
378
|
+
{ "trigger": "proxy_list[0].name.first", "var": "x[i].name.first", "value": "Firstname", "original": { "trigger": "proxy_list[0].name.first", "var": "x[i].name.first", "value": "Firstname" } },
|
|
379
|
+
];
|
|
380
|
+
|
|
381
|
+
// Missing trigger matches second loop
|
|
382
|
+
tables.proxies_missing_trigger = [
|
|
383
|
+
{ "trigger": "", "var": "x[i].name.first", "value": "Firstname", "original": { "trigger": "", "var": "x[i].name.first", "value": "Firstname" }},
|
|
384
|
+
];
|
|
385
|
+
|
|
376
386
|
|
|
377
387
|
// ============================
|
|
378
388
|
// Signature
|