@suffolklitlab/alkiln 5.17.0 → 5.17.1-detect-upload-1
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/{da_image_v_sha_7d13853.yml → al_da_image_latest.yml} +10 -5
- package/.github/workflows/github_server.yml +7 -3
- package/.github/workflows/playground.yml +2 -2
- package/CHANGELOG.md +54 -1
- package/docs/decisions/017_post_navigation_custom_behavior_2026_10_26.md +136 -0
- package/lib/docassemble/docassemble_api_interface.js +3 -0
- package/lib/scope.js +1199 -306
- package/lib/steps.js +150 -67
- package/lib/utils/Log.js +10 -8
- package/lib/utils/session_vars.js +25 -8
- package/package.json +1 -1
- package/tests/log_codes/log_code_expected_instances.txt +20 -1
- package/tests/unit_tests/constrained_random_answers/valid.fixtures.js +3 -1
- package/tests/unit_tests/fields.fixtures.js +19 -8
- package/tests/unit_tests/getAllFields.test.js +1 -1
- package/tests/unit_tests/html.fixtures.js +3 -1
- package/tests/unit_tests/navigation.test.js +72 -0
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Sandbox with AL da image version
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
pull_request:
|
|
6
6
|
workflow_dispatch:
|
|
7
7
|
inputs:
|
|
8
|
+
tags:
|
|
9
|
+
required: False
|
|
10
|
+
description: 'Optional. Use a "tag expression" specify which tagged tests to run (https://cucumber.io/docs/cucumber/api/#tag-expressions)'
|
|
8
11
|
show_docker_output:
|
|
9
12
|
required: false
|
|
10
13
|
default: false
|
|
@@ -16,10 +19,12 @@ on:
|
|
|
16
19
|
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
|
17
20
|
required: false
|
|
18
21
|
default: false
|
|
22
|
+
schedule:
|
|
23
|
+
- cron: "0 1 * * SUN"
|
|
19
24
|
|
|
20
25
|
jobs:
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
sandbox-al-tests:
|
|
23
28
|
# Avoids running double tests when someone on the team makes a pull request
|
|
24
29
|
# 1: Trigger job on push or dispatch from this repository
|
|
25
30
|
# 2: Trigger job on pull request from a fork
|
|
@@ -42,7 +47,7 @@ jobs:
|
|
|
42
47
|
uses: ./action_for_github_server
|
|
43
48
|
with:
|
|
44
49
|
SHOW_DOCKER_OUTPUT: "${{ github.event.inputs.show_docker_output }}"
|
|
45
|
-
DOCASSEMBLE_IMAGE: "ghcr.io/suffolklitlab/docassemble:
|
|
50
|
+
DOCASSEMBLE_IMAGE: "ghcr.io/suffolklitlab/docassemble:latest"
|
|
46
51
|
- run: echo "ALKiln finished starting the isolated GitHub docassemble server"
|
|
47
52
|
shell: bash
|
|
48
53
|
|
|
@@ -61,5 +66,5 @@ jobs:
|
|
|
61
66
|
SERVER_URL: "${{ steps.github_server.outputs.SERVER_URL }}"
|
|
62
67
|
DOCASSEMBLE_DEVELOPER_API_KEY: "${{ steps.github_server.outputs.DOCASSEMBLE_DEVELOPER_API_KEY }}"
|
|
63
68
|
INSTALL_METHOD: "server"
|
|
64
|
-
ALKILN_TAG_EXPRESSION: "
|
|
65
|
-
|
|
69
|
+
ALKILN_TAG_EXPRESSION: "${{ env.ALKILN_TAG_EXPRESSION }}"
|
|
70
|
+
ALKILN_VERSION: "da_version"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Sandbox with latest da image
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
@@ -19,10 +19,12 @@ on:
|
|
|
19
19
|
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
|
20
20
|
required: false
|
|
21
21
|
default: false
|
|
22
|
+
schedule:
|
|
23
|
+
- cron: "0 1 * * SUN"
|
|
22
24
|
|
|
23
25
|
jobs:
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
sandbox-da-tests:
|
|
26
28
|
#### Developer note: If you have both `push` and `pull_request` in the
|
|
27
29
|
#### `on` section (above), this avoids running double tests when someone
|
|
28
30
|
#### on the team makes a pull request
|
|
@@ -70,6 +72,8 @@ jobs:
|
|
|
70
72
|
SHOW_DOCKER_OUTPUT: "${{ github.event.inputs.show_docker_output }}"
|
|
71
73
|
#### Developer note: You can probably leave this out
|
|
72
74
|
CONFIG_CONTENTS: "${{ secrets.CONFIG_CONTENTS }}"
|
|
75
|
+
#### Developer note: Example of using a different docassemble image:
|
|
76
|
+
# DOCASSEMBLE_IMAGE: "ghcr.io/suffolklitlab/docassemble:latest"
|
|
73
77
|
- run: echo "ALKiln finished starting the isolated GitHub docassemble server"
|
|
74
78
|
shell: bash
|
|
75
79
|
|
|
@@ -157,7 +161,7 @@ jobs:
|
|
|
157
161
|
#### Developer note: You can probably leave the rest out
|
|
158
162
|
#### To learn more, see https://assemblyline.suffolklitlab.org/docs/alkiln/writing/#optional-inputs
|
|
159
163
|
ALKILN_TAG_EXPRESSION: "${{ env.ALKILN_TAG_EXPRESSION }}"
|
|
160
|
-
|
|
164
|
+
ALKILN_VERSION: "da_version"
|
|
161
165
|
|
|
162
166
|
#### Developer note: Example of making an issue when tests fail
|
|
163
167
|
#### that includes the text of the failure output file
|
|
@@ -13,7 +13,7 @@ on:
|
|
|
13
13
|
|
|
14
14
|
jobs:
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
alkiln-tests:
|
|
17
17
|
#### Developer note: If you have both `push` and `pull_request` in the
|
|
18
18
|
#### `on` section (above), this avoids running double tests when someone
|
|
19
19
|
#### editing the repository makes a pull request
|
|
@@ -80,4 +80,4 @@ jobs:
|
|
|
80
80
|
# want to check up on this.
|
|
81
81
|
ALKILN_TAG_EXPRESSION: "${{ env.ALKILN_TAG_EXPRESSION }}"
|
|
82
82
|
#### Developer note: You can probably leave this out
|
|
83
|
-
|
|
83
|
+
ALKILN_VERSION: "da_version"
|
package/CHANGELOG.md
CHANGED
|
@@ -21,6 +21,7 @@ Format:
|
|
|
21
21
|
-
|
|
22
22
|
|
|
23
23
|
## [1.0.0] - 2021-01-16
|
|
24
|
+
|
|
24
25
|
### Added
|
|
25
26
|
-
|
|
26
27
|
|
|
@@ -45,6 +46,58 @@ Format:
|
|
|
45
46
|
|
|
46
47
|
## [Unreleased]
|
|
47
48
|
|
|
49
|
+
### Added
|
|
50
|
+
|
|
51
|
+
- Step `I continue` which taps the continue button expecting to navigate to a new page in the interview. `I continue` and `I can't continue` should together replace the behaviors of `I tap to continue`.
|
|
52
|
+
- Step `I can't continue` which taps the continue button expecting to fail to navigate. It passes when there are invalid answers or when a continue button is missing. It fails on other errors, like system errors (including Assembly Line custom errors) and timeout errors. Those types of errors should always fail across the whole framework. An author could use `I can't continue` to check that the interview correctly indicated one or more invalid answers. This replaces the practice of using `I tap to continue` twice.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Part 2 of detecting custom AL error screen (final part): Though `I tap to continue` allows invalid answers again, it throws on other errors, like system errors (including Assembly Line custom errors) and timeout errors. Those types of errors should always fail across the whole framework. It also throws if the continue button is missing. See [#656](https://github.com/SuffolkLITLab/ALKiln/issues/656).
|
|
57
|
+
- Extended error message when the test causes a docassemble system error page (like syntax errors, etc.) It now should contain some of the relevant contents of the page.
|
|
58
|
+
- Tweaked other log messages.
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- Restored the documented behavior of `I tap to continue`. Specifically, the documentation describes using `I tap to continue` to potentially trigger invalid answers. To do this, these commits re-implement old behavior - `I tap to continue` never fails with invalid answers or missing continue-type buttons. Does add a small change - `I tap to continue` now throws on other errors, like system errors and timeout errors. Those types of errors should always fail across the whole framework. Note: A different behavior was proposed where an author could tap to continue once and be guaranteed no failures and then fail on a second tap to the same page. There are situations in which this would break potentially live tests. For example, an author could test multiple invalid answers in a row for the same field by cycling through `I tap to continue` and `I should see the phrase`. The proposed change would break those tests. The `I tap to continue` Step does now log its deprecation, as well as copious warnings with invalid answers or ambiguous lack of navigation. See [#1125](https://github.com/SuffolkLITLab/ALKiln/issues/1125).
|
|
63
|
+
- Ensured new file upload buttons don't warn about duplicates since they have the same selectors.
|
|
64
|
+
- Restored wait for file upload completion signals. See [#1125](https://github.com/SuffolkLITLab/ALKiln/issues/1125).
|
|
65
|
+
|
|
66
|
+
### Internal
|
|
67
|
+
|
|
68
|
+
- Fixed confusing error message when tests expected to fail actually pass.
|
|
69
|
+
- Started refactoring navigation functions to start untangling that rat's nest formed by overlapping motivations.
|
|
70
|
+
- Refactored getting different types of page errors (system error pages vs. user errors.)
|
|
71
|
+
- Started refactoring out `scope.examinePageID()` which is currently doing too many things.
|
|
72
|
+
- Added tests
|
|
73
|
+
- Fixed check for previous filenames on file uploads. See [#1125](https://github.com/SuffolkLITLab/ALKiln/issues/1125).
|
|
74
|
+
- Removed `shared_names` from global scope. See [#1125](https://github.com/SuffolkLITLab/ALKiln/issues/1125).
|
|
75
|
+
|
|
76
|
+
## [5.17.1] - 2026-10-13
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- Added the `I can't continue` Step to assert that pressing the continue button fails to continue. That press should allow the author to then check for invalid answers. Using `I can't continue` once should replace the practice of using `I tap to continue` twice.
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
|
|
84
|
+
- Updated to work with docassemble v1.10.n while being backwards compatible. See [issue #1117](https://github.com/SuffolkLITLab/ALKiln/issues/1117)
|
|
85
|
+
- Unable to find some continue buttons
|
|
86
|
+
- Single-line fields like `yesno: likes_good_things`
|
|
87
|
+
- Buttons created with `buttons:`
|
|
88
|
+
- Continue buttons on signature pages
|
|
89
|
+
- Unable to sign with a name
|
|
90
|
+
- Unable to upload files
|
|
91
|
+
- Created infinite loop with 'Restart' button
|
|
92
|
+
- Changed the internal behavior of the experimental Step `I can't continue` from testing for errors after the previous Step (whatever it happened to be) to attempting to continue. Failure to continue causes success of the Step.
|
|
93
|
+
|
|
94
|
+
### Internal
|
|
95
|
+
|
|
96
|
+
- Added a workflow to test using an Assembly Line docker image
|
|
97
|
+
- Test using a cron job to catch failures more regularly
|
|
98
|
+
- Remove unsupported Step `Then I arrive at the next page` and moved responsibility to Steps that imply they navigate
|
|
99
|
+
- Fixed typo in fixture
|
|
100
|
+
|
|
48
101
|
## [5.17.0] - 2026-09-10
|
|
49
102
|
|
|
50
103
|
### Changed
|
|
@@ -54,7 +107,7 @@ Format:
|
|
|
54
107
|
### Fixed
|
|
55
108
|
|
|
56
109
|
- Fixed GitHub+You action outdated docassemble cli version causing Scenario timeouts.
|
|
57
|
-
- Part 1 of detecting custom AL error screen: Story Table now catches `
|
|
110
|
+
- Part 1 of detecting custom AL error screen: Story Table now catches `al_custom_error_action` error. Previously, Story Tables that ran into this screen would get stuck on the AL error page infinitely. Next steps: Linear Steps may need additional development. Currently linear Steps succeed even when they run into AL's error page. That bears additional discussion. See [issue #656](https://github.com/SuffolkLITLab/ALKiln/issues/656) and [PR #1116](https://github.com/SuffolkLITLab/ALKiln/pull/1116).
|
|
58
111
|
|
|
59
112
|
### Internal
|
|
60
113
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Post navigation custom behavior
|
|
2
|
+
|
|
3
|
+
## Context and Problem Statement
|
|
4
|
+
|
|
5
|
+
What architecture should we use to abstract custom behavior after navigation, like for invalid answers?
|
|
6
|
+
|
|
7
|
+
At this time, we need to test for navigation failures in several different ways and in this specific order:
|
|
8
|
+
|
|
9
|
+
1. A visible system error page, a **critical error**, trumps all other errors. Must always run.
|
|
10
|
+
2. Invalid answers will offer more specific information than the handlers to come after. Optional and must allow custom handling (e.g. warning, failure.)
|
|
11
|
+
3. A timeout with failed navigation is an otherwise invisible **critical error**, but doesn't have much information. Must always run.
|
|
12
|
+
4. A final catchall navigation failure must allow custom handling (warning, failure, other) and has the least amount of information. Optional and must allow custom handling (e.g. warning, failure.)
|
|
13
|
+
|
|
14
|
+
Requirements:
|
|
15
|
+
|
|
16
|
+
- We must enforce test failure for all critical errors
|
|
17
|
+
- We must allow custom behavior for other situations
|
|
18
|
+
- Visible system errors must come first
|
|
19
|
+
- The custom catchall failure must come last if the caller wants it
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Navigation attempt
|
|
23
|
+
|
|
|
24
|
+
Visible system error page – critical error, required
|
|
25
|
+
|
|
|
26
|
+
Invalid answers? – optional
|
|
27
|
+
|
|
|
28
|
+
Nav timeout – critical error, required
|
|
29
|
+
|
|
|
30
|
+
Catch‑all? – optional
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
We currently have only 1 need for custom behavior - the "I tap to continue" Step. That Step must avoid a test failure for invalid answers or other non-critical non-navigation.
|
|
34
|
+
|
|
35
|
+
Note that the default post-navigation functions are most strict and handle any kind of irregularity by throwing errors. They don't warn or skip checks.
|
|
36
|
+
|
|
37
|
+
## Considered Options
|
|
38
|
+
|
|
39
|
+
For each of these options, I'm assuming the caller passes in its desired post-navigation-attempt behavior as handler functions. Those post-navigation-attempt handlers will be called one after the other until finished. An error in one of the handlers will stop the execution of any further handlers. The handler arguments can be:
|
|
40
|
+
|
|
41
|
+
1. A list of handlers that the deepest function calls after the navigation attempt is complete.
|
|
42
|
+
2. Two individual handlers, one called after the page error handler, and the other called after the "timeout before navigation" error handler.
|
|
43
|
+
3. Option 2, but each argument would be a list of handlers.
|
|
44
|
+
4. Three lists of handlers with the error handlers running between them.
|
|
45
|
+
|
|
46
|
+
Also considered, but dismissed on the spot:
|
|
47
|
+
|
|
48
|
+
- Global state flags
|
|
49
|
+
- Caller passes in flags instead of functions
|
|
50
|
+
- The caller has a choice of top-level functions to call, each of which duplicates the initial required navigation behavior followed by a different variation on the post-navigation-attempt behavior 🤪
|
|
51
|
+
|
|
52
|
+
## Decision Outcome
|
|
53
|
+
|
|
54
|
+
We will use option 1, the caller passes a list of all the functions to run after attempted navigation. I'm most compelled by the second "pro" for option 1. That is, this option keeps the flow of the logic visible in one place at the highest level possible.
|
|
55
|
+
|
|
56
|
+
## Implementation
|
|
57
|
+
|
|
58
|
+
The deepest navigation logic is in `scope.wait_until_continued()`, which will accept, among other arguments, the list of handlers described in option 1. For the purposes of the rest of this documentation, I will use the name `post_navigation_handlers` as the name for the parameter containing the list of handlers from option 1.
|
|
59
|
+
|
|
60
|
+
Pseudo-code for one possible simplified implementation where most names are examples:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
function top_caller() {
|
|
64
|
+
const post_navigation_handlers = [
|
|
65
|
+
throw_on_page_system_error,
|
|
66
|
+
warn_on_invalid_answers,
|
|
67
|
+
throw_on_nav_timeout,
|
|
68
|
+
warn_on_unspecified_non_navigation,
|
|
69
|
+
];
|
|
70
|
+
await scope.first_chain_method( post_navigation_handlers );
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// In `scope.js`
|
|
74
|
+
|
|
75
|
+
const scope = {
|
|
76
|
+
first_chain_method: async ( post_navigation_handlers=null ) => {
|
|
77
|
+
await scope.wait_until_continued( post_navigation_handlers );
|
|
78
|
+
},
|
|
79
|
+
wait_until_continued: async ( post_navigation_handlers=null ) => {
|
|
80
|
+
post_navigation_handlers ??= [
|
|
81
|
+
throw_on_page_system_error,
|
|
82
|
+
throw_on_invalid_answers,
|
|
83
|
+
throw_on_nav_timeout,
|
|
84
|
+
throw_on_unspecified_non_navigation,
|
|
85
|
+
];
|
|
86
|
+
// Other logic
|
|
87
|
+
for ( const handler of post_navigation_handlers ) {
|
|
88
|
+
await handler( shared_arguments );
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
As shown in the example, when the navigation attempt is finished, `scope.wait_until_continued()` will loop through `post_navigation_handlers`, calling each one in succession until one triggers an error or until it has called all the handlers. We will not handle catching any errors to let failing tests fail properly.
|
|
95
|
+
|
|
96
|
+
As shown in the example, sometimes `scope.wait_until_continued()` comes at the end of a chain of method calls. We will need to pass `post_navigation_handlers` down through all that chain. `scope.wait_until_continued()` will use a nullish coalescer to set the default handlers list. Because of that, when destructuring parameters, any method that doesn't need to override the final handlers should use `null` as its own default value for the handlers list. Passing `null` will allow the next method in the chain to use its own default handlers list.
|
|
97
|
+
|
|
98
|
+
As option 1 describes, a risk of this approach is that we will forget to include the critical error throwers in `post_navigation_handlers`. We will implement a validator that checks for the presence of the required functions.
|
|
99
|
+
|
|
100
|
+
## Pros and Cons of the Options
|
|
101
|
+
|
|
102
|
+
### 1. A list of handlers
|
|
103
|
+
|
|
104
|
+
The caller passes in a list of all the functions they want run once the navigation attempt is complete.
|
|
105
|
+
|
|
106
|
+
Pros:
|
|
107
|
+
1. Seems more straightforward and consistent.
|
|
108
|
+
2. The behavior is less buried. We can see the flow of functions in one place.
|
|
109
|
+
|
|
110
|
+
Cons:
|
|
111
|
+
1. We duplicate handing in the required failure handlers.
|
|
112
|
+
2. This might be going too far, providing more flexibility than we really need.
|
|
113
|
+
3. A possible risk is writing a caller that doesn't include the critical error throwers.
|
|
114
|
+
|
|
115
|
+
### 2. 2 separate handlers
|
|
116
|
+
|
|
117
|
+
The caller passes in 2 handlers. We call the visible system error, then the 1st function, then we call the timeout error, and finally we call the 2nd function.
|
|
118
|
+
|
|
119
|
+
Pros:
|
|
120
|
+
1. Enforces required failures so no one else has to think about them.
|
|
121
|
+
|
|
122
|
+
Cons:
|
|
123
|
+
1. Much less flexible. In future, will we want to handle something before the visible system failure?
|
|
124
|
+
2. The complex logic is buried in the most nested part of the code that runs.
|
|
125
|
+
|
|
126
|
+
### 3. 2 lists of handlers
|
|
127
|
+
|
|
128
|
+
The caller passes in 2 lists of handlers. We call the visible system error, then the first list of function, then the timeout navigation, then the last list of handlers.
|
|
129
|
+
|
|
130
|
+
Pros:
|
|
131
|
+
1. More flexible than option 2.
|
|
132
|
+
2. Still enforces strict failures.
|
|
133
|
+
|
|
134
|
+
Cons:
|
|
135
|
+
1. Again, hidden complexity.
|
|
136
|
+
2. Preemptive flexibility that we don't need yet.
|
|
@@ -377,6 +377,9 @@ da_i.get_interview = async function ({ interview = {}, api_keys = [], options =
|
|
|
377
377
|
log.debug({ code: `ALK0193`, context, },
|
|
378
378
|
`Status ${ response.status }. Got ${ response.data.items[0].session }.`
|
|
379
379
|
);
|
|
380
|
+
// Discuss: Do we need to handle pagination? Think most recent
|
|
381
|
+
// sessions are listed first, so perhaps not a problem.
|
|
382
|
+
// https://docassemble.org/docs/api.html#user_interviews
|
|
380
383
|
return response.data.items[0];
|
|
381
384
|
} else {
|
|
382
385
|
log.debug({ code: `ALK0194`, context, },
|