Skip to content

feat(web): Gesture Recognizer input sequence recorder 🐵#6952

Merged
jahorton merged 30 commits intofeat/web/gesture-recognizer-mainfrom
feat/web/recognizer-input-unit-testing
Aug 2, 2022
Merged

feat(web): Gesture Recognizer input sequence recorder 🐵#6952
jahorton merged 30 commits intofeat/web/gesture-recognizer-mainfrom
feat/web/recognizer-input-unit-testing

Conversation

@jahorton
Copy link
Copy Markdown
Contributor

@jahorton jahorton commented Jul 15, 2022

This entry in the 🐵 chain establishes the tools needed to support an input-sequence recorder page to be used for developing unit tests for the new module. While I previously planned to implement the unit test themselves in this PR... well, the changeset's already pretty big, so this'll be a good spot to split the two.

Features added:

  • I've created a folder within the module's tools section for testing and extracting the core model used by feat(web): first gesture-recognizer host page 🐵 #6878's host page so that it can be turned into a fixture for unit tests via shell script.
  • That fixture can also be inserted via shell script into other pages.
    • The recorder page itself is managed this way, as the fixture (in isolation) is also targeted for use in unit tests.
    • While not yet set to update the web/testing version, we could DRY things out by doing so.
  • Adds a unit-test-resources submodule within the tools section with a few utility TS classes based on the host page's code that are designed to be unit-test compatible while also usable by the recorder page.

@keymanapp-test-bot skip

@jahorton jahorton added this to the A16S6 milestone Jul 15, 2022
@keymanapp-test-bot keymanapp-test-bot bot added the user-test-missing User tests have not yet been defined for the PR label Jul 15, 2022
@keymanapp-test-bot
Copy link
Copy Markdown

keymanapp-test-bot bot commented Jul 15, 2022

@keymanapp-test-bot keymanapp-test-bot bot removed the user-test-missing User tests have not yet been defined for the PR label Jul 15, 2022
@@ -0,0 +1,113 @@
// This script allows user-interactive use of the user-testing oriented unit-test-resource objects.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

