@suffolklitlab/alkiln 5.13.2 → 5.13.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.
- package/.github/workflows/github_server.yml +1 -1
- package/.github/workflows/playground.yml +1 -1
- package/CHANGELOG.md +8 -1
- package/docs/constrained_random_tests.md +27 -0
- package/docs/decisions/move_runtime_config_to_sources_folder.md +1 -0
- package/docs/prioritize_constrained_random_tests.md +101 -0
- package/docs/seprate_file_generation_GitHub_action.md +11 -0
- package/lib/scope.js +9 -2
- package/package.json +1 -1
|
@@ -160,7 +160,7 @@ jobs:
|
|
|
160
160
|
#### Developer note: You can probably leave the rest out
|
|
161
161
|
#### To learn more, see https://assemblyline.suffolklitlab.org/docs/alkiln/writing/#optional-inputs
|
|
162
162
|
ALKILN_TAG_EXPRESSION: "${{ env.ALKILN_TAG_EXPRESSION }}"
|
|
163
|
-
ALKILN_VERSION:
|
|
163
|
+
# ALKILN_VERSION: da_DOM_fieldset
|
|
164
164
|
|
|
165
165
|
#### Developer note: Example of making an issue when tests fail
|
|
166
166
|
#### that includes the text of the failure output file
|
package/CHANGELOG.md
CHANGED
|
@@ -43,11 +43,18 @@ Format:
|
|
|
43
43
|
-
|
|
44
44
|
-->
|
|
45
45
|
|
|
46
|
-
## [Unreleased]
|
|
46
|
+
<!-- ## [Unreleased] -->
|
|
47
|
+
|
|
48
|
+
## [5.13.3] - 2025-01-05
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- Updates to latest docassemble HTML. See [#960](https://github.com/SuffolkLITLab/ALKiln/issues/960). Changes all appearances of `fieldset` to keep the code consistent.
|
|
47
53
|
|
|
48
54
|
## [5.13.2] - 2024-11-23
|
|
49
55
|
|
|
50
56
|
### Fixed
|
|
57
|
+
|
|
51
58
|
- Fixes download Step unable to use a partial filename match. The Step needed the whole name, including the extension. See [#725](https://github.com/SuffolkLITLab/ALKiln/issues/725).
|
|
52
59
|
|
|
53
60
|
## [5.13.1] - 2024-10-23
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Constrained random input tests architecture and decisions
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## What should throw an error in the generator parsing stage?
|
|
5
|
+
|
|
6
|
+
Nothing? Should it all get reported in the ALKiln tests?
|
|
7
|
+
|
|
8
|
+
## Author wrote multiple generator Steps in one Scenario
|
|
9
|
+
|
|
10
|
+
Discuss: Warning or error
|
|
11
|
+
|
|
12
|
+
We think the easiest and clearest reaction is to refuse to generate any test and give a warning or error.
|
|
13
|
+
|
|
14
|
+
Other options:
|
|
15
|
+
|
|
16
|
+
- Use the last Step and delete the others. This may be hard to do. We'd need to mutate the Scenario's file text lines, maybe as we were looping through them. It would take some research
|
|
17
|
+
- Use the first Step and leave the others as they are. This would generate a broken test, but the test would at least work until it gets to the next generator Step line. We could add a Step in the core code for the generator Step and use it to give a meaningful error instead of just letting cucumber set a status of `undefined`. Maybe that would at least be a bit more clear, but I think not as clear as just refusing to generate and producing a warning or error.
|
|
18
|
+
|
|
19
|
+
Complications:
|
|
20
|
+
|
|
21
|
+
- What if there are other Steps between and after the generator Steps? Do we keep those and put them all at the bottom? Do we only keep the ones after the chosen generator Step?
|
|
22
|
+
|
|
23
|
+
If we do decide to pick a generator Step, maybe we can make sure to pick one that is otherwise valid. That is, it has a dataTable that has rows, is otherwise correctly formatted, etc.
|
|
24
|
+
|
|
25
|
+
## Grammar
|
|
26
|
+
|
|
27
|
+
Post MVP, discuss: should generator Steps without a number, but with the word "tests" generate 2 Scenarios?
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Moving the runtime config to the sources folder would make it very easy for each Project to have its own runtime config which would make ALKilnInThePlayground work more smoothly. On the other hand, it could be confusing to authors (though it's fine if they check it in now, it may not be fine later). On the other other hand, we could delete it after every test suite run and and "temp" and "alkiln" to the name. If there are multiple sources folders with config files then...? We'll just have to pick one?
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Constrained random input tests
|
|
2
|
+
|
|
3
|
+
I do 10 constrained random tests
|
|
4
|
+
|
|
5
|
+
## Why do people want purely random input tests?
|
|
6
|
+
|
|
7
|
+
1. They don't have time to write individual specific tests
|
|
8
|
+
2. They are worried they haven't covered all eventualities
|
|
9
|
+
|
|
10
|
+
## Problems for purely random tests
|
|
11
|
+
|
|
12
|
+
- Non-specific input. E.g. a name field might get a sentence. Can we do our best? That would be more work.
|
|
13
|
+
|
|
14
|
+
## Why would people prefer constrained random input tests?
|
|
15
|
+
|
|
16
|
+
- They want to make the tests more focused on certain scenarios and avoid wasting time on unimportant tests. For example, sometimes several options actually give the same answer. A purely random test would give more preference to the repeated answer.
|
|
17
|
+
- **Some fields might require very specific answers, like a real lawyer's bar number or a specific file name for uploading exhibits.**
|
|
18
|
+
- Narrow down the paths at some points, like always choosing that you have minor children
|
|
19
|
+
- **Even if the user doesn't know it, this is the most flexible option**
|
|
20
|
+
|
|
21
|
+
## Note
|
|
22
|
+
|
|
23
|
+
~~If in the future we want to add the option to not specify, then we can and it won't be a breaking change.~~
|
|
24
|
+
|
|
25
|
+
We have to decide what it means to allow a person to not specify. E.g if excluding a row means don't give an answer to that variable at all, then it can't in future mean "give a random answer to this field". Options:
|
|
26
|
+
|
|
27
|
+
- (bad) Excluding a row means don't give an answer. Including a row with a blank answer means give a random answer.
|
|
28
|
+
- (bad) Including a row with a blank answer means don't give an answer. Give unlisted variables random answers.
|
|
29
|
+
- Or should we require a string (e.g. ALK_NO_ANSWER) for fields that should not get random inputs?
|
|
30
|
+
- (most easy purely random input method to implement without changing current code?) Or specify randomness (e.g. ALK_RANDOM_ANSWER)?
|
|
31
|
+
- **(backwards compatible because we can become more flexible later) Require both of the above?**
|
|
32
|
+
|
|
33
|
+
Which of these is worse? Mind reading can be bad. On the other hand, specifying everything may be somewhat antithetical to the 2 goals of people who want purely random input tests. (added to the interview an unrequired value, but forgot to add it to the test, they won't test all eventualities).
|
|
34
|
+
|
|
35
|
+
Possible solutions for people who want purely random tests or bits of tests:
|
|
36
|
+
- Add a Step for answering randomly for a whole test.
|
|
37
|
+
- Add a Step for answering randomly up to various page ids (list is allowed).
|
|
38
|
+
- Add Step to answer randomly for one page.
|
|
39
|
+
|
|
40
|
+
## Flexible constraints?
|
|
41
|
+
|
|
42
|
+
Post MVP
|
|
43
|
+
|
|
44
|
+
- Allow number range "ALKiln: [1, 5)"? Or they have to do "1, 2, 3, 4"
|
|
45
|
+
- "ALKiln: year 1965 - 1999"
|
|
46
|
+
- "ALKiln: date [today, today - 10)"
|
|
47
|
+
- "ALKiln: max length 3" (of 5 checkbox answers)
|
|
48
|
+
- "ALKiln: name"
|
|
49
|
+
- "ALKiln: number" (and other types like "currency") (we can probably figure those out)
|
|
50
|
+
|
|
51
|
+
## Note
|
|
52
|
+
|
|
53
|
+
MVP of random input tests
|
|
54
|
+
|
|
55
|
+
## no seeds
|
|
56
|
+
|
|
57
|
+
seeds can break more easily. instead we save the spec of the test(s)
|
|
58
|
+
|
|
59
|
+
## MVP
|
|
60
|
+
|
|
61
|
+
save the spec of the test...somewhere. Probably using special name to say
|
|
62
|
+
"rerun" and then change the name at the end of the run.
|
|
63
|
+
retry the test somehow (if needed)...
|
|
64
|
+
present the test and results to the user
|
|
65
|
+
|
|
66
|
+
## Better
|
|
67
|
+
|
|
68
|
+
Avoid repeating previous random tests
|
|
69
|
+
Avoid repeating tests of users (which is much(?) harder)
|
|
70
|
+
|
|
71
|
+
## Specifics
|
|
72
|
+
|
|
73
|
+
Create a file with a certain # of Scenarios and run it
|
|
74
|
+
- Does cucumber decide the tests it'll run at runtime or before? I think the former
|
|
75
|
+
- Is it better to split tests up into separate files if there are a lot?
|
|
76
|
+
- Is it better or worse to help the developer feel the magnitude of the #
|
|
77
|
+
of tests they're running (using Example) [Answer: worse]
|
|
78
|
+
- How to handle separate constrained random tables?
|
|
79
|
+
|
|
80
|
+
## right now
|
|
81
|
+
[r1 opt 1, r1 opt 2, r1 opt 3, name input, date input, description input]
|
|
82
|
+
|
|
83
|
+
## need for random
|
|
84
|
+
|
|
85
|
+
detect r1 while looping through the fields
|
|
86
|
+
[r1 opt 1, r1 opt 2, r1 opt 3, name input, date input, description input]
|
|
87
|
+
Con: as we loop through, we don't know the number of options at each particular instance
|
|
88
|
+
|
|
89
|
+
or make grouped fields into groups. Basically group r1:
|
|
90
|
+
[[r1 opt 1, r1 opt 2, r1 opt 3], name input, date input, description input]
|
|
91
|
+
|
|
92
|
+
## why not generate a test that uses all the constraints and thus is fully random?
|
|
93
|
+
|
|
94
|
+
Because we'd have to parse docassembled *compiled* files, which is very hard
|
|
95
|
+
|
|
96
|
+
Alternative:
|
|
97
|
+
|
|
98
|
+
When the developer runs a test, they can use a Step to have it collect all possible fields that ALKiln sees during that test run.
|
|
99
|
+
Q: How effectively can we decode the fields? Or can we make a tool that will help a developer decode their fields? (Include an input that just decodes one encoded string (`atob()`))
|
|
100
|
+
Q: If the fields are multiple choice and the developer's test picks at least one choice from that group of fields, can we use that to properly decode all the names of the fields? Hesitant to do this because some values may be encoded differently from other values (I think).
|
|
101
|
+
Q: Is this more work than just refactoring how we group fields?
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Pros for separate action:
|
|
2
|
+
|
|
3
|
+
- Reflects nature of process - generating files is inherently separate.
|
|
4
|
+
- Potentially cleaner separation conceptually for us.
|
|
5
|
+
|
|
6
|
+
Cons:
|
|
7
|
+
|
|
8
|
+
- Main beef: Developing and maintaining GitHub actions is hard
|
|
9
|
+
- Authors have more in their workflow file
|
|
10
|
+
- Need to update existing workflows
|
|
11
|
+
- Need to update ALKilnSetup interview
|
package/lib/scope.js
CHANGED
|
@@ -514,13 +514,17 @@ module.exports = {
|
|
|
514
514
|
},
|
|
515
515
|
|
|
516
516
|
continue_button_selector: `fieldset.da-field-buttons button[type="submit"].btn-primary`,
|
|
517
|
+
continue_button_selector_backup: `.da-fieldset.da-field-buttons button[type="submit"].btn-primary`,
|
|
517
518
|
signature_selector: `fieldset .dasigsave`,
|
|
519
|
+
signature_selector_backup: `.da-fieldset .dasigsave`,
|
|
518
520
|
continue: async function ( scope ) {
|
|
519
521
|
/* Presses whatever button it finds that might lead to the next page. */
|
|
520
522
|
// Any selectors I find seem somewhat precarious.
|
|
521
523
|
let elem = await Promise.race([
|
|
522
524
|
scope.page.waitForSelector(scope.continue_button_selector), // other pages (this is the most consistent way)
|
|
525
|
+
scope.page.waitForSelector(scope.continue_button_selector_backup),
|
|
523
526
|
scope.page.waitForSelector(scope.signature_selector), // signature page
|
|
527
|
+
scope.page.waitForSelector(scope.signature_selector_backup),
|
|
524
528
|
]);
|
|
525
529
|
await elem.evaluate( el => { return el.className });
|
|
526
530
|
// Waits for navigation or user error
|
|
@@ -540,9 +544,11 @@ module.exports = {
|
|
|
540
544
|
// <button type="submit" class="btn btn-da btn-danger" name="X211bHRpcGxlX2Nob2ljZQ" value="0">exit</button>
|
|
541
545
|
// `buttons:` can be used in question blocks as choices
|
|
542
546
|
let regular = await scope.page.$(scope.continue_button_selector);
|
|
547
|
+
let regular_backup = await scope.page.$(scope.continue_button_selector_backup);
|
|
543
548
|
let signature = await scope.page.$(scope.signature_selector);
|
|
549
|
+
let signature_backup = await scope.page.$(scope.signature_selector_backup);
|
|
544
550
|
|
|
545
|
-
return regular !== null || signature !== null;
|
|
551
|
+
return regular !== null || regular_backup !== null || signature !== null || signature_backup !== null;
|
|
546
552
|
|
|
547
553
|
}, // Ends scope.continue_exists()
|
|
548
554
|
|
|
@@ -916,7 +922,7 @@ module.exports = {
|
|
|
916
922
|
// All the different types of fields
|
|
917
923
|
// buttons, canvases, inputs of all kinds, selects (dropdowns), textareas. Are there more?
|
|
918
924
|
// Will deal with `option` once inside `select`
|
|
919
|
-
let all_nodes = $( `#dasigpage, fieldset button, .daquestionactionbutton, fieldset input, .da-form-group input, .da-form-group select, form select, .da-form-group textarea` );
|
|
925
|
+
let all_nodes = $( `#dasigpage, fieldset button, .da-fieldset button, .daquestionactionbutton, fieldset input, da-fieldset input, .da-form-group input, .da-form-group select, form select, .da-form-group textarea` );
|
|
920
926
|
for ( let node of all_nodes ) {
|
|
921
927
|
// Decision: Do not abstract the below. There's too much data to pass around for it to make sense
|
|
922
928
|
let $node = $( node );
|
|
@@ -2635,6 +2641,7 @@ module.exports = {
|
|
|
2635
2641
|
|
|
2636
2642
|
let fullPage = true;
|
|
2637
2643
|
let signature_elem = await scope.page.$(scope.signature_selector);
|
|
2644
|
+
signature_elem = signature_elem || await scope.page.$(scope.signature_selector_backup);
|
|
2638
2645
|
if ( signature_elem !== null ) {
|
|
2639
2646
|
fullPage = false;
|
|
2640
2647
|
}
|