@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
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
const _da_REST = require('./docassemble_api_REST');
|
|
2
|
+
const log = require('../utils/log');
|
|
3
|
+
const session_vars = require('../utils/session_vars' );
|
|
4
|
+
const time = require('../utils/time');
|
|
5
|
+
|
|
6
|
+
// Temp notes:
|
|
7
|
+
// Do we need to respond if the dev api key expires in the middle of
|
|
8
|
+
// everything? [Answer: the docs don't give an expiration date, so that would
|
|
9
|
+
// only happen if they deleted it in the middle. Which we shouldn't handle?]
|
|
10
|
+
// General: How/when do we check if server is busy? Just on error? What about
|
|
11
|
+
// all kinds of race conditions? Probably not something we can overcome. Just
|
|
12
|
+
// do it before trying to load a page.
|
|
13
|
+
|
|
14
|
+
// TODO: How can we test busy server stuff properly? Especially down
|
|
15
|
+
// to specific functions, like `.pull()` which run in a very small
|
|
16
|
+
// window.
|
|
17
|
+
|
|
18
|
+
/** Notes:
|
|
19
|
+
* - Checking for a busy server is vulnerable to race conditions, but
|
|
20
|
+
* there's nothing we can do about that.
|
|
21
|
+
*
|
|
22
|
+
* Axios response structures:
|
|
23
|
+
*
|
|
24
|
+
* 204 for creating project)
|
|
25
|
+
* {
|
|
26
|
+
* status: 204,
|
|
27
|
+
* statusText: 'NO CONTENT',
|
|
28
|
+
* data: '',
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* 200 working on it)
|
|
32
|
+
* {
|
|
33
|
+
* status: 200,
|
|
34
|
+
* statusText: 'OK',
|
|
35
|
+
* data: { status: 'working'/'completed' }
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
*
|
|
39
|
+
* Axios error structures:
|
|
40
|
+
*
|
|
41
|
+
* response timeout server request)
|
|
42
|
+
* {
|
|
43
|
+
* code = 'ECONNABORTED'
|
|
44
|
+
* response: undefined,
|
|
45
|
+
* isAxiosError: true,
|
|
46
|
+
* }
|
|
47
|
+
*
|
|
48
|
+
* access denied
|
|
49
|
+
* {
|
|
50
|
+
* response: {
|
|
51
|
+
* status: 403,
|
|
52
|
+
* statusText: 'FORBIDDEN',
|
|
53
|
+
* data: 'Access denied.',
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
let da_i = {};
|
|
59
|
+
module.exports = da_i;
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
let is_timeout_error = function( error ) {
|
|
63
|
+
/** Return whether the error is an axios timeout error.
|
|
64
|
+
* See:
|
|
65
|
+
* Check on https://github.com/axios/axios/issues/1543#issuecomment-558166483 (2019)
|
|
66
|
+
* and https://github.com/axios/axios/issues/1174#issuecomment-349014752 (2017)
|
|
67
|
+
*/
|
|
68
|
+
if ( error.message && error.message.includes( `timeout` ) ) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").throw_an_error_if_server_is_not_responding()'
|
|
76
|
+
da_i.throw_an_error_if_server_is_not_responding = async function ( options ) {
|
|
77
|
+
/** Make a request to the server to see if it's responding.
|
|
78
|
+
* It doesn't matter what the request is, as long as it doesn't
|
|
79
|
+
* cause a server restart.
|
|
80
|
+
* This is currently meant for puppeteer tests, not for here.
|
|
81
|
+
*
|
|
82
|
+
* If we do add a loop to poll the server, we can add it in here:
|
|
83
|
+
* let { time_per_loop, max_loops } = options || { time_per_loop: 5 * 1000, max_loops: 15 };
|
|
84
|
+
*/
|
|
85
|
+
|
|
86
|
+
// Defaults
|
|
87
|
+
let { timeout } = options || { timeout: 5 * 1000 };
|
|
88
|
+
log.info({ pre: `Waiting for the docassemble server to respond. Will wait for ${ timeout/1000 } seconds at most.` });
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
let start_time = Date.now()
|
|
92
|
+
// Axios + server will poll until server is ready or timeout is over
|
|
93
|
+
let response = await _da_REST.get_dev_id( timeout );
|
|
94
|
+
let end_time = Date.now()
|
|
95
|
+
if ( response && response.data && response.data.id ) {
|
|
96
|
+
log.info({ pre: `The docassemble server responded after ${ (end_time - start_time)/1000 } seconds.` });
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
} catch ( error ) {
|
|
101
|
+
// Timeout means the server is busy.
|
|
102
|
+
if ( is_timeout_error( error ) ) {
|
|
103
|
+
// Anything that's waiting for the server to not be busy does not want
|
|
104
|
+
// to move forward without a free server.
|
|
105
|
+
log.info({ pre: `The docassemble server was still busy after ${ timeout/1000 } seconds.` });
|
|
106
|
+
} else {
|
|
107
|
+
// Not sure what to do for other errors. It could be a server
|
|
108
|
+
// error, like an 'Access Denied' error, which should be handled.
|
|
109
|
+
log.error({
|
|
110
|
+
pre: `Tried to check if the docassemble server was busy, but `
|
|
111
|
+
+ `ran into an unexpected error. The error didn't indicate a busy server, though.`
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}; // Ends da_i.throw_an_error_if_server_is_not_responding()
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").get_dev_id()'
|
|
121
|
+
da_i.get_dev_id = async function ( dev_id_options ) {
|
|
122
|
+
/** For consistency, wrap _da_REST.get_dev_id().
|
|
123
|
+
* See https://docassemble.org/docs/api.html#user. */
|
|
124
|
+
|
|
125
|
+
// Default timeouts
|
|
126
|
+
let { timeout } = dev_id_options || { timeout: 75 * 1000 };
|
|
127
|
+
return await _da_REST.get_dev_id( timeout );
|
|
128
|
+
}; // Ends da_i.get_dev_id();
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").validate_api_key()'
|
|
132
|
+
da_i.validate_api_key = async function ( api_key_options ) {
|
|
133
|
+
/** Make sure the api key is the right one for this server.
|
|
134
|
+
* See https://docassemble.org/docs/api.html#user. */
|
|
135
|
+
|
|
136
|
+
log.info({ pre: `Checking the testing account's API key.` });
|
|
137
|
+
|
|
138
|
+
// Default timeouts
|
|
139
|
+
api_key_options = api_key_options || { timeout: 75 * 1000 };
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
|
|
143
|
+
// There's only one possible success result
|
|
144
|
+
// As long as this succeeds, we're good
|
|
145
|
+
await _da_REST.get_dev_id( api_key_options.timeout );
|
|
146
|
+
log.info({ pre: `Your testing account's API key is perfectly valid on this server.` });
|
|
147
|
+
return true;
|
|
148
|
+
|
|
149
|
+
} catch ( error ) {
|
|
150
|
+
// There's only one possible sever response error
|
|
151
|
+
if ( error.response && error.response.status === 403 ) {
|
|
152
|
+
// Throw in here, or at the caller?
|
|
153
|
+
log.error({
|
|
154
|
+
pre: `The API key in the GitHub secret DOCASSEMBLE_DEVELOPER_API_KEY `
|
|
155
|
+
+ `failed on this server with "Access Denied". Are you sure your `
|
|
156
|
+
+ `DOCASSEMBLE_DEVELOPER_API_KEY secret is set to the API key for `
|
|
157
|
+
+ `the docassemble account that runs the tests on this server? `
|
|
158
|
+
+ `Are you sure your SERVER_URL GitHub secret is set to the server `
|
|
159
|
+
+ `address on which this testing account exists?`
|
|
160
|
+
+ `To update your GitHub secrets, either set this repository's `
|
|
161
|
+
+ `secrets at ${ session_vars.get_repo_url() }/settings/secrets `
|
|
162
|
+
+ `or ask your GitHub organization admin to set the `
|
|
163
|
+
+ `organization's secrets.`
|
|
164
|
+
});
|
|
165
|
+
} // ends 403 message
|
|
166
|
+
throw error;
|
|
167
|
+
} // ends try to get dev_id
|
|
168
|
+
}; // Ends da_i.validate_api_key()
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").loop_to_create_project()'
|
|
172
|
+
da_i.loop_to_create_project = async function( creation_options ) {
|
|
173
|
+
/** Create a docassemble Project on the docassemble server's account.
|
|
174
|
+
* Loop through potential project names until we find one that
|
|
175
|
+
* isn't already taken and then use that name to create the Project. */
|
|
176
|
+
let default_opts = { timeout: 3 * 1000, max_tries: 15, wait_seconds: 5 };
|
|
177
|
+
let { timeout, max_tries, wait_seconds } = creation_options || default_opts;
|
|
178
|
+
|
|
179
|
+
let project_name = null;
|
|
180
|
+
let name_incrementor = 0;
|
|
181
|
+
|
|
182
|
+
// Try to create a project. If the project name is already taken, increment and loop again.
|
|
183
|
+
while ( name_incrementor <= max_tries ) {
|
|
184
|
+
name_incrementor++;
|
|
185
|
+
try {
|
|
186
|
+
|
|
187
|
+
// Try next name that could be unique. Must remove all non-valid characters
|
|
188
|
+
// TODO: This sanitization is already done in session_vars, so remove it from here
|
|
189
|
+
project_name = session_vars.get_project_base_name().replace(/[^A-Za-z0-9]/g, '') + name_incrementor;
|
|
190
|
+
log.info({ pre: `Trying to create a docassemble Project with the name ${ project_name }` });
|
|
191
|
+
let response = await _da_REST.create_project( project_name, timeout );
|
|
192
|
+
log.info({ pre: `The docassemble server is ready. Created a Project named ${ project_name }` });
|
|
193
|
+
// If succeeded in creating project, return the name that worked
|
|
194
|
+
return project_name;
|
|
195
|
+
|
|
196
|
+
} catch ( error ) {
|
|
197
|
+
// TODO: Make a `normalize_ajax_responses_and_errors()`?
|
|
198
|
+
let response = error.response;
|
|
199
|
+
|
|
200
|
+
if ( response && response.data ) {
|
|
201
|
+
if ( response.data.includes( `Invalid project` ) ) {
|
|
202
|
+
if ( name_incrementor < max_tries ) {
|
|
203
|
+
// A non-unique project name. Try the next project name.
|
|
204
|
+
continue;
|
|
205
|
+
|
|
206
|
+
} else {
|
|
207
|
+
// On the last loop, failed because there were too many project
|
|
208
|
+
// names already taken
|
|
209
|
+
log.error({
|
|
210
|
+
pre: `There were already ${ max_tries } projects with the base `
|
|
211
|
+
+ `name ${ session_vars.get_project_base_name() }. If you need to allow `
|
|
212
|
+
+ `more, file an issue at https://github.com/SuffolkLITLab/ALKiln/issues.`
|
|
213
|
+
});
|
|
214
|
+
throw( error );
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// ends "Invalid project" error
|
|
218
|
+
} else {
|
|
219
|
+
// Other response errors should be thrown with link to docs
|
|
220
|
+
log.error({
|
|
221
|
+
type: `docassemble ${ response.status } "${ response.data }"`,
|
|
222
|
+
pre: `See https://docassemble.org/docs/api.html#playground_post_project.`
|
|
223
|
+
});
|
|
224
|
+
throw ( error );
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// ends if error.response
|
|
228
|
+
} else {
|
|
229
|
+
|
|
230
|
+
// If it's a timeout error, server is busy. Try again after waiting.
|
|
231
|
+
if ( is_timeout_error( error ) && name_incrementor < max_tries ) {
|
|
232
|
+
log.info({ pre: `The docassemble server was busy when we tried to `
|
|
233
|
+
+ `create the Project. Attempt ${ name_incrementor } of `
|
|
234
|
+
+ `${ max_tries }. Will try again in ${ wait_seconds } seconds.` });
|
|
235
|
+
name_incrementor--; // Try this name again next time
|
|
236
|
+
await time.waitForTimeout( wait_seconds * 1000 );
|
|
237
|
+
continue;
|
|
238
|
+
|
|
239
|
+
// A non-timeout, non-server error should just be thrown
|
|
240
|
+
} else {
|
|
241
|
+
log.error({ pre: `Ran into unexpected error when trying to create the Project.` });
|
|
242
|
+
throw error;
|
|
243
|
+
|
|
244
|
+
} // ends type of non-response error
|
|
245
|
+
} // ends type of reponse error
|
|
246
|
+
} // ends try
|
|
247
|
+
} // ends while
|
|
248
|
+
}; // Ends da_i.loop_to_create_project()
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").pull()'
|
|
252
|
+
da_i.pull = async function ( pull_options ) {
|
|
253
|
+
/** Pull github code into an existing Project. */
|
|
254
|
+
|
|
255
|
+
log.info({ pre: `Trying to pull code from the "${ session_vars.get_branch_name() }" branch.` });
|
|
256
|
+
|
|
257
|
+
// Default timeouts
|
|
258
|
+
let { timeout } = pull_options || { timeout: 75 * 1000 };
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
|
|
262
|
+
let response = await _da_REST.pull( timeout );
|
|
263
|
+
|
|
264
|
+
// If server didn't need to restart
|
|
265
|
+
if ( response && response.status === 204 ) {
|
|
266
|
+
log.info({ pre: `Your Docassemble server finished pulling the package's code.` });
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// If server needed to restart because of the pulled code
|
|
271
|
+
if ( response && response.status === 200 ) {
|
|
272
|
+
log.debug({ pre: `Pull task id: ${ response.data.task_id }` });
|
|
273
|
+
return response.data.task_id;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
} catch ( error ) {
|
|
277
|
+
// Pulling should not error
|
|
278
|
+
log.error({ pre: `Pulling into the docassemble Project ran into an unexpected error.` });
|
|
279
|
+
log.debug({ pre: `See https://docassemble.org/docs/api.html#playground_pull.` });
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
}; // Ends da_i.pull()
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").has_task_finished()'
|
|
286
|
+
da_i.has_task_finished = async function ( task_id, options ) {
|
|
287
|
+
/** Check task status if it exists. If not, return true as task did
|
|
288
|
+
* not require a server restart. See da_i.pull().
|
|
289
|
+
* See https://docassemble.org/docs/api.html#restart_status. */
|
|
290
|
+
|
|
291
|
+
// Defaults
|
|
292
|
+
let { timeout } = options || { timeout: 3 * 1000 };
|
|
293
|
+
|
|
294
|
+
try {
|
|
295
|
+
|
|
296
|
+
// If server did need to restart, check if it's done.
|
|
297
|
+
let response = await _da_REST.has_task_finished( task_id, timeout );
|
|
298
|
+
log.debug({ pre: `Task status: ${ response.status }. Docassemble status text: ${ response.data.status }. Task id: ${ task_id }` });
|
|
299
|
+
|
|
300
|
+
if ( response.data.status === 'completed' ) {
|
|
301
|
+
return true;
|
|
302
|
+
|
|
303
|
+
} else if ( response.data.status === 'working' ) {
|
|
304
|
+
log.info({ pre: `The docassemble server is uploading the package.` });
|
|
305
|
+
return false;
|
|
306
|
+
|
|
307
|
+
} else if ( response.data.status === 'unknown' ) {
|
|
308
|
+
// Server is working, but status 'unknown'? We shouldn't even
|
|
309
|
+
// get here according to the API docs, but it feels weird to have
|
|
310
|
+
// no default behavior. What to return? Throw?
|
|
311
|
+
log.info({
|
|
312
|
+
pre: `\`task_id\` "${ task_id }" has expired. If it's been `
|
|
313
|
+
+ `less than 1 hour since the task started, the task is `
|
|
314
|
+
+ `complete. See https://docassemble.org/docs/api.html#restart_status.`,
|
|
315
|
+
data: response,
|
|
316
|
+
});
|
|
317
|
+
return null;
|
|
318
|
+
} // ends status type
|
|
319
|
+
|
|
320
|
+
} catch ( error ) {
|
|
321
|
+
// Timeout means the server is busy.
|
|
322
|
+
if ( is_timeout_error( error ) ) {
|
|
323
|
+
log.info({ pre: `The docassemble server is still uploading the package.` });
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
log.error({ pre: `Tried to check that the package was uploaded, but ran into an unexpected error.` });
|
|
328
|
+
throw error;
|
|
329
|
+
} // ends try to check for server done restarting
|
|
330
|
+
|
|
331
|
+
}; // Ends da_i.has_task_finished()
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
da_i.wait_for_server_to_restart = async ( task_id, options ) => {
|
|
335
|
+
/** Wait for the server to finish restarting in case a module needs to load.
|
|
336
|
+
* This is a polling function because things may be returned
|
|
337
|
+
* that aren't equivalent to the server being done with a task. */
|
|
338
|
+
log.info({ pre: `Docassemble is pulling this package. The task_id is `
|
|
339
|
+
+ `"${ task_id }". A task_id is usually created for a package `
|
|
340
|
+
+ `with a module. It can take a few minutes to finish uploading.` });
|
|
341
|
+
|
|
342
|
+
// Defaults
|
|
343
|
+
let { wait_seconds_per_loop, max_loops } = options || { wait_seconds_per_loop: 5, max_loops: 15 };
|
|
344
|
+
|
|
345
|
+
// Flags for stopping the `while` loop
|
|
346
|
+
let num_tries = 0;
|
|
347
|
+
let done_restarting = false;
|
|
348
|
+
|
|
349
|
+
// Why loop instead of one long timeout? Because it might not just hang.
|
|
350
|
+
// We might get a return value that's just `waiting`, meaning the
|
|
351
|
+
// task is not done.
|
|
352
|
+
// - [ ] How many tries/time do we give this? Do we allow customization of those values?
|
|
353
|
+
while ( !done_restarting && num_tries <= max_loops ) {
|
|
354
|
+
num_tries++;
|
|
355
|
+
|
|
356
|
+
done_restarting = await da_i.has_task_finished( task_id );
|
|
357
|
+
if ( !done_restarting ) {
|
|
358
|
+
if ( num_tries < max_loops ) {
|
|
359
|
+
log.info({ pre: `Not yet complete. Check ${ num_tries } of ${ max_loops }. `
|
|
360
|
+
+ `Will check again in ${ wait_seconds_per_loop } seconds.`
|
|
361
|
+
});
|
|
362
|
+
await time.waitForTimeout( wait_seconds_per_loop * 1000 );
|
|
363
|
+
|
|
364
|
+
} else {
|
|
365
|
+
// This is our last round, let's wrap it up
|
|
366
|
+
let server_msg = `ALKiln setup: It seems like the docassemble server `
|
|
367
|
+
+ `didn't finish uploading the code after ${ max_loops * wait_seconds_per_loop } `
|
|
368
|
+
+ `seconds. Some things you can try: check your server is up, try `
|
|
369
|
+
+ `re-running the test, and try pulling the package manually `
|
|
370
|
+
+ `into the playground.`;
|
|
371
|
+
// Add link to docs once the docs are more comprehensive
|
|
372
|
+
throw( server_msg );
|
|
373
|
+
} // ends if ran out of tries
|
|
374
|
+
} // ends if done_restarting
|
|
375
|
+
} // ends while not done restarting
|
|
376
|
+
|
|
377
|
+
log.info({ pre: `The docassemble server has uploaded your package.` });
|
|
378
|
+
}; // Ends da_i.wait_for_server_to_restart()
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
// Delete the Project
|
|
382
|
+
// node -e 'require("./lib/docassemble/docassemble_api_interface.js").delete_project( "create1" )'
|
|
383
|
+
da_i.delete_project = async function ( delete_options ) {
|
|
384
|
+
/** Delete a project on the user's da server. */
|
|
385
|
+
|
|
386
|
+
// Defaults
|
|
387
|
+
let { timeout } = delete_options || { timeout: 75 * 1000 };
|
|
388
|
+
|
|
389
|
+
let project_name = session_vars.get_project_name()
|
|
390
|
+
log.info({ pre: `Trying to delete Project ${ project_name }` });
|
|
391
|
+
|
|
392
|
+
try {
|
|
393
|
+
|
|
394
|
+
let response = await _da_REST.delete_project( timeout );
|
|
395
|
+
log.info({ pre: `Deleted Project "${ project_name }"` });
|
|
396
|
+
|
|
397
|
+
} catch ( error ) {
|
|
398
|
+
// Should we throw in here?
|
|
399
|
+
log.error({ pre: `Ran into an error when deleting Project "${ project_name }"` });
|
|
400
|
+
log.debug({ pre: `See https://docassemble.org/docs/api.html#playground_delete_project.` });
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
}; // Ends da_i.delete_project()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const da_i = require('./docassemble_api_interface');
|
|
4
|
+
const log = require('../utils/log');
|
|
5
|
+
const session_vars = require('../utils/session_vars' );
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
const setup = async () => {
|
|
9
|
+
/* In the docassemble testing account identified by the
|
|
10
|
+
* DOCASSEMBLE_DEVELOPER_API_KEY secret, create a new Project,
|
|
11
|
+
* pull code into that project, and, if needed, wait for the
|
|
12
|
+
* server to restart. */
|
|
13
|
+
log.info({ type: `setup`, pre: `Starting to upload this package to `
|
|
14
|
+
+ `a new Project in the server's testing account.` });
|
|
15
|
+
|
|
16
|
+
// Check that API key is valid. Will error if it is invalid.
|
|
17
|
+
// Should the error be thrown here?
|
|
18
|
+
await da_i.validate_api_key();
|
|
19
|
+
|
|
20
|
+
// Create a project on the da server's account with a unique name then
|
|
21
|
+
// store it locally for later deleting the project.
|
|
22
|
+
let project_name = await da_i.loop_to_create_project();
|
|
23
|
+
// Once the name is created, save that name to a local file.
|
|
24
|
+
session_vars.save_project_name( project_name );
|
|
25
|
+
|
|
26
|
+
// Pull code and wait for server restart to finish if needed
|
|
27
|
+
let task_id = await da_i.pull();
|
|
28
|
+
// Task id will be null if server did not need to restart
|
|
29
|
+
if ( task_id ) {
|
|
30
|
+
await da_i.wait_for_server_to_restart( task_id );
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Finish
|
|
34
|
+
log.info({ type: `setup`, pre: `Success! Test setup has finished successfully.` });
|
|
35
|
+
}; // Ends setup();
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
setup();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const da_i = require('./docassemble_api_interface');
|
|
4
|
+
const log = require('../utils/log');
|
|
5
|
+
const session_vars = require('../utils/session_vars' );
|
|
6
|
+
|
|
7
|
+
const takedown = async () => {
|
|
8
|
+
/* In the docassemble testing account identified by the
|
|
9
|
+
* DOCASSEMBLE_DEVELOPER_API_KEY secret, delete the
|
|
10
|
+
* Project created for this test.
|
|
11
|
+
* For local development, clean up project name file. */
|
|
12
|
+
log.info({ type: `takedown`, pre: `Trying to remove the docassemble Project from the testing account.` });
|
|
13
|
+
await da_i.delete_project();
|
|
14
|
+
session_vars.delete_project_name();
|
|
15
|
+
log.info({ type: `takedown`, pre: `Success! Test takedown has finished successfully.` });
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
takedown();
|