Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace harness instruction page rendering #434

Closed

Conversation

mzgoddard
Copy link
Contributor

@mzgoddard mzgoddard commented May 19, 2021

The harness module is given a test json of commands to perform and assertions to record the results of. This change replaces the manual DOM rendering and manual updates of the test instructions and result form with an object representing the test results, from which a second object, the instruction document, is created representing the structure, text, and user event handlers to update the first object. This separates the application state of the instructions and result entry from the DOM so that it can be reused outside the harness module.

This change further uses the added instruction document type and produces the existing DOM with a small virtual dom module. From the perspective of someone running the commands and entering the results into the form, there should be no change in the page’s behavior.

Progress

This change is almost complete. Briefly, I think to complete it, the result state needs to be turned into the summary object for submission. Below is an overview of the steps implemented.

  • Type definitions
    • Define the type of the Test JSON input, stored in the harness behavior module scope variable
    • Define the type of the Commands JSON input
    • Define the type of the Support JSON input
    • Define the type of the submitted results produced when Submit Results is clicked
    • Define a type of the state of the user input results
    • Define a type that represents the displayed text and result input fields of the test input and state of the results
  • Update state of results from user events sent to functions in the instruction document representation
    • Update atOutput text for a command
    • Update an assertion for a command
    • Update an additional assertion for a command
    • Update if there are or are not undesirable results
    • Update individual undesirable entries
    • Update other undesirable text input
    • Update if field should highlight when required when validating
  • Create the document object following the defined type
  • Create the result submission following the defined type
  • Track document item focus when updating the result state
    • Focus header after page load
    • Focus next or previous checkbox when pressing relevant keyboard keys
    • Focus first required and not set result input after validating before submitting the result
  • Render the document object into DOM
    • Render updates with a virtual dom to maintain minimal changes to dom like prior manual change implementation
    • Transform DOM events into relevant input to functions in document object
      • Transform text input change event
      • Transform radio click event
      • Transform checkbox change and keydown event
      • Transform open test pop click event
      • Transform submit results click event

@mzgoddard mzgoddard force-pushed the mzgoddard-harness-controller-and-render branch from cbd29da to fd54347 Compare May 19, 2021 14:21
@@ -0,0 +1,906 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is pretty mind blowing! This ain't everyday JS, this is shiny stuff. I find myself wondering how you did this!

I think, and correct me if I'm wrong, that this is a virtual DOM implementation to be used for rendering the tests, and I believe from our conversations that we wouldn't use it in the app, it would be confined to the aria-at repo.

Which of course, the thought of having to come in here to fix something is making me sweat slightly, haha. It's frankly over my head right now. So my question is, is there a way to avoid having to maintain this ourselves? I'm sure the reasoning is solid but I was hoping you would take a little time to help me grasp it.

Finally, I was wondering if there's a good way to test this file specifically. How do I put it through its paces so I feel like I gave it the review it deserves?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to echo @alflennik's comments, could you share your rationale for writing a custom implementation?

Any reason you didn't lean on a more commonly used dependency such as lit-html or snabbdom?

Copy link
Contributor Author

@mzgoddard mzgoddard Jun 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, and correct me if I'm wrong, that this is a virtual DOM implementation to be used for rendering the tests, and I believe from our conversations that we wouldn't use it in the app, it would be confined to the aria-at repo.

Yes. aria-at-app will use the javascript object produced by instructionDocument. aria-at itself renders that same object with this virtual DOM implementation.

I'll use the rest of this comment to reply to Seth's added point.

to echo @alflennik's comments, could you share your rationale for writing a custom implementation?

Any reason you didn't lean on a more commonly used dependency such as lit-html or snabbdom?

My thoughts on priorities in this PR

  1. Add a rendering library
    • tracks state in js objects and not dom
    • output a document, a js object, representing the structure, text, and event handling that can be transformed into dom by the library consumer (e.g. aria-at-app)
  2. Maintain behavior
    • Focus on the page header on first render
    • On keyboard event on a checkbox focus an adjacent checkbox
    • Change classes when submitting results when some fields are invalid, focus the first invalid form input
  3. Keep a low probability of adding bugs in this change
    • Produce the same html structure
  4. Minimal external dependencies
  5. Easy to turn instructionDocument into the current html shape
    • Many adjacent elements represent a semantic section without a parent element
    • Fragments like in React give an easy way to produce a html structure with semantic and not structural sections
    • Fragments help break up long sequences of adjacent elements into helper functions
  6. Ease of changing the rendering in the future after this PR
    • Such as supporting new test features