To make a comparison with a previous PR (#6878), this, along with the relevant classes under unit-test-resources, is effectively an up-do on its hostConfiguration.js. The caveat is that the backing script must be built first with this version, unlike that in #6878.

That said, it does allow us to do user-testing on classes that will see use by upcoming unit testing, so that's pretty neat. Well, it would be... if this were saved by our CI as a testing artifact. But it's not in a good place for that. (At least, not yet.)

FIXTURE_START=" <!-- START: recognizer host fixture -->"
FIXTURE_END=" <!-- END: recognizer host fixture -->"

sed -n "/$FIXTURE_START/, /$FIXTURE_END/{ /$FIXTURE_START/! { /$FIXTURE_END/! p } }" host-fixture.html No newline at end of file
Copy link
Copy Markdown
Contributor Author

@jahorton jahorton Jul 20, 2022

Choose a reason for hiding this comment

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

... and the differences between Mac sed (and awk) strike again.

GNU awk, at least, is possible to get on macOS via Homebrew, but that would mean more build-agent setup.

Alternatively... a small headless TS program should be able to handle this. Maybe I'll just take that approach instead, since we've already got Node in place anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

And, done. Fixture extraction + insertion each have their own node script now.

The exact setup may not be optimized, but it's at least "good enough".

@jahorton jahorton marked this pull request as ready for review July 20, 2022 08:59
ermshiperete
ermshiperete previously approved these changes Jul 21, 2022
Copy link
Copy Markdown
Contributor

@ermshiperete ermshiperete left a comment

Choose a reason for hiding this comment

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

I added a few comments, but those are mostly out of curiosity to improve my knowledge of ts/js.

roamingStyle?: RoamingLayoutClass,
receiverStyle?: ReceiverLayoutClass,
safeZoneStyle?: SafeLayoutClass);
constructor(deviceStyle?: DeviceLayoutClass,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

(sorry, this might be a dumb question/comment, but I'm not too familiar with Typescript/Javascript...)

Why do we have the exact same c'tor declaration/definition twice? Wouldn't it be sufficient to just have the ones in lines 42-45 and delete lines 38-41?

Or does it define the default c'tor? That might be more obvious by indenting lines 38-41 or something like that.

Copy link
Copy Markdown
Contributor Author

@jahorton jahorton Jul 21, 2022

Choose a reason for hiding this comment

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

The final constructor signature is the true internal signature, a catch-all that's compatible with the others seen above.

Any extra, preceding constructors are public overloads of each other. Intellisense will not include the final one; only the other versions.

In JS/TS, you can only ever define a single constructor per class. That multi-signature constructor is TypeScript's workaround to give the illusion of multiple constructors, but developers still have to do the "heavy lifting" within a single function to differentiate the possible intended codepaths for each public signature.

this._layoutConfig = new FixtureLayoutConfiguration();
}

public get recognizer() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What's the reason for not specifying the type here? Or why do you specify the type for layoutConfiguration() below?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

TS can pretty easily infer types in straightforward properties like these, though I'll still normally annotate them anyway just to be clear. I might have gotten a bit lazy here and relied on that for this particular property.

@mcdurdin mcdurdin modified the milestones: A16S6, A16S7 Jul 24, 2022
Copy link
Copy Markdown
Member

@mcdurdin mcdurdin left a comment

Choose a reason for hiding this comment

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

I will try and work on the build.sh tooling soon. For now, go ahead with what you've done and I can revisit it once I have written the action:target management.


# Thanks to https://stackoverflow.com/a/10107668 for this tidbit.
# Searches for FIXTURE_TARGET above and replaces it with the actual fixture!
node update-index.js build/index.html
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't understand why we need all the complexity of update-index.js and host-fixture for this? Why do we need to construct all this each time -- it seems like a lot of code to maintain.

Copy link
Copy Markdown
Contributor Author

@jahorton jahorton Jul 25, 2022

Choose a reason for hiding this comment

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

  1. To perform in-browser unit-tests, especially ones that match the user tests defined in one of this PR's ancestors, we need an HTML fixture. That much is pretty unavoidable.

  2. To keep our maintenance load down, it's best if that fixture match what is used on the recorder page. The unit tests may then function by simply "playing back" the recording on the same element configuration and verifying that we get the same results.

  3. For maintaining that fixture... note that the fixture will not function properly without its associated CSS. It's difficult to maintain those elements in isolation when the CSS isn't linked. (Of course, having a WET copy with it linked, then doing the ol' CTRL-C CTRL-V works well enough.) Took me a while to get the element configuration + CSS structure functional and to its current state, after all; even the HTML arrangement by itself isn't that straightforward.

  4. Since our team policy is generally "write DRY code when possible," this turned out to be the least complex / most maintainable way I could discern to meet that goal. We clearly need the same 'fixture' for both unit tests and unit-test resource recording. (It's also a near-duplicate with the user-testing 'host page, technically.) I could easily see updating the recorder page but forgetting to update the fixture at some point in the future; why not prevent that?

As far as the "maintenance" angle goes...

At one stage in development, I was using sed and awk to extract and insert, respectively. That said, my sed and awk skills are quite low, and the scripts broke instantly on Mac due to differences with the versions it natively includes.

On the flip-side, we're already using Node, JS, and TS, and we have code using the modules and functions in that script already. Also, I personally find it much easier to parse at a glance than the dense sed and awk constructions I "Frakensteined" together via StackOverflow references.

Now, one idea that may be slightly more palatable - what if the fixture were extracted from the recorder page, rather than defined in its own separate subfolder? We'd still need the extractor, to be sure, and it's worth noting that this proposal would technically overload the purpose of the tools/recorder subfolder.

@jahorton jahorton marked this pull request as draft July 25, 2022 04:59
@jahorton
Copy link
Copy Markdown
Contributor Author

jahorton commented Jul 25, 2022

The previous PR's likely to undergo some significant changes shortly, so I'm putting this back in draft.

Also, some of the already-existing changes may be better addressed by the new #6986, so it wouldn't hurt to incorporate that if it gets merged relatively quickly.

@jahorton jahorton marked this pull request as ready for review July 27, 2022 05:50
Base automatically changed from feat/web/recognizer-multipoint-tracking to feat/web/gesture-recognizer-main July 29, 2022 04:15
@jahorton jahorton dismissed ermshiperete’s stale review July 29, 2022 05:19

Significant underlying updates to the base branch necessitated some reworking.

@jahorton jahorton merged commit 501240e into feat/web/gesture-recognizer-main Aug 2, 2022
@jahorton jahorton deleted the feat/web/recognizer-input-unit-testing branch August 2, 2022 07:50
@jahorton jahorton mentioned this pull request Sep 19, 2022
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants