@suffolklitlab/alkiln 5.17.1 → 5.17.2-deps

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.
@@ -36,6 +36,17 @@ jobs:
36
36
  && github.event.pull_request.head.repo.fork
37
37
  )
38
38
  runs-on: ubuntu-latest
39
+
40
+ env:
41
+ NORMAL_USER_EMAIL: "alkiln@example.com"
42
+ NORMAL_USER_PASSWORD: "User123^"
43
+ WRONG_EMAIL: "wrong_email@example.com"
44
+ WRONG_PASSWORD: "wrong_password"
45
+ INVALID_API_KEY: "invalidAPIkey"
46
+ EMPTY_STRING: ""
47
+ SECRET_VAR1: "secret-var1-value"
48
+ SECRET_VAR2: "secret-var2-value"
49
+ SECRET_FOR_MISSING_FIELD: "secret for missing field"
39
50
 
40
51
  steps:
41
52
  # Place the root directory in this branch to access relative paths to
@@ -51,20 +62,70 @@ jobs:
51
62
  - run: echo "ALKiln finished starting the isolated GitHub docassemble server"
52
63
  shell: bash
53
64
 
65
+ - name: "Add a low-level user and their API key (in an env var)"
66
+ env:
67
+ SERVER_URL: "${{ steps.github_server.outputs.SERVER_URL }}"
68
+ KEY: ${{ steps.github_server.outputs.DOCASSEMBLE_DEVELOPER_API_KEY }}
69
+ run: |
70
+ # Create user and their API key
71
+
72
+ # Install json processor
73
+ sudo apt-get install jq
74
+
75
+ # https://docassemble.org/docs/api.html#user_new
76
+ user_data=$(curl -X POST \
77
+ ${{ env.SERVER_URL }}/api/user/new \
78
+ -H 'Content-Type: application/json' \
79
+ -d '{
80
+ "key": "${{ env.KEY }}",
81
+ "username": "${{ env.NORMAL_USER_EMAIL }}",
82
+ "password": "${{ env.NORMAL_USER_PASSWORD }}"
83
+ }')
84
+ echo "User data:"
85
+ echo "$user_data"
86
+
87
+ user_id=$(echo "$user_data" | jq '.user_id' -r)
88
+
89
+ # https://docassemble.org/docs/api.html#api_user_user_id_api_post
90
+ new_key_with_quotes=$(curl -X POST \
91
+ ${{ env.SERVER_URL }}/api/user/"$user_id"/api \
92
+ -H 'Content-Type: application/json' \
93
+ -d '{
94
+ "key": "${{ env.KEY }}",
95
+ "name": "alkiln_key",
96
+ "method": "none"
97
+ }')
98
+ echo "new key (watch out, this contains actual quotation marks): $new_key_with_quotes"
99
+ no_end_quote="${new_key_with_quotes%\"}"
100
+ unquoted="${no_end_quote#\"}"
101
+ echo "unquoted: $unquoted"
102
+
103
+ echo "NORMAL_USER_API_KEY=$unquoted" >> "$GITHUB_ENV"
104
+
54
105
  ## Optional debugging to explore things like docker issues
55
106
  #- name: Docker debug tmate session
56
107
  # #if: ${{ failure() && github.event.inputs.enable_tmate == 'true' }}
57
108
  # uses: mxschmitt/action-tmate@v3
58
109
 
59
- - name: "ALKiln - Confirm docassemble packages get installed correctly"
110
+ - name: "Create other env vars for our own tests from server output"
111
+ run: |
112
+ echo "USER1_EMAIL=${{ steps.github_server.outputs.DA_ADMIN_EMAIL }}" >> $GITHUB_ENV
113
+ echo "USER1_PASSWORD=${{ steps.github_server.outputs.DA_ADMIN_PASSWORD }}" >> $GITHUB_ENV
114
+
115
+ - name: "ALKiln - Run if docassemble packages get installed correctly"
60
116
  if: ${{ success() }}
61
117
  id: alkiln
62
118
  uses: ./
119
+ env:
120
+ # Internal: docassemble changes sometimes break @a11y tests. That is
121
+ # a da problem, not ours. We will trigger these tests manually when we
122
+ # want to check up on this.
123
+ ALKILN_TAG_EXPRESSION: "${{ (github.event.inputs.tags && format('{0}', github.event.inputs.tags)) || '(not @error) and (not @temp_error)' }}"
63
124
  with:
64
125
  # Required inputs. See
65
126
  # https://assemblyline.suffolklitlab.org/docs/alkiln/writing/#sandbox-inputs
66
127
  SERVER_URL: "${{ steps.github_server.outputs.SERVER_URL }}"
67
128
  DOCASSEMBLE_DEVELOPER_API_KEY: "${{ steps.github_server.outputs.DOCASSEMBLE_DEVELOPER_API_KEY }}"
68
129
  INSTALL_METHOD: "server"