dom libraries comparison

  • LitHTML

    • Adds one dependency
    • Cannot produce the same dom
      • Inserts html comments at dynamic content locations
        • I find it hard this would have an impact but conservatively I want to avoid it
      • Supporting focus behavior
        1. Option: Use components and their update hook
          • Components are web components (custom elements)
          • This would put a change into the html structure
        2. Option: Manually find the right element after rendering without components and focus it
  • Snabbdom

  • vrender

    • Internal dependency
      • Like @alflennik pointed out we would be maintaining this
    • Fragment support

Copy link
Contributor

@alflennik alflennik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really thankful you opened this up to early review Z, because this is going to take all my brainpower to review, haha, and definitely multiple passes. It's really amazing how you were able to turn this file upside down and right side up again. I think this file has been beyond mortal reach for a while, but with these changes I definitely feel like that is about to change.

tests/resources/aria-at-harness.mjs Outdated Show resolved Hide resolved
tests/resources/aria-at-harness.mjs Outdated Show resolved Hide resolved
tests/resources/aria-at-harness.mjs Outdated Show resolved Hide resolved
tests/resources/aria-at-harness.mjs Outdated Show resolved Hide resolved
tests/resources/aria-at-harness.mjs Outdated Show resolved Hide resolved
tests/resources/aria-at-harness.mjs Outdated Show resolved Hide resolved
tests/resources/aria-at-harness.mjs Outdated Show resolved Hide resolved
@mzgoddard mzgoddard force-pushed the mzgoddard-harness-controller-and-render branch from 86420f3 to a2b93a2 Compare June 11, 2021 14:54
@mzgoddard mzgoddard marked this pull request as ready for review June 11, 2021 15:01
Copy link
Contributor

@howard-e howard-e left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outside of nitpicks and what's been spoken about before, I'm finding it difficult to add much from a technical standpoint. This is without a doubt, impressive! I also believe it has been tested well enough to some degree to be convinced it does exactly what it has been proposed to do.

However, my general concern is around the maintainability of it, to also echo @alflennik, should any additional work ever be required. I know things are still changing but maybe some additional descriptions should start getting added in with the newly added JSDoc tags (which is impressive in and of itself as well) to describe further what these inputs are, especially the map, object and any properties. This should be helpful to others down the line in helping to alleviate this concern.

In a previous meeting we had as well, you provided very useful descriptions on the overall purpose of each file which I believe helped my understanding immensely going in. So having a similar write-up could be helpful to capture your initial thoughts for others as well I believe.

tests/resources/aria-at-harness.mjs Show resolved Hide resolved
* @typedef {EnumValues<typeof AdditionalAssertionResultMap>} AdditionalAssertionResult
*/

export const AdditionalAssertionResultMap = createEnumMap({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I certainly agree with the separation of concerns for the Maps here but it does feel like a few of these could be packaged into 1, especially the ...AssertionMaps because they are related and it could limit the amount of documentation/'looking for property in wrong map' errors one could possibly encounter? Just a thought.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Yeah at this point I just wanted to mirror the values that get exported with ones in the internal state that follow a common idiom.


export const AdditionalAssertionResultMap = createEnumMap({
...CommonResultMap,
FAIL_SUPPORT: "failSupport",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I noticed the values of these generated Maps all seem to differ between camelCase, natural language and capitalized. I figure it has to do with where their respective values will be used. Perhaps their appropriate usage could be described in their JSDoc tags?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. The natural language, spaced and title cased, values and the all capitalized values are values as they already appear in the json object built and submitted from the test result from input. I'll add something like that to the doc tags.

tests/resources/vrender.mjs Outdated Show resolved Hide resolved
- add an Application to the harness that maintains an internal state,
  produces a non-dom document with all the page's structure and text and
  representation of the internal state and functions to change state and
  produce a new accompanying document
- add a reduced in-repo virtual dom renderer
- render the non-dom document with the virtual dom renderer
@mzgoddard mzgoddard force-pushed the mzgoddard-harness-controller-and-render branch from 62f38c6 to 1f54b16 Compare July 27, 2021 14:32
@mzgoddard mzgoddard marked this pull request as draft July 27, 2021 15:33
@mzgoddard mzgoddard closed this Jul 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants