govuk_publishing_components 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 231f4e05eaee81049ea4f72bf5ec1ced16026e3f
4
- data.tar.gz: f1564c8de553159a32af562e96dcca4931f2a554
3
+ metadata.gz: 8e46bcab548aa86ded198500c1ef47b6967a4405
4
+ data.tar.gz: b29345bd70ee782b127bbe8e5c5640a28dfe3649
5
5
  SHA512:
6
- metadata.gz: a32780c774231f52e107781140fa301643437b5ff976b63f7fc3f3e2b3a41ecbb786aa742c738039dac6bff514b770f1d7a70cd468e16b56be704ebd1ab04d81
7
- data.tar.gz: '0724197ba6f3f37e563bd7b24826d1fb9c8b1942b39332d3fe21d9b6c12d3a1751ebd2dcccba59c45bd248d3ae6777327299283554a6b25d47b725f9517ebbe9'
6
+ metadata.gz: 2f18566d1fc8338914133467e623d20b8a31adcec1cde09f20be989987952a6cd8fb925856930cbff7bc227088c2e2913e65330170ab956cc29cdce8096d623e
7
+ data.tar.gz: 8a32cd97cfcf7d34bdfb9d0fc056e686b6300b6bb18e3bfe6838719bdfdc80ce6e3e8e33276675a5a98886dd92bebe3192b67adb63259c7a4eb7630d72a11494
data/README.md CHANGED
@@ -27,23 +27,6 @@ https://government-frontend.herokuapp.com/component-guide
27
27
 
