@suffolklitlab/alkiln 3.0.9 → 4.0.0-pre-api.4
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/.github/workflows/test_tests.yml +11 -2
- package/CHANGELOG.md +22 -20
- package/action.yml +42 -32
- package/lib/cucumber_8_shim.js +25 -0
- package/lib/docassemble/docassemble_api_REST.js +130 -0
- package/lib/docassemble/docassemble_api_interface.js +404 -0
- package/lib/docassemble/setup.js +38 -0
- package/lib/docassemble/takedown.js +18 -0
- package/lib/scope.js +337 -60
- package/lib/steps.js +209 -138
- package/lib/utils/env_vars.js +73 -69
- package/lib/utils/log.js +51 -0
- package/lib/utils/session_vars.js +188 -0
- package/lib/utils/time.js +26 -0
- package/lib/world.js +2 -2
- package/package.json +13 -12
- package/tests/features/establishing_steps.feature +15 -0
- package/tests/features/observation_steps.feature +31 -0
- package/tests/features/reports.feature +70 -12
- package/lib/github_integration/install-branch.js +0 -84
- package/lib/github_integration/puppeteer-utils.js +0 -224
- package/lib/github_integration/setup.js +0 -4
- package/lib/github_integration/takedown.js +0 -4
package/lib/utils/env_vars.js
CHANGED
|
@@ -2,6 +2,8 @@ const fs = require('fs');
|
|
|
2
2
|
|
|
3
3
|
require('dotenv').config();
|
|
4
4
|
|
|
5
|
+
const session_vars = require( './session_vars' );
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* This code assumes that this module is run as part of a GitHub Action. If the
|
|
7
9
|
* customer is running it as a CLI tool, then they are on their own.
|
|
@@ -76,66 +78,66 @@ const env_vars = {
|
|
|
76
78
|
|
|
77
79
|
env_vars.validateEnvironment();
|
|
78
80
|
|
|
79
|
-
// Path could be 'refs/branch_name' or 'refs/head/branch_name' and maybe other things
|
|
80
|
-
// Assume branch name is last part of branch path
|
|
81
|
-
if ( process.env.BRANCH_PATH ) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
} else {
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// ---- Project name ----
|
|
89
|
-
let no_starting_digit = ( 'testing' + env_vars.BRANCH_NAME ).replace( /^[0-9]+/i, '' );
|
|
90
|
-
env_vars.PROJECT_BASE_NAME = no_starting_digit.replace( /[^A-Za-z0-9]+/gi, '' );
|
|
91
|
-
|
|
92
|
-
const project_name_file_path = '_al_test_project_name.json';
|
|
93
|
-
env_vars.setProjectName = function ( value ) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
env_vars.getProjectName = function () {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
env_vars.cleanUpProjectName = function () {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
};
|
|
81
|
+
// // Path could be 'refs/branch_name' or 'refs/head/branch_name' and maybe other things
|
|
82
|
+
// // Assume branch name is last part of branch path
|
|
83
|
+
// if ( process.env.BRANCH_PATH ) {
|
|
84
|
+
// let split = process.env.BRANCH_PATH.split('/');
|
|
85
|
+
// env_vars.BRANCH_NAME = split[ split.length - 1 ];
|
|
86
|
+
// } else {
|
|
87
|
+
// env_vars.BRANCH_NAME = 'test'
|
|
88
|
+
// }
|
|
89
|
+
|
|
90
|
+
// // ---- Project name ----
|
|
91
|
+
// let no_starting_digit = ( 'testing' + env_vars.BRANCH_NAME ).replace( /^[0-9]+/i, '' );
|
|
92
|
+
// env_vars.PROJECT_BASE_NAME = no_starting_digit.replace( /[^A-Za-z0-9]+/gi, '' );
|
|
93
|
+
|
|
94
|
+
// const project_name_file_path = '_al_test_project_name.json';
|
|
95
|
+
// env_vars.setProjectName = function ( value ) {
|
|
96
|
+
// // As long as it's a string, it can be made safe for a project name
|
|
97
|
+
// if ( typeof value !== 'string' ) { throw new TypeError(`The project's name must start as a string. It was ${ value }.`); }
|
|
98
|
+
// // Make the name safe for a project name
|
|
99
|
+
// let no_starting_digit = value.replace( /^[0-9]+/i, '' );
|
|
100
|
+
// let alphanumeric = no_starting_digit.replace( /[^A-Za-z0-9]+/gi, '' );
|
|
101
|
+
// // Create or modify a file to store the actual name of the project
|
|
102
|
+
// // for later deletion as internal values and context get destroyed before
|
|
103
|
+
// // the takedown command that comes later. It's a string, not a list, to avoid
|
|
104
|
+
// // the list getting out of date and deleting another test's project.
|
|
105
|
+
// fs.writeFileSync( project_name_file_path, JSON.stringify( alphanumeric ));
|
|
106
|
+
// console.log( `Saved new project name: ${ alphanumeric }` );
|
|
107
|
+
|
|
108
|
+
// return alphanumeric;
|
|
109
|
+
// }
|
|
110
|
+
|
|
111
|
+
// env_vars.getProjectName = function () {
|
|
112
|
+
// /* Get the stored name of the project that was created on the
|
|
113
|
+
// * server - the base project name might have been adjusted to
|
|
114
|
+
// * avoid overwriting existing project. */
|
|
115
|
+
// if ( env_vars.DEBUG ) { console.trace( `Getting project name` ); }
|
|
116
|
+
// let actual_proj_name = null;
|
|
117
|
+
// // Avoid race coditions possibly caused by checking for existence first
|
|
118
|
+
// try {
|
|
119
|
+
// actual_proj_name = JSON.parse( fs.readFileSync( project_name_file_path ));
|
|
120
|
+
// if ( env_vars.DEBUG ) { console.log( `Project name from file is ${ actual_proj_name }.` ); }
|
|
121
|
+
// } catch ( error ) {} // Do nothing
|
|
122
|
+
|
|
123
|
+
// // If no such file existed or value was invalid, set up the file with a basic name
|
|
124
|
+
// if ( !actual_proj_name ) {
|
|
125
|
+
// actual_proj_name = env_vars.setProjectName( env_vars.PROJECT_BASE_NAME );
|
|
126
|
+
// }
|
|
127
|
+
|
|
128
|
+
// if ( env_vars.DEBUG ) { console.log( `Processed project name is "${ actual_proj_name }"` ); }
|
|
129
|
+
// return actual_proj_name;
|
|
130
|
+
// };
|
|
131
|
+
|
|
132
|
+
// env_vars.cleanUpProjectName = function () {
|
|
133
|
+
// /* Delete stored name of project */
|
|
134
|
+
// // Avoid race coditions possibly caused by checking for existence first
|
|
135
|
+
// // Delete file if possible
|
|
136
|
+
// try { fs.unlinkSync( project_name_file_path ); }
|
|
137
|
+
// catch ( error ) {
|
|
138
|
+
// console.warn(`After trying to delete the project created for the test, the file containing the name of project did not exist. ${ error }`)
|
|
139
|
+
// }
|
|
140
|
+
// };
|
|
139
141
|
|
|
140
142
|
// Notes: We were using `new_session=1` in the url args, but it wasn't
|
|
141
143
|
// always working. The idea was to save each session so we could look
|
|
@@ -155,19 +157,21 @@ env_vars.getBaseInterviewURL = function () {
|
|
|
155
157
|
/* Return the part of the interview URL that comes before the filename.
|
|
156
158
|
* Depends on the project name, which may have been changed. */
|
|
157
159
|
let new_session = `/interview?new_session=1&i=docassemble.playground`;
|
|
158
|
-
return `${
|
|
160
|
+
return `${ session_vars.get_da_server_url() }${ new_session }${ env_vars.PLAYGROUND_ID }${ session_vars.get_project_name() }%3A`;
|
|
159
161
|
};
|
|
160
162
|
env_vars.BASE_INTERVIEW_URL = env_vars.getBaseInterviewURL();
|
|
161
163
|
|
|
162
164
|
|
|
163
|
-
// These are actually the words that are on the buttons or links
|
|
164
|
-
// that change the language of the interview. Have not yet detected
|
|
165
|
-
// another distinguishing feature
|
|
166
|
-
if ( process.env.EXTRA_LANGUAGES && process.env.EXTRA_LANGUAGES !== 'default' ) {
|
|
167
|
-
|
|
168
|
-
} else {
|
|
169
|
-
|
|
170
|
-
}
|
|
165
|
+
// // These are actually the words that are on the buttons or links
|
|
166
|
+
// // that change the language of the interview. Have not yet detected
|
|
167
|
+
// // another distinguishing feature
|
|
168
|
+
// if ( process.env.EXTRA_LANGUAGES && process.env.EXTRA_LANGUAGES !== 'default' ) {
|
|
169
|
+
// env_vars.EXTRA_LANGUAGES = process.env.EXTRA_LANGUAGES.split(', ');
|
|
170
|
+
// } else {
|
|
171
|
+
// env_vars.EXTRA_LANGUAGES = [];
|
|
172
|
+
// }
|
|
173
|
+
|
|
174
|
+
env_vars.EXTRA_LANGUAGES = session_vars.get_languages();
|
|
171
175
|
|
|
172
176
|
|
|
173
177
|
module.exports = env_vars;
|
package/lib/utils/log.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const session_vars = require( './session_vars' );
|
|
2
|
+
|
|
3
|
+
let log = {};
|
|
4
|
+
module.exports = log;
|
|
5
|
+
|
|
6
|
+
let create_msg_start = function ( types, pre='' ) {
|
|
7
|
+
let parts = [ `ALKiln`, ...types ];
|
|
8
|
+
let start = parts.join(` `);
|
|
9
|
+
return `${ start }: ${ pre }`;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
log.info = function ({ type='', pre='', data='', post='' }) {
|
|
13
|
+
/* Log info msg with the given information and strings, prepended with `ALKiln`.
|
|
14
|
+
* `type` is often something like 'setup', 'takedown', etc. */
|
|
15
|
+
let start = create_msg_start([ type ], pre );
|
|
16
|
+
// Log them each on a separate line
|
|
17
|
+
console.info( `${ start }` );
|
|
18
|
+
if ( data ) { console.info( data ); }
|
|
19
|
+
if ( post ) { console.info( post ); }
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
log.warn = function ({ type='', pre='', data='', post='' }) {
|
|
23
|
+
/* Log warning msg with the given information and strings, prepended with `ALKiln`.
|
|
24
|
+
* `type` is often something like 'setup', 'takedown', etc. */
|
|
25
|
+
let start = create_msg_start([ type, `WARNING` ], pre );
|
|
26
|
+
// Log them each on a separate line
|
|
27
|
+
console.warn( `${ start }` );
|
|
28
|
+
if ( data ) { console.warn( data ); }
|
|
29
|
+
if ( post ) { console.warn( post ); }
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
log.error = function ({ type='', pre='', data='', post='' }) {
|
|
33
|
+
/* Log error msg with the given information and strings, prepended with `ALKiln`.
|
|
34
|
+
* `type` is often something like 'setup', 'takedown', etc. */
|
|
35
|
+
let start = create_msg_start([ type, `ERROR` ], pre );
|
|
36
|
+
// Log them each on a separate line with extra new lines around the whole thing
|
|
37
|
+
console.error( `\n${ start }` );
|
|
38
|
+
if ( data ) { console.error( data ); }
|
|
39
|
+
if ( post ) { console.error( post, `\n` ); }
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
log.debug = function ({ type='', pre='', data='', post='' }) {
|
|
43
|
+
/* If debugging is turned on, log a message that includes `ALKiln` and `debug` */
|
|
44
|
+
if ( session_vars.get_debug() ) {
|
|
45
|
+
let start = create_msg_start([ type, 'debug' ], pre );
|
|
46
|
+
// Log them each on a separate line
|
|
47
|
+
console.log( `ALKiln ${ type } debug: ${ pre }` );
|
|
48
|
+
if ( data ) { console.log( data ); }
|
|
49
|
+
if ( post ) { console.log( post ); }
|
|
50
|
+
}
|
|
51
|
+
};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
require('dotenv').config();
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This code assumes that this module is run as part of a GitHub Action. If the
|
|
7
|
+
* customer is running it as a CLI tool, then they won't get useful messages yet.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* This file provides user info variables. E.g. server address. They're either
|
|
11
|
+
* `process.env` vars or vars that have been built from `process.env` vars.
|
|
12
|
+
* It is meant to avoid duplication, make testing easier, and leave room for
|
|
13
|
+
* future maninpulation. No other file should need to use `process.env`.
|
|
14
|
+
*
|
|
15
|
+
* We have a bunch of `.get_foo()` functions partly because it makes the code
|
|
16
|
+
* much easier to test.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const session_vars = {
|
|
20
|
+
PLAYGROUND_ID: process.env.PLAYGROUND_ID, // Need to get rid of this in favor of API
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
module.exports = session_vars;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Ensure all required environment variables exist. Add each missing variable
|
|
27
|
+
* to an error that will be thrown at the end.
|
|
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();
|
|
69
|
+
|
|
70
|
+
session_vars.get_dev_api_key = function () { return process.env.DOCASSEMBLE_DEVELOPER_API_KEY; };
|
|
71
|
+
session_vars.get_da_server_url = function () {
|
|
72
|
+
let url = process.env.SERVER_URL || process.env.BASE_URL;
|
|
73
|
+
return url.replace(/\/$/g, ''); // Remove any trailing slash for safety
|
|
74
|
+
};
|
|
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
|
+
|
|
83
|
+
session_vars.get_branch_name = function () {
|
|
84
|
+
/* Get the name of the repository's branch that is being tested */
|
|
85
|
+
let branch_name = null;
|
|
86
|
+
if ( process.env.BRANCH_PATH ) {
|
|
87
|
+
branch_name = process.env.BRANCH_PATH.replace( `refs/head/`, '' );
|
|
88
|
+
} else if ( process.env.BRANCH_NAME ) {
|
|
89
|
+
branch_name = process.env.BRANCH_NAME;
|
|
90
|
+
}
|
|
91
|
+
return branch_name;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
session_vars.get_project_base_name = function () {
|
|
95
|
+
/* Make an un-incremented project name based on the repo name and branch name. */
|
|
96
|
+
let repo_url_without_trailing_slash = session_vars.get_repo_url().replace(/\/$/, '');
|
|
97
|
+
let repo_name_parts = repo_url_without_trailing_slash.split('/');
|
|
98
|
+
let package_name = repo_name_parts[ repo_name_parts.length - 1 ];
|
|
99
|
+
|
|
100
|
+
let name = `testing${ package_name }${ session_vars.get_branch_name() }`;
|
|
101
|
+
let sanitized_name = name.replace( /[^A-Za-z0-9]/g, '' );
|
|
102
|
+
return sanitized_name;
|
|
103
|
+
};
|
|
104
|
+
|
|
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
|
+
session_vars.get_languages = function () {
|
|
129
|
+
/* Returns an array of strings, names of languages that should be tested. */
|
|
130
|
+
|
|
131
|
+
// These are assumed to be the words that are on the buttons or links
|
|
132
|
+
// that change the language of the interview. Have not yet detected
|
|
133
|
+
// another distinguishing feature
|
|
134
|
+
// Need to research using the language url param instead.
|
|
135
|
+
let langs = [];
|
|
136
|
+
if ( process.env.EXTRA_LANGUAGES && process.env.EXTRA_LANGUAGES !== 'default' ) {
|
|
137
|
+
langs = process.env.EXTRA_LANGUAGES.split(', ');
|
|
138
|
+
}
|
|
139
|
+
return langs;
|
|
140
|
+
}; // Ends session_vars.get_languages()
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
const project_name_file_path = `_al_test_project_name.json`;
|
|
144
|
+
session_vars.save_project_name = function ( project_name ) {
|
|
145
|
+
/* Saves the name of the project to a file so deletion can use it later.
|
|
146
|
+
* Built for local as well as remote testing. Assumes a kosher string.
|
|
147
|
+
* We avoided a list because of concerns over getting out of date.
|
|
148
|
+
* Should we try to prevent someone overwriting a previous project name?
|
|
149
|
+
*
|
|
150
|
+
* @param project_name { string } - purely alphanumeric string */
|
|
151
|
+
|
|
152
|
+
// Warn local developers if file already exists
|
|
153
|
+
if ( fs.existsSync( project_name_file_path ) ) {
|
|
154
|
+
let old_project_name = session_vars.get_project_name();
|
|
155
|
+
let session_project_already_exists_msg = `ALKiln WARNING: `
|
|
156
|
+
+ `This session had a project name already: ${ old_project_name }. `
|
|
157
|
+
+ `A new project has now been created called ${ project_name }. `
|
|
158
|
+
+ `Remember to delete ${ old_project_name }`;
|
|
159
|
+
console.warn( session_project_already_exists_msg );
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let file = fs.writeFileSync( project_name_file_path, JSON.stringify( project_name ) );
|
|
163
|
+
if ( session_vars.get_debug() ) {
|
|
164
|
+
console.log( `ALKiln debug: Stored name of Project "${ project_name }" locally.` );
|
|
165
|
+
}
|
|
166
|
+
return file;
|
|
167
|
+
}; // Ends save_project_name()
|
|
168
|
+
|
|
169
|
+
session_vars.get_project_name = function () {
|
|
170
|
+
/* Get the name of the current project */
|
|
171
|
+
let project_name = JSON.parse( fs.readFileSync( project_name_file_path ));
|
|
172
|
+
if ( session_vars.get_debug() ) { console.log( `Project name from file is "${ project_name }".` ); }
|
|
173
|
+
return project_name;
|
|
174
|
+
}; // Ends get_project_name()
|
|
175
|
+
|
|
176
|
+
session_vars.delete_project_name = function () {
|
|
177
|
+
/* Delete the file storing the name of the docassemble project */
|
|
178
|
+
// Avoid race coditions possibly caused by checking for existence first
|
|
179
|
+
// Delete file if possible
|
|
180
|
+
try {
|
|
181
|
+
fs.unlinkSync( project_name_file_path );
|
|
182
|
+
console.log( `ALKiln: Deleted the file that stored the name of the Project.` );
|
|
183
|
+
return true;
|
|
184
|
+
} catch ( error ) {
|
|
185
|
+
console.warn( `ALKiln WARNING: Could not delete the Project name file. Error: ${ error }.` );
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
// We'll use a library if we need anything more complicated
|
|
3
|
+
let time = {};
|
|
4
|
+
module.exports = time;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Causes your script to wait for the given number of milliseconds.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* From https://github.com/puppeteer/puppeteer/pull/6268/files#diff-94b4e5903a98ebf8e5f178eb3354b806fd2aed9c74a5022d88dcd24bc477a5aaR1096-R1100
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
*
|
|
14
|
+
* Wait for 1 second:
|
|
15
|
+
*
|
|
16
|
+
* ```
|
|
17
|
+
* await time.waitForTimeout( 1000 );
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @param milliseconds - the number of milliseconds to wait.
|
|
21
|
+
*/
|
|
22
|
+
time.waitForTimeout = function( milliseconds ) {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
setTimeout(resolve, milliseconds);
|
|
25
|
+
});
|
|
26
|
+
};
|
package/lib/world.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { setWorldConstructor } = require('cucumber');
|
|
1
|
+
const { setWorldConstructor } = require('@cucumber/cucumber');
|
|
2
2
|
const puppeteer = require('puppeteer');
|
|
3
3
|
const scope = require('./scope');
|
|
4
4
|
|
|
@@ -7,4 +7,4 @@ const World = function() {
|
|
|
7
7
|
scope.context = {};
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
setWorldConstructor(World);
|
|
10
|
+
setWorldConstructor( World );
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suffolklitlab/alkiln",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-pre-api.4",
|
|
4
4
|
"description": "Integrated automated end-to-end testing with docassemble, puppeteer, and cucumber.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"langs_setup": "./lib/utils/langs.js 'tests/features/*.feature'",
|
|
12
12
|
"langs_local": "npm run langs_setup && npm run local",
|
|
13
13
|
"local": "npm run setup && npm run cucumber; npm run takedown",
|
|
14
|
-
"setup": "./lib/
|
|
15
|
-
"takedown": "./lib/
|
|
14
|
+
"setup": "./lib/docassemble/setup.js",
|
|
15
|
+
"takedown": "./lib/docassemble/takedown.js",
|
|
16
16
|
"unit": "mocha tests/unit_tests/*.test.*"
|
|
17
17
|
},
|
|
18
18
|
"repository": {
|
|
@@ -32,22 +32,23 @@
|
|
|
32
32
|
"bugs": {
|
|
33
33
|
"url": "https://github.com/SuffolkLITLab/alkiln/issues"
|
|
34
34
|
},
|
|
35
|
-
"homepage": "https://github.
|
|
35
|
+
"homepage": "https://suffolklitlab.github.io/docassemble-AssemblyLine-documentation/docs/automated_integrated_testing",
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"@cucumber/cucumber": "^7.3.2",
|
|
38
|
+
"axios": "^0.24.0",
|
|
37
39
|
"chai": "^4.2.0",
|
|
38
40
|
"cheerio": "^1.0.0-rc.5",
|
|
39
|
-
"colors": "1.4.0",
|
|
40
|
-
"cucumber": "^6.0.5",
|
|
41
41
|
"dotenv": "^8.2.0",
|
|
42
|
-
"mocha": "^
|
|
43
|
-
"puppeteer": "^
|
|
42
|
+
"mocha": "^9.2.0",
|
|
43
|
+
"puppeteer": "^13.1.3",
|
|
44
|
+
"qs": "^6.10.2",
|
|
44
45
|
"sanitize-filename": "^1.6.3",
|
|
45
46
|
"uuid": "^8.3.2"
|
|
46
47
|
},
|
|
47
48
|
"bin": {
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
49
|
+
"alkiln-setup": "./lib/docassemble/setup.js",
|
|
50
|
+
"alkiln-takedown": "./lib/docassemble/takedown.js",
|
|
51
|
+
"alkiln-cucumber": "./lib/index.js",
|
|
52
|
+
"alkiln-langs": "./lib/utils/langs.js"
|
|
52
53
|
}
|
|
53
54
|
}
|
|
@@ -20,3 +20,18 @@ Scenario: I am able to set a custom wait time before an interview has been loade
|
|
|
20
20
|
Scenario: Interview name includes url args
|
|
21
21
|
Given I start the interview at "url_args.yml&from=theinternets&random=zoo"
|
|
22
22
|
Then I should see the phrase "zoo"
|
|
23
|
+
|
|
24
|
+
@slow @e4 @wait_first
|
|
25
|
+
Scenario: I can wait as a first step in a test
|
|
26
|
+
Given I wait 1 second
|
|
27
|
+
|
|
28
|
+
@slow @e5 @wait_first
|
|
29
|
+
Scenario: Interview name includes url args with a wait
|
|
30
|
+
Given I wait 1 second
|
|
31
|
+
Then I start the interview at "url_args.yml&from=theinternets&random=zoo"
|
|
32
|
+
Then I should see the phrase "zoo"
|
|
33
|
+
|
|
34
|
+
@fast @e6 @signin
|
|
35
|
+
Scenario: I sign in
|
|
36
|
+
Given I sign in with the email "USER1_EMAIL" and the password "USER1_PASSWORD"
|
|
37
|
+
And I start the interview at "all_tests"
|
|
@@ -95,3 +95,34 @@ Scenario: Test "Then I don’t continue" with an apostrophe
|
|
|
95
95
|
And I tap to continue
|
|
96
96
|
Then I don’t continue
|
|
97
97
|
And I will be told an answer is invalid
|
|
98
|
+
|
|
99
|
+
@fast @o9
|
|
100
|
+
Scenario: I can match JSON page var to str
|
|
101
|
+
Given I start the interview at "all_tests.yml"
|
|
102
|
+
And I get to "showifs" with this data:
|
|
103
|
+
| var | value | trigger |
|
|
104
|
+
| double_quote_dict["double_quote_key"]['dq_two'] | true | |
|
|
105
|
+
| checkboxes_other['checkbox_other_opt_1'] | true | |
|
|
106
|
+
| dropdown_test | dropdown_opt_2 | |
|
|
107
|
+
| radio_yesno | False | false |
|
|
108
|
+
| radio_other | radio_other_opt_3 | |
|
|
109
|
+
| single_quote_dict['single_quote_key']['sq_two'] | true | |
|
|
110
|
+
| text_input | Regular text input field value | |
|
|
111
|
+
| textarea | Multiline text\narea value | |
|
|
112
|
+
| date_input | today | |
|
|
113
|
+
Then the text in the JSON variable "dropdown_test" should be
|
|
114
|
+
"""
|
|
115
|
+
dropdown_opt_2
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
# Maybe this one should be in the report tests (as well?)
|
|
119
|
+
@fast @o10 @json
|
|
120
|
+
Scenario: I get the page's JSON
|
|
121
|
+
Given I start the interview at "all_tests"
|
|
122
|
+
Then I get the page's JSON variables and values
|
|
123
|
+
|
|
124
|
+
@fast @o9
|
|
125
|
+
Scenario: I take a screenshot
|
|
126
|
+
Given I start the interview at "all_tests"
|
|
127
|
+
Then I take a screenshot
|
|
128
|
+
Then I take a screenshot named "some-screenshot"
|