-
Notifications
You must be signed in to change notification settings - Fork 325
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
Provide a way for maintainers of ports to check that they're using equivalent HTML markup #1830
Comments
This would be really useful for a Jinja port I've recently started: https://github.com/LandRegistry/govuk-frontend-jinja The code in the repo above is generated by an automated script that creates Jinja equivalent macros for each of the Nunjucks ones. This is currently run within each frontend app itself at build time. I'd rather this was an installable package from PyPi to help manage version upgrades, remove some additional complexity from the app, and have a robust set of tests to prove compatibility. Ideally, I want to render the HTML output using a single set of inputs, for both the original Nunjucks and Jinja ported macros, then diff and fail tests if they're not identical. As you can see, not got very far with this yet so feedback/contributions very welcome! |
In govuk-react-jsx I render the nunjucks templates using the yaml example data in each component, and then do the same for the react components. I then use https://github.com/Prettyhtml/prettyhtml to smooth over minor rendering differences and https://github.com/markedjs/html-differ to diff the results. It's not the prettiest code but you can see it here: which is then called from each component's tests: I then get test output like this (in this case, I have removed the role="banner" from the header to demonstrate) This works well for the most part. The only issue I have encountered is cases where the example yaml data doesn't fully exercise the component. There's also a few superficial differences in the output but I managed to configure the html differ to ignore these. Having a set of pre-rendered fixtures would certainly simplify my test suite and I could concentrate on just the diffing. Or indeed a test suite where I pass in my html and everything is handled for me. I might have a go at abstracting out the work I did on govuk-react-jsx and see if it can help @matthew-shaw out above - as a proof of concept almost. |
@matthew-shaw have you seen https://github.com/alphagov/govuk-frontend-jinja? (maintained by a separate team at GDS, not the Design System team) @andymantell I'm not sure you tagged the right person there! We think the first step will be to create a proposal that we can share with the community – once we've done that we'll make sure you get the chance to feed back. These comments will be really helpful in shaping that proposal, so thank you both! |
@36degrees The govuk-frontend-jinja repo at https://github.com/alphagov/govuk-frontend-jinja repository uses a port of a script I wrote back at HM Land Registry to automatically port the Nunjucks across to Jinja using some regular expressions and other tomfoolery. I believe they've taken it a bit further than I had originally and fixed some issues I hadn't managed to. But it's similar conceptually. Before I left HMLR though I was growing increasingly frustrated with the automated porting script and had basically concluded that it wasn't a great way to do things - there are so many subtle differences between Nunjucks and Jinja that the script became harder to maintain than just manually porting between the two! @matthew-shaw and I have chatted about this at length and he is working on the successor to this which is a set of manual ports supported by a test suite exactly as you described in this ticket. (i.e. the same model I use for govuk-react-jsx) I think if I have a crack at packaging up my test suite it might be an interesting exercise to see how easily it can be applied to @matthew-shaw's work Not proposing you use my code particularly, but it might shed some light on any potential issues with such a solution. |
@andymantell interesting, we actually found that Nunjucks and Jinja templates are similar enough that we haven't really had to worry about maintaining https://github.com/alphagov/govuk-frontend-jinja (which of course we couldn't have done without you, so thanks again!). That said, that could be mainly because we haven't been closely following the master branch of govuk-frontend, but we've also been helped by a comprehensive test suite. Much as you and @matthew-shaw described, it's based on the YAML examples; except we copied and pasted them into our codebase :/ |
Also, I think that @penx who created the issue #1095 already had a way of extracting and packaging the govuk-frontend exampes https://github.com/penx/govuk-frontend-template-spec |
Oh nice. @lfdebrux Regarding the Jinja porting script - I found myself adding more and more edge cases to the conversion as each govuk-frontend release came out and it just didn't feel like an clean and enjoyable way to achieve it. I manually replicate the govuk-frontend changes into govuk-react-jsx and it's really easy just to step through the changelog when releases happen and implement them again in JSX (backed up by the tests). Doing it this way has felt much tidier (to me at least). I reckon @matthew-shaw should pursue this solution (and I'll pitch in and help where I can) and maybe we could all have a chat at some point at compare where we've ended up. It would be good to get one published to PyPi. I've probably derailed this thread massively. Sorry! :-) |
We (Department of Finance Northern Ireland) have a c# port in development of the nunjucks macros. A way to test that the output is largely the same as the nunjucks macros would be very useful. Definitely going to look into govuk-frontend-template-spec. |
@DanScottNI is your C# port open source? |
I've been working on extracting the tests from govuk-react-jsx into their own cli tool this week. It's here at https://github.com/surevine/govuk-frontend-diff if anyone wants to give it a whirl. It expects you to implement a tiny http server responding to There's a pull request open at LandRegistry/govuk-frontend-jinja#6 for a demo of how to integrate with it. Happy to help out with others if repositories are open source. |
As @andymantell says, the govuk-frontend-jinja package is now published on PyPi. I've also deployed a little demo Flask app to Heroku with a full component specimen of every example from the GOV.UK Design System. This is now also being used internally within HM Land Registry reference/template implementations we call "skeleton apps" and I'm working on getting our service teams to adopt it. This has already been a very worthwhile exercise. Using Andy's test suite, we now have 190 tests for every single component in every single permutation from the design system. In doing that, we've found some bugs with our original port that have now been fixed, so we already have a provably higher quality output than before. This means we can be certain of 100% markup parity and compliance with the latest, and every subsequent, GOV.UK Frontend release. This has also enabled me to remove a bunch of complexity from our skeleton frontend application, and simplify that into an open source component that the cross government community can make use of too. The published package is currently at release |
Hi all, I made govuk-frontend-template-spec, just to let you know I've subbed to this thread and happy to help where I can. I'm not working on govuk projects at the moment, but If anyone wants to collaborate on it to make it a decent stop gap solution until there's an official solution then please ping me. |
Not yet. Still very early stages of development, and we're still in the early stages of open sourcing things. |
I have an ASP.NET Core Tag Helper port of most of these components at https://github.com/gunndabad/govuk-frontend-aspnetcore that may be of interest. Still early days so (very) light on docs. |
We're going to start including fixture files in the published GOV.UK Frontend package. If you maintain your own macros, templates or partials you can use the fixtures to check that your components output the same HTML that GOV.UK Frontend uses, for example:
We'd like your feedback on this proposed change. You can:
Please provide feedback by 5pm on Tuesday 4 August. ProblemWhilst you can easily re-use the stylesheets and JavaScript from GOV.UK Frontend, it's likely that you have to maintain the HTML markup used for each component yourself. At the minute there's no automated way for you to tell whether your HTML is the same as the HTML that GOV.UK Frontend uses. You may already be using the examples in the component YAML files as test fixtures, but:
ProposalWe'll make the examples provided for each component more comprehensive, so that every component option is represented by at least one example. We'll then publish the examples in a
For example, in the published package you'd find [
{
"name": "default",
"options": {
"text": "Save and continue"
},
"html": "<button class=\"govuk-button\" data-module=\"govuk-button\">\n Save and continue\n</button>"
},
// […]
] You can use these fixture files in your own tests to check that your HTML is the same as the HTML that GOV.UK Frontend uses. For example, in pseudo-code:
You may need to normalise the expected and actual HTML to allow for differences in whitespace or indentation. You can try a pre-release of GOV.UK Frontend that includes a fixtures.json file for the button component only by running:
|
@vanitabarrett Are the current YAML files going to remain, or do the new fixtures.json files replace them? Reason I ask is that I use the examples in the YAML files to build the storybook demos on govuk-react-jsx. If they're disappearing I'll do something else instead... (I.e. I'm not saying you have to keep them, just thinking ahead). As for the fixtures themselves, it sounds perfect. |
@36degrees @vanitabarrett having a read through, that sounds spot on. I'll try do a React PoC at some point. Some things to think about:
e.g. {
"button": "./govuk/components/button/fixtures.json",
"etc.": "...etc"
} |
Thank you for the comments @penx @andymantell Some parts of the proposal were perhaps not as clear as they could be:
@penx Our aim is to make these fixtures as generic as possible. In the same way that maintainers may need to normalise the HTML to allow for differences, we expect any differences in framework behaviour to be handled by maintainers. If there’s anything we can do to make the process smoother, let us know! The examples in GOVUK Frontend should only pass html where we specifically want to check the HTML works correctly. If you want to skip these, you could skip any tests that pass |
👌 if this is consistently followed then this works for me, thanks! |
This is an initial attempt at using GOV.UK Frontend's recent fixtures[0] addition to ensure the HTML we're generating is in accordance with the Design System. After flipping a few default values it's not a million miles off, but there are some snags: 1) Rails insists on adding a `data-disable-with` attribute to the submit[1], even when we attempt to disable it by passing `false` 2) Because in all cases (other than `#govuk_date_field`) we are merely wrapping the built-in Rails form helpers, we're not in control of the order of attributes. Comparing them directly will fail. Both of these problems are demonstrated in the RSpec output: expected: `<input value="Start now" type="submit" name="start-now" class="govuk-button" data-module="govuk-button">` got: `<input type="submit" name="start-now" value="Start now" class="govuk-button" data-module="govuk-button" data-disable-with="Start now" />` [0] alphagov/govuk-frontend#1830 [1] https://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-submit_tag
I like this idea, and will experiment with the button example in our port. A few questions:
Minor suggestion:
|
Thanks for your comment @frankieroberto ! We will generate fixtures for all components in GOVUK Frontend, so the fieldset and label will have fixtures. The fixtures are generated from the YAML files, so anything with a YAML file will get a corresponding fixtures file. Any components that support If you want to avoid npm, the fixtures will be on Github in a standard place for each component at: Can you give a little more detail or an example of the backward-compatibility you mentioned? |
@vanitabarrett thanks for your response.
Great. Would these be under the existing
That makes sense, but the You could either add an
Sounds good.
If the JSON file looked like this: {
"examples": [
{
"name": "default",
"options": {
"text": "Save and continue"
},
"html": "<button class=\"govuk-button\" data-module=\"govuk-button\">\n Save and continue\n</button>"
}
]
} rather than this: [
{
"name": "default",
"options": {
"text": "Save and continue"
},
"html": "<button class=\"govuk-button\" data-module=\"govuk-button\">\n Save and continue\n</button>"
}
] then that allows you to add additional top-level keys to the JSON file, without breaking any existing code which is simply iterating through the examples array: {
"name": "Button",
"url": "https://design-system.service.gov.uk/components/button/",
"version": "3.8.0",
"deprecated": false,
"examples": [
{
"name": "default",
"options": {
"text": "Save and continue"
},
"html": "<button class=\"govuk-button\" data-module=\"govuk-button\">\n Save and continue\n</button>"
}
]
} (It's hard to predict whether this’ll be needed or not, but may as well allow it as a possibility. It’s also recommended by the GDS API guidance, I just discovered) |
Thanks for clarifying @frankieroberto, I think your suggestions sound sensible! 👍
Yes, the fixtures files will be generated from the examples in the YAML files. We’ll need to do a bit of work to ensure the current examples are comprehensive enough before generating the first set of fixtures. I think we’ll probably review the existing documentation for contributors to see if anything needs tweaking there too. |
This has been included in v3.9.0 of GOVUK Frontend 🎉 |
What
Provide a way for maintainers of ports to ensure that, for given scenarios, their port generates markup equivalent to that of GOV.UK Frontend.
Why
Whilst anyone can easily re-use the stylesheets and JavaScript from GOV.UK Frontend, most of our users have to maintain their own abstractions of the HTML markup used for a component.
It's important for that markup to be equivalent to the markup used in GOV.UK Frontend so that it renders the same and has the same accessibility. This is especially true when those abstractions are published as packages to be re-used by others.
Further detail
Possible implementations might include:
Questions:
The text was updated successfully, but these errors were encountered: