linkedin / css-blocks

High performance, maintainable stylesheets.
http://css-blocks.com/
BSD 2-Clause "Simplified" License
6.33k stars 152 forks source link

CSS Blocks Test Helpers for Ember #480

Closed chriseppstein closed 3 years ago

chriseppstein commented 3 years ago

We need to provide test helpers that allow a developer to perform assertions about what css block styles are currently applied to an element.

For debugging purposes, I already wrote code to generate a human-readable css-blocks name for the block styles that are currently applied to an element including those that are inferred through composition and inheritance. Unfortunately, the downside of the human-readable name I have right now is that the block only known as a guid (E.g. a4f31:scope[enabled]) and that guid isn't stable across machines so a direct reference to the guid in test code isn't feasible.

The basic idea for testing is to put these human readable strings into the class list of the element but only when the tests are running so that the element has something like class="a4f31:scope a4f31:scope[enabled] a0 b7 c3". These human readable classes won't match any selectors but they will provide a way to assert that the element has a particular block style via element.classList.contains()

So the first challenge is to provide a way to map some sort of consistent reference to a block from the test code and to do this without further bloating the runtime data that we're currently sending to the browser. This means that we'll need to get some metadata into the test bundle so that the test code can import it. For example:

import cssBlocksTestSupport from "my-app/css-blocks-test-support";
// I'm not sure how to get a handle to the css blocks service from a test.
// it should be able to be dependency injected.
cssBlocksService.enableDebugMode(cssBlocksTestSupport);
let darknessBlock = cssBlocksTestSupport.getBlock("@linkedin/hue-web-foundations", "darkness");
let darkness = darknessBlock.style(":scope");
assert(element.classList.contains(darkness));

The reason we should pass cssBlocksTestSupport into the service call is that, in the future, it is my plan that the actual block style names won't be part of the runtime deliverable -- I should be able to optimize them away to just being a unique number. So I'd like to provide appropriate API surface that we can move the style name generation to the test meta data in the future. That call might do nothing with the test metadata right now, but we should require it in order to put css blocks into debug mode so that we can use it in the future.

We should be able to generate a javascript file that contains the API and the relevant data using the treeForTestSupport hook from our @css-blocks/ember-app addon.

The tree containing the compiled block files in the final application build is probably the easiest way to construct human meaningful paths to the blocks. In that tree there's a subdirectory for the application, a subdirectory for addons, and a subdirectory for lazy engines. This is some code where I search through the various subdirectories to look for references to block files.