@suffolklitlab/alkiln 5.17.0 → 5.17.1-fix-stop-on-error-3

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.
@@ -1,10 +1,13 @@
1
- name: Use docassemble image version
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
- github-server-tests:
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:sha-7d13853"
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
 
@@ -62,4 +67,4 @@ jobs:
62
67
  DOCASSEMBLE_DEVELOPER_API_KEY: "${{ steps.github_server.outputs.DOCASSEMBLE_DEVELOPER_API_KEY }}"
63
68
  INSTALL_METHOD: "server"
64
69
  ALKILN_TAG_EXPRESSION: "@e3" # One very simple test
65
- # ALKILN_VERSION:
70
+ ALKILN_VERSION: "stop_on_error"
@@ -1,4 +1,4 @@
1
- name: GitHub server installation
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
- github-server-tests:
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
@@ -157,7 +159,7 @@ jobs:
157
159
  #### Developer note: You can probably leave the rest out
158
160
  #### To learn more, see https://assemblyline.suffolklitlab.org/docs/alkiln/writing/#optional-inputs
159
161
  ALKILN_TAG_EXPRESSION: "${{ env.ALKILN_TAG_EXPRESSION }}"
160
- # ALKILN_VERSION:
162
+ ALKILN_VERSION: "stop_on_error"
161
163
 
162
164
  #### Developer note: Example of making an issue when tests fail
163
165
  #### that includes the text of the failure output file
@@ -13,7 +13,7 @@ on:
13
13
 
14
14
  jobs:
15
15
 
16
- puppeteer-tests:
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
- # ALKILN_VERSION:
83
+ ALKILN_VERSION: "stop_on_error"
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,55 @@ 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.
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
+ - Restores 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.
63
+ - Ensured new file upload buttons don't warn about duplicates since they have the same selectors.
64
+
65
+ ### Internal
66
+
67
+ - Fixed confusing error message when tests expected to fail actually pass.
68
+ - Started refactoring navigation functions to start untangling that rat's nest formed by overlapping motivations.
69
+ - Refactored getting different types of page errors (system error pages vs. user errors.)
70
+ - Started refactoring out `scope.examinePageID()` which is currently doing too many things.
71
+ - Added tests
72
+
73
+ ## [5.17.1] - 2026-10-13
74
+
75
+ ### Added
76
+
77
+ - 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.
78
+
79
+ ### Changed
80
+
81
+ - Updated to work with docassemble v1.10.n while being backwards compatible. See [issue #1117](https://github.com/SuffolkLITLab/ALKiln/issues/1117)
82
+ - Unable to find some continue buttons
83
+ - Single-line fields like `yesno: likes_good_things`
84
+ - Buttons created with `buttons:`
85
+ - Continue buttons on signature pages
86
+ - Unable to sign with a name
87
+ - Unable to upload files
88
+ - Created infinite loop with 'Restart' button
89
+ - 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.
90
+
91
+ ### Internal
92
+
93
+ - Added a workflow to test using an Assembly Line docker image
94
+ - Test using a cron job to catch failures more regularly
95
+ - Remove unsupported Step `Then I arrive at the next page` and moved responsibility to Steps that imply they navigate
96
+ - Fixed typo in fixture
97
+
48
98
  ## [5.17.0] - 2026-09-10
49
99
 
50
100
  ### Changed
@@ -54,7 +104,7 @@ Format:
54
104
  ### Fixed
55
105
 
56
106
  - Fixed GitHub+You action outdated docassemble cli version causing Scenario timeouts.
57
- - 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).
107
+ - 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
108
 
59
109
  ### Internal
60
110
 
@@ -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, },