28
28
  The guide includes your application’s `application.scss` and `application.js` files by default. This is [configurable](#configuration).
29
29
 
30
- ## Test the component guide
31
-
32
- The gem [includes integration tests](lib/govuk_publishing_components/minitest/component_guide_test.rb) to check that your component guide and examples are error free and that they meet basic accessibility needs.
33
-
34
- Automated accessibility tests use [aXe](https://github.com/dequelabs/axe-core). Using our `AccessibilityTest` wrapper the gem runs the aXe suite against each example and throws JavaScript errors for any violations. These JavaScript errors can be used to fail a build in CI.
35
-
36
- ### Minitest
37
-
38
- ```ruby
39
- # component_guide_test.rb
40
- require 'govuk_publishing_components/minitest/component_guide_test'
41
-
42
- class ComponentGuideTest < ActionDispatch::IntegrationTest
43
- include GovukPublishingComponents::Minitest::ComponentGuideTest
44
- end
45
- ```
46
-
47
30
  ### Install gem
48
31
 
49
32
  Add this line to your application's Gemfile in the [development and test groups](http://bundler.io/v1.12/groups.html#grouping-your-dependencies):
@@ -57,6 +40,30 @@ And then execute:
57
40
  $ bundle
58
41
  ```
59
42
 
43
+ #### Integration with Heroku
44
+
45
+ To make the best use of the component guide we use Heroku to serve the current `master` build and whenever a [pull request is added](https://devcenter.heroku.com/articles/github-integration-review-apps)
46
+
47
+ When an app is deployed to Heroku it will be in `production` mode, so only gems that are in the main group will be installed and made available.
48
+ To ensure that we only load the guide on Heroku and not when deployed to _production_ we need to have the gem included in the main bundle group in the Gemfile.
49
+ For this use case we need `require: false` so that it's not loaded in _production_ but then we can manually `require` the gem in our `application.rb` based on the more complex environmental logic that we've specified.
50
+
51
+ First move the gem outside of the `development`, `test` groups and set require to false. ([example](https://github.com/alphagov/government-frontend/blob/5110d3d33f7a6b63f218b889a5afec90e6df810f/Gemfile#L11)):
52
+
53
+ ```ruby
54
+ # Gemfile
55
+ gem 'govuk_publishing_components', require: false
56
+ ```
57
+
58
+ Now we can manually require the gem ([example](https://github.com/alphagov/government-frontend/blob/5110d3d33f7a6b63f218b889a5afec90e6df810f/config/application.rb#L14)):
59
+
60
+ ```ruby
61
+ # config/application.rb
62
+ if !Rails.env.production? || ENV['HEROKU_APP_NAME'].present?
63
+ require 'govuk_publishing_components'
64
+ end
65
+ ```
66
+
60
67
  ### Mount the component guide
61
68
 
62
69
  Mount the component guide in your application:
@@ -88,39 +95,33 @@ if defined?(GovukPublishingComponents)
88
95
  end
89
96
  ```
90
97
 
91
- ## Component generator
92
-
93
- The gem includes a component generator to stub the minimal files required for a component.
94
-
95
- ```ruby
96
- rails generate govuk_publishing_components:component [component_name]
97
- ```
98
-
99
- This will create a template, scss file and yml documentation file for a new component. It will not create a test file as this cannot be reliably done automatically across applications, but a test file will be necessary.
98
+ ### Test the component guide
100
99
 
101
- ## Integration with Heroku
102
- To make the best use of the component guide we use Heroku to serve the current `master` build and whenever a [pull request is added](https://devcenter.heroku.com/articles/github-integration-review-apps)
100
+ The gem [includes integration tests](lib/govuk_publishing_components/minitest/component_guide_test.rb) to check that your component guide and examples are error free and that they meet basic accessibility needs.
103
101
 
104
- When an app is deployed to Heroku it will be in `production` mode, so only gems that are in the main group will be installed and made available.
105
- To ensure that we only load the guide on Heroku and not when deployed to _production_ we need to have the gem included in the main bundle group in the Gemfile.
106
- For this use case we need `require: false` so that it's not loaded in _production_ but then we can manually `require` the gem in our `application.rb` based on the more complex environmental logic that we've specified.
102
+ Automated accessibility tests use [aXe](https://github.com/dequelabs/axe-core). Using our `AccessibilityTest` wrapper the gem runs the aXe suite against each example and throws JavaScript errors for any violations. These JavaScript errors can be used to fail a build in CI.
107
103
 
108
- First move the gem outside of the `development`, `test` groups and set require to false. ([example](https://github.com/alphagov/government-frontend/blob/5110d3d33f7a6b63f218b889a5afec90e6df810f/Gemfile#L11)):
104
+ #### Minitest
109
105
 
110
106
  ```ruby
111
- # Gemfile
112
- gem 'govuk_publishing_components', require: false
107
+ # component_guide_test.rb
108
+ require 'govuk_publishing_components/minitest/component_guide_test'
109
+
110
+ class ComponentGuideTest < ActionDispatch::IntegrationTest
111
+ include GovukPublishingComponents::Minitest::ComponentGuideTest
112
+ end
113
113
  ```
114
114
 
115
- Now we can manually require the gem ([example](https://github.com/alphagov/government-frontend/blob/5110d3d33f7a6b63f218b889a5afec90e6df810f/config/application.rb#L14)):
115
+ ## Component generator
116
+
117
+ The gem includes a component generator to stub the minimal files required for a component.
116
118
 
117
119
  ```ruby
118
- # config/application.rb
119
- if !Rails.env.production? || ENV['HEROKU_APP_NAME'].present?
120
- require 'govuk_publishing_components'
121
- end
120
+ rails generate govuk_publishing_components:component [component_name]
122
121
  ```
123
122
 
123
+ This will create a template, scss file and yml documentation file for a new component. It will not create a test file as this cannot be reliably done automatically across applications, but a test file will be necessary.
124
+
124
125
  ## Automated Testing
125
126
  ### Visual Diff Tool
126
127
  The component guide includes a visual diff tool that should make it easier to spot when you are introducing visual regressions in your components.
@@ -35,18 +35,16 @@
35
35
  return callback('aXe Error: Expected results but none returned')
36
36
  }
37
37
 
38
- var errorText = _processViolations(results.violations, results.url)
39
- var incompleteWarningsObj = _processIncompleteWarnings(results.incomplete)
40
-
38
+ var consoleErrorText = _consoleErrorText(results.violations, results.url)
41
39
  var bodyClass = results.violations.length === 0 ? "js-test-a11y-success" : "js-test-a11y-failed"
42
40
  document.body.classList.add(bodyClass);
43
41
  document.body.classList.add("js-test-a11y-finished");
44
42
 
45
- callback(undefined, errorText, incompleteWarningsObj)
43
+ callback(undefined, consoleErrorText, _processAxeResultsForPage(results))
46
44
  })
47
45
  }
48
46
 
49
- var _processViolations = function(violations, url) {
47
+ var _consoleErrorText = function(violations, url) {
50
48
  if (violations.length !== 0) {
51
49
  return (
52
50
  '\n' + 'Accessibility issues at ' +
@@ -68,33 +66,31 @@
68
66
  }
69
67
  }
70
68
 
71
- var _processIncompleteWarnings = function(incompleteWarnings) {
72
- if (incompleteWarnings.length !== 0) {
73
- return (
74
- incompleteWarnings.map(function (incomplete) {
75
- var help = incomplete.help
76
- var helpUrl = _formatHelpUrl(incomplete.helpUrl)
77
- var cssSelector = incomplete.nodes.map(function (node) {
78
- return {
79
- 'selector': node.target,
80
- 'reason': node.any.map(function(item) {
81
- return item.message
82
- })
83
- }
84
- })
85
-
86
- return {
87
- 'summary': help,
88
- 'selectors': cssSelector,
89
- 'url': helpUrl
90
- }
91
- })
92
- )
93
- } else {
94
- return false
69
+ var _processAxeResultsForPage = function(results) {
70
+ return {
71
+ violations: _mapSummaryAndCause(results.violations),
72
+ incompleteWarnings: _mapSummaryAndCause(results.incomplete)
95
73
  }
96
74
  }
97
75
 
76
+ var _mapSummaryAndCause = function(resultsArray) {
77
+ return resultsArray.map(function (result) {
78
+ var cssSelector = result.nodes.map(function (node) {
79
+ return {
80
+ 'selector': node.target,
81
+ 'reasons': node.any.map(function(item) {
82
+ return item.message
83
+ })
84
+ }
85
+ })
86
+ return {
87
+ 'summary': result.help,
88
+ 'selectors': cssSelector,
89
+ 'url': _formatHelpUrl(result.helpUrl)
90
+ }
91
+ })
92
+ }
93
+
98
94
  var _formatHelpUrl = function (helpUrl) {
99
95
  if (axe.version.indexOf('alpha') === -1) {
100
96
  console.warn('Deprecation warning: helpUrl formatting is no longer needed so can be deleted')
@@ -121,22 +117,21 @@
121
117
  }
122
118
  }
123
119
 
124
- var _renderIncompleteWarnings = function (incompleteWarnings) {
125
- incompleteWarnings.forEach(function (warning) {
126
- warning.selectors.forEach(function (selectorObj) {
120
+ var _renderAxeResultsInGuide = function (resultsGroup, resultContainerSelector) {
121
+ resultsGroup.forEach(function (result) {
122
+ result.selectors.forEach(function (selectorObj) {
127
123
  var activeEl = document.querySelector(selectorObj.selector)
128
124
  var activeElParent = _findParent(activeEl, '[data-module="test-a11y"]')
129
- var warningWrapper = activeElParent.querySelector('[data-module="test-a11y-warning"]')
125
+ var wrapper = activeElParent.querySelector(resultContainerSelector)
130
126
 
131
- if (warningWrapper) {
132
- // Add warning to warnings box
133
- var warningsHTML = '<h3>' + warning.summary + ' <a href="' + warning.url + '">(see guidance)</a></h3>' +
134
- '<p>Reason: ' + selectorObj.reason + '</p>' +
135
- '<p>Element can be found using the following CSS selector: <span class="selector">' +
127
+ if (wrapper) {
128
+ var resultHTML = '<h3>' + result.summary + ' <a href="' + result.url + '">(see guidance)</a></h3>' +
129
+ '<p>' + selectorObj.reasons.join('<br />') + '</p>' +
130
+ '<p>Element can be found using the selector:<br /><span class="selector">' +
136
131
  selectorObj.selector +
137
132
  '</span></p>'
138
133
 
139
- warningWrapper.insertAdjacentHTML('beforeend', warningsHTML)
134
+ wrapper.insertAdjacentHTML('beforeend', resultHTML)
140
135
  }
141
136
  })
142
137
  })
@@ -156,12 +151,19 @@
156
151
  // http://responsivenews.co.uk/post/18948466399/cutting-the-mustard
157
152
  if (document.addEventListener) {
158
153
  document.addEventListener('DOMContentLoaded', function () {
159
- AccessibilityTest('[data-module="test-a11y"]', function (err, violations, incompleteWarnings) {
160
- if (err) {
161
- _throwUncaughtError(err)
154
+ AccessibilityTest('[data-module="test-a11y"]', function (axeError, consoleErrorText, pageResults) {
155
+ if (axeError) {
156
+ _throwUncaughtError(axeError)
157
+ }
158
+
159
+ if (pageResults) {
160
+ _renderAxeResultsInGuide(pageResults.incompleteWarnings, '[data-module="test-a11y-warning"]')
161
+ _renderAxeResultsInGuide(pageResults.violations, '[data-module="test-a11y-violation"]')
162
+ }
163
+
164
+ if (consoleErrorText) {
165
+ _throwUncaughtError(consoleErrorText)
162
166
  }
163
- if (incompleteWarnings) _renderIncompleteWarnings(incompleteWarnings)
164
- if (violations) _throwUncaughtError(violations)
165
167
  })
166
168
  })
167
169
  }
@@ -127,13 +127,6 @@ $border-color: #ccc;
127
127
  color: $black;
128
128
  font-weight: bold;
129
129
  }
130
-
131
- div[class^="govuk-"] {
132
- &:hover {
133
- outline: 1px solid $border-color;
134
- box-shadow: 0 0 10px $border-color;
135
- }
136
- }
137
130
  }
138
131
 
139
132
  .component-guide-preview--simple {
@@ -145,20 +138,22 @@ $border-color: #ccc;
145
138
  }
146
139
  }
147
140
 
141
+ .component-guide-preview--violation,
148
142
  .component-guide-preview--warning {
149
143
  margin-top: $gutter-half;
150
- border-color: $yellow;
144
+ @include core-19;
151
145
 
152
146
  &:empty {
153
147
  display: none;
154
148
  }
155
149
 
156
- &:before {
157
- background-color: $yellow;
150
+ h3 {
151
+ @include bold-19;
158
152
  }
159
153
 
154
+ p,
160
155
  h3 {
161
- @include bold-16;
156
+ margin-bottom: $gutter / 2;
162
157
  }
163
158
 
164
159
  h3:not(:first-child) {
@@ -170,6 +165,23 @@ $border-color: #ccc;
170
165
  }
171
166
  }
172
167
 
168
+ .component-guide-preview--warning {
169
+ border-color: $yellow;
170
+
171
+ &:before {
172
+ background-color: $yellow;
173
+ }
174
+ }
175
+
176
+ .component-guide-preview--violation {
177
+ border-color: $red;
178
+
179
+ &:before {
180
+ background-color: $red;
181
+ color: $white;
182
+ }
183
+ }
184
+
173
185
  .examples {
174
186
  .component-example {
175
187
  margin: 0 0 $gutter * 1.5;
@@ -1,3 +1,3 @@
1
1
  <div class="component-call component-highlight" contenteditable>
2
- <pre><code><%= example.highlight_code("\<%= render \"#{@component_doc.partial_path}\" #{example.pretty_data} %\>") %></code></pre>
2
+ <pre><code><%= example.highlight_code("\<%= render \"#{@component_doc.partial_path}\", #{example.pretty_data} %\>") %></code></pre>
3
3
  </div>
@@ -1,4 +1,5 @@
1
1
  <div data-module="test-a11y">
2
2
  <%= render "govuk_publishing_components/component_guide/component_doc/component", component_doc: @component_doc, example: example, preview_page: false %>
3
- <div class="component-guide-preview component-guide-preview--warning" data-module="test-a11y-warning" data-content="Potential Accessibility Issues: Need Manual Check"></div>
3
+ <div class="component-guide-preview component-guide-preview--violation" data-module="test-a11y-violation" data-content="Accessibility Issues"></div>
4
+ <div class="component-guide-preview component-guide-preview--warning" data-module="test-a11y-warning" data-content="Potential accessibility issues: need manual check"></div>
4
5
  </div>
@@ -1,3 +1,3 @@
1
1
  module GovukPublishingComponents
2
- VERSION = '1.10.0'.freeze
2
+ VERSION = '1.11.0'.freeze
3
3
  end
@@ -1,4 +1,22 @@
1
- # desc "Explaining what the task does"
2
- # task :govuk_publishing_components do
3
- # # Task goes here
4
- # end
1
+ desc 'warns if component view files exist without corresponding documentation'
2
+ task :validate_component_documentation do
3
+ components_missing_docs = []
4
+ component_views = Dir["app/views/#{GovukPublishingComponents::Config.component_directory_name}/**/*.html.erb"]
5
+
6
+ component_views.each do |partial|
7
+ expected_component_docs_file = partial.split('/')[-1].gsub('html.erb', 'yml')
8
+ expected_component_docs_file.sub!(/^_/, '')
9
+
10
+ expected_component_docs_path = "app/views/#{GovukPublishingComponents::Config.component_directory_name}/docs/#{expected_component_docs_file}"
11
+ components_missing_docs << partial unless File.exist?(expected_component_docs_path)
12
+ end
13
+
14
+ if components_missing_docs.any?
15
+ error = "You have components which are missing documentation. These components will not be displayed in the component guide:\n"
16
+ components_missing_docs.each { |component| error += "\t" + component + "\n" }
17
+ error += "\n"
18
+ raise NotImplementedError, error
19
+ end
20
+ end
21
+
22
+ Rake::Task["validate_component_documentation"].invoke
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_publishing_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-21 00:00:00.000000000 Z
11
+ date: 2017-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -243,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
243
  version: '0'
244
244
  requirements: []
245
245
  rubyforge_project:
246
- rubygems_version: 2.6.8
246
+ rubygems_version: 2.6.13
247
247
  signing_key:
248
248
  specification_version: 4
249
249
  summary: A gem to document components in GOV.UK frontend applications