Storybook: Browser Support Addon - New Addon Feature
 - Based on static analysis

Created on 27 Mar 2019  ·  12Comments  ·  Source: storybookjs/storybook

Feature description
One of the largest issues when developing an application for a wide array of users is ensuring that a component will work in Chrome, IE, Firefox, Safari, etc.. At the moment, the best way to determine if your component is likely to look the same across browsers is to test them in each. Based on static analysis, the Browser Support addon will offer the information necessary to increase the confidence level developers need to have in their component’s browser compatibility.


I see three main use cases for this feature (but there may be more):

  • A developer is working on a component that they would like to make more compatible with a set of browsers
  • A designer who is looking to make sure that the components in the project work for the set of browsers they support
  • A new user of the project/library who is looking to see if they can use a component in their project while factoring in browser compatibility

User abilities
A user will be able to provide a list of browsers that they want to support in the config file.
The add-on will analyze the CSS styling on each element in the component rendered in the DOM to determine if the element is compatible with the browser list provided. Based on this data, a high-level view of browser support can be displayed in a score-like format (think Google Lighthouse).


At a fine grain level, the user will be able to see which elements in the rendered component do not pass browser compatibility testing (and what they can do to fix those issues). In the future, we can add the option to highlight where the issue is are located on the screen (similar to the implementation of highlighting in a11y).

Implementation thoughts
In order to develop this feature, we can use data from CanIUse found here: https://github.com/Fyrd/caniuse. We can also look to other projects like https://github.com/ben-eb/caniuse-lite and https://github.com/anandthakker/doiuse to use their packages or for inspiration.

Handling static analysis of JavaScript Is a little tougher but I'm sure we could come up with a good design for that. https://github.com/amilajack/eslint-plugin-compat is a nice static analysis tool that does something similar to what we would be looking for. The eslint plugin also uses the data from CanIUse.

Where should we start?
I would suggest that we start with CSS analysis and work our way towards validating Javascript. For an MVP, we could accept browsers from the user and give metrics/scores about browser support at the component level. Following the MVP, we can add highlighting and more information at the element level for each component. We can then move on to Javascript analysis.

Are you able to assist bring the feature to reality?
I can serve in a limited capacity in the code development of this feature and I can assist with accessibility, creating a roadmap, solutioning, and research.

Would anyone be interested in collaborating on this?

addons feature request help wanted inactive

Most helpful comment

I think this would make a great addon and a useful standalone library/tool like axe. If there were more "check the DOM" use cases like this, I could even imagine generalizing addon-a11y into a generalized checker.

All 12 comments

I think this would make a great addon and a useful standalone library/tool like axe. If there were more "check the DOM" use cases like this, I could even imagine generalizing addon-a11y into a generalized checker.

In looking at the above libraries, they all use manual feature data updates and it could be dicey to create those kind of dependencies. Perhaps there is a way to implement something along the lines of:
https://github.com/una/caniuse-component

...as a separate panel that would display the features you are currently using (optionally features you specify as well) and load compatibility tables for those features directly from caniuse.

@pgoforth Thanks for the feedback! Just took a look into the caniuse-component and it looks interesting and is similar to what we want to do at the component level at the "CSS Property Name" level. Maybe we can take some tips about how they wrote their code but it looks like it depends on caniuse-api which depends on caniuse-lite. A lot of projects rely on caniuse-lite and it looks like caniuse-lite generates their dataset from the caniuse-db in an automated way based on the following statement: "The contents of this section have been generated automatically; each version tracks the caniuse-db package at the same version." It's been updated almost daily for a while so it seems pretty reliable. If we didnt want to risk it, we could try using the full dataset from caniuse-db and writing our own parser and api but that would be a lot to take on for an MVP. When this gets off the ground, maybe we can reconsider then. What do you think?

@pgoforth, would you be interested in helping out with this addon?

@CodeByAlex
This is something that I could work on, although I think it's going to be a long running project unless the scope is limited. Analyzing the Javascript itself is a particularly tedious task. Based on my limited understanding of the Storybook addon structure, the story is fed through the addon at runtime. How would you determine what features were being used by the story at runtime? Determining CSS is a slightly easier task, but what about third party CSS loaded at runtime through something like addon-cssresources? Stories that contain components that update their own classNames? Stories that add or remove styled elements or javascript functionalities by changing props through addon-knobs?