69
- ALKILN_TAG_EXPRESSION: "@e3" # One very simple test
70
- # ALKILN_VERSION:
130
+ ALKILN_TAG_EXPRESSION: "${{ env.ALKILN_TAG_EXPRESSION }}"
131
+ # ALKIlN_VERSION:
@@ -159,7 +159,7 @@ jobs:
159
159
  #### Developer note: You can probably leave the rest out
160
160
  #### To learn more, see https://assemblyline.suffolklitlab.org/docs/alkiln/writing/#optional-inputs
161
161
  ALKILN_TAG_EXPRESSION: "${{ env.ALKILN_TAG_EXPRESSION }}"
162
- # ALKILN_VERSION:
162
+ # ALKIlN_VERSION:
163
163
 
164
164
  #### Developer note: Example of making an issue when tests fail
165
165
  #### that includes the text of the failure output file
@@ -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
- # ALKILN_VERSION:
83
+ # ALKIlN_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
 
@@ -43,10 +44,49 @@ Format:
43
44
  -
44
45
  -->
45
46
 
46
- <!-- ## [Unreleased] -->
47
+ ## [Unreleased]
48
+
49
+ ### Changed
50
+
51
+ - Updated many dependencies
52
+ - Updated nodejs version
53
+
54
+ ## [5.17.2] - 2026-10-29
55
+
56
+ ### Added
57
+
58
+ - 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`.
59
+ - 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.
60
+
61
+ ### Changed
62
+
63
+ - 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).
64
+ - 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.
65
+ - Tweaked other log messages.
66
+
67
+ ### Fixed
68
+
69
+ - 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).
70
+ - Ensured new file upload buttons don't warn about duplicates since they have the same selectors.
71
+ - Restored wait for file upload completion signals. See [#1125](https://github.com/SuffolkLITLab/ALKiln/issues/1125).
72
+
73
+ ### Internal
74
+
75
+ - Fixed confusing error message when tests expected to fail actually pass.
76
+ - Started refactoring navigation functions to start untangling that rat's nest formed by overlapping motivations.
77
+ - Refactored getting different types of page errors (system error pages vs. user errors.)
78
+ - Started refactoring out `scope.examinePageID()` which is currently doing too many things.
79
+ - Added tests
80
+ - Fixed check for previous filenames on file uploads. See [#1125](https://github.com/SuffolkLITLab/ALKiln/issues/1125).
81
+ - Removed `shared_names` from global scope. See [#1125](https://github.com/SuffolkLITLab/ALKiln/issues/1125).
82
+ - Use latest AL docassemble image to run all tests instead of just one.
47
83
 
48
84
  ## [5.17.1] - 2026-10-13
49
85
 
86
+ ### Added
87
+
88
+ - 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.
89
+
50
90
  ### Changed
51
91
 
52
92
  - Updated to work with docassemble v1.10.n while being backwards compatible. See [issue #1117](https://github.com/SuffolkLITLab/ALKiln/issues/1117)
@@ -57,13 +97,13 @@ Format:
57
97
  - Unable to sign with a name
58
98
  - Unable to upload files
59
99
  - Created infinite loop with 'Restart' button
60
- - 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.
100
+ - 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.
61
101
 
62
102
  ### Internal
63
103
 
64
104
  - Added a workflow to test using an Assembly Line docker image
65
105
  - Test using a cron job to catch failures more regularly
66
- - Remove unsupported Step "Then I arrive at the next page" and moved responsibility to Steps that imply they navigate
106
+ - Remove unsupported Step `Then I arrive at the next page` and moved responsibility to Steps that imply they navigate
67
107
  - Fixed typo in fixture
68
108
 
69
109
  ## [5.17.0] - 2026-09-10
@@ -75,7 +115,7 @@ Format:
75
115
  ### Fixed
76
116
 
77
117
  - Fixed GitHub+You action outdated docassemble cli version causing Scenario timeouts.
78
- - Part 1 of detecting custom AL error screen: Story Table now catches `al_custom_error_screen` 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).
118
+ - 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).
79
119
 
80
120
  ### Internal
81
121
 
package/action.yml CHANGED
@@ -113,7 +113,7 @@ runs:
113
113
  - name: "💡 ALK0025 INFO: Set up node"
114
114
  uses: actions/setup-node@v6
115
115
  with:
116
- node-version: "24.x"
116
+ node-version: "26.x"
117
117
  package-manager-cache: false
118
118
 
119
119
  - name: "💡 ALK0026 INFO: Install ALKiln directly from npm"
@@ -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.
@@ -36,7 +36,7 @@ function build_config() {
36
36
 
37
37
  const config = {
38
38
  publishQuiet: true,
39
- require: `./lib/index.js`,
39
+ require: [ `./lib/index.js` ],
40
40
  format: [`progress`, `summary:${ SUMMARY_FILENAME }`],
41
41
  paths: feature_paths,
42
42
  retry: 1,