I think the best route forward that would provide the most concrete plan of attack is to create an addon that would allow you to provide specific requirements (CSS, HTML and Javascript) into the addon and have the panel display the requirements for that particular story based on those provided requirements. Make sense? I'm envisioning something like:

storiesOf('caniuse', module)
    .add('FancyReactComponent', () => {
        return (
            <FancyReactComponent />
        );
    }, {
        caniuse: {
            html: [ 'canvas', 'details', 'summary' ],
            javascript: [ 'fetch', 'requestAnimationFrame' ],
            css: [ 'css-variables' ],
        },
    })

Let me know if that's something that would work...because something much more involved than that would require a lot of effort that may not even do what you are wanting it to do.

@pgoforth Thanks for getting on board for this addon:) I agree that the initial scope has to be limited. I think that hardcoded caniuse options is an interesting approach for this addon but those options would have to be changed whenever the component is updated and really doesn't test the components capabilities which is the goal I'm hoping we can meet with this addon.

What I'm thinking is that we can run analysis on the css of each element after it is rendered. Just like a11y, this will occur on the initial state that the component comes in to view. If the user wants to re-run the analysis, we can give them the option to do so(might be out of scope). By checking at the element level, the styles will consist of 3rd party library styles and any default styling that's applied, knob defaults included.

After speaking with you, @Armanio, and @leoyli, I think it might be best if I come up with a very rudimentary addon MVP (nothing flashy) that we can start building off of. If I run into some issues along the way and I can bring those up in this thread.

Do you think the scope above is restricted enough? Let me know what you think

*I didnt think about testing against HTML (that would be pretty cool to add on down the road)

To get thing clear, is the current direction focused on CSS compatibility only?! That is how I see this can take a similar approach from a11y.

Also, I would suggest we start from React as the baseline since the main SB App is based on it. And to make things easier later, I think we should take TypeScript from the ground up. However, based on my experience on addon-contexts, building addon on TS in an SB client/main-repo is really awful... We might want to build this addon out of the main repo, which should make things easier at beginning.

@leoyli I think the end goal would be to test css, javascript, and html. We have to start somewhere though and Im thinking CSS could be a good place to start. Of course, if others think differently, we can certainly discuss that.

I totally agree that we should start by using typescript. Not sure that we have to start by focusing on React. Seems like an implementation to check the dom would be framework agnostic. May get more tricky when we get into checking JavaScript later on.

Glad you have some experience with creating addons. If you think it was easier breaking the addon off into its own repo to start, lets do that. Just created an empty repo here: https://github.com/CodeByAlex/storybook-browser-support-addon

The main reason for building from React is due to the need of communicating between the SB manager (panel/toolbar/view-mode, etc) and the story decorator. A story decorator is nothing but a parent component of a story, so it have to align with its underlying story rendered with its framework of choice.

I believe we will need to choose a framework for prototyping, then React is a reasonable choice for aligning with SB manager first. And of course, we will bring this addon framework agnostic at the end.

I think the most tricky part is to identify what to analyze and how to get it right (where the source came from, run-time? compile-time?). CSS alone is actually quite messy already since it can be inline, injected style block, external css file, even being manipulate directly via CSSOM (<- the so called speedy mode in the CSS-in-JS wonderland)...

Thanks, @leoyli for the insight! I guess Ill have to look into making sure we can get all types of styling from a single element. I was thinking we could solve this by doing something like this: https://zellwk.com/blog/css-values-in-js/. That way you wouldn't have to worry about the source of the styles are being applied.

We would get all nodes that stem from #root and pull the CSS from each element post render. If an attribute is set that isn't supported in all browsers, we would be able to tell. Based on what you're saying, I'm wondering if this is too simple of an approach but would have to verify

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tirli picture tirli  ·  3Comments

tomitrescak picture tomitrescak  ·  3Comments

zvictor picture zvictor  ·  3Comments

wahengchang picture wahengchang  ·  3Comments

shilman picture shilman  ·  3Comments