Browse Source

added eslint-plugin-vue-a11y for accessibility linting

Bachir Soussi Chiadmi 10 months ago
parent
commit
36817261e3
7 changed files with 237 additions and 3 deletions
  1. 3 1
      .eslintrc.js
  2. 10 0
      README.md
  3. 3 0
      assets/css/app.styl
  4. 213 0
      package-lock.json
  5. 1 0
      package.json
  6. 6 2
      src/components/Home/Posts.vue
  7. 1 0
      test/specs/Posts.spec.js

+ 3 - 1
.eslintrc.js

@@ -13,10 +13,12 @@ module.exports = {
   },
   extends: [
     'plugin:vue/recommended',
+    'plugin:vue-a11y/base',
     'standard'
   ],
   plugins: [
-    'vue'
+    'vue',
+    'vue-a11y'
   ],
   rules: {
     'generator-star-spacing': 'off',

+ 10 - 0
README.md

@@ -17,6 +17,16 @@ npm run prod
 ```
 then deploy the dist folder
 
+## Questions
+
+#### axios get xml ?
+https://github.com/axios/axios/issues/667
+
+#### accessibility ?
+https://medium.com/@emilymears/getting-started-with-web-accessibility-in-vue-17e2c4ea0842
+https://github.com/vuejs/vuejs.org/pull/1002
+[x] https://github.com/maranran/eslint-plugin-vue-a11y
+
 ## Ref
 
 Based on VueJs template using Webpack 4 from the 'Vue.js and Webpack 4 From Scratch' article series on [itnext.io](https://itnext.io) from Daniel Cook.

+ 3 - 0
assets/css/app.styl

@@ -5,3 +5,6 @@
   display flex
   justify-content center
   align-items center
+
+*:focus
+  outline: 1px dotted red;

+ 213 - 0
package-lock.json

@@ -1736,6 +1736,16 @@
         "sprintf-js": "~1.0.2"
       }
     },
+    "aria-query": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-0.7.1.tgz",
+      "integrity": "sha1-Jsu1r/ZBRLCoJb4YRuCxbPoAsR4=",
+      "dev": true,
+      "requires": {
+        "ast-types-flow": "0.0.7",
+        "commander": "^2.11.0"
+      }
+    },
     "arr-diff": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -1766,6 +1776,16 @@
       "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
       "dev": true
     },
+    "array-includes": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
+      "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.2",
+        "es-abstract": "^1.7.0"
+      }
+    },
     "array-union": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
@@ -1845,12 +1865,24 @@
       "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
       "dev": true
     },
+    "assertion-error": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+      "dev": true
+    },
     "assign-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
       "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
       "dev": true
     },
+    "ast-types-flow": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
+      "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
+      "dev": true
+    },
     "astral-regex": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
@@ -1911,6 +1943,15 @@
         "is-buffer": "^1.1.5"
       }
     },
+    "axobject-query": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
+      "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==",
+      "dev": true,
+      "requires": {
+        "ast-types-flow": "0.0.7"
+      }
+    },
     "babel-code-frame": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -2680,6 +2721,20 @@
       "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
       "dev": true
     },
+    "chai": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
+      "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
+      "dev": true,
+      "requires": {
+        "assertion-error": "^1.1.0",
+        "check-error": "^1.0.2",
+        "deep-eql": "^3.0.1",
+        "get-func-name": "^2.0.0",
+        "pathval": "^1.1.0",
+        "type-detect": "^4.0.5"
+      }
+    },
     "chalk": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -2697,6 +2752,12 @@
       "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
       "dev": true
     },
+    "check-error": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+      "dev": true
+    },
     "chokidar": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz",
@@ -3334,6 +3395,12 @@
       "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
       "dev": true
     },
+    "damerau-levenshtein": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz",
+      "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=",
+      "dev": true
+    },
     "dashdash": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@@ -3400,6 +3467,15 @@
       "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
       "dev": true
     },
+    "deep-eql": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+      "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+      "dev": true,
+      "requires": {
+        "type-detect": "^4.0.0"
+      }
+    },
     "deep-equal": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
@@ -4184,6 +4260,34 @@
         }
       }
     },
+    "eslint-plugin-jsx-a11y": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz",
+      "integrity": "sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w==",
+      "dev": true,
+      "requires": {
+        "aria-query": "^3.0.0",
+        "array-includes": "^3.0.3",
+        "ast-types-flow": "^0.0.7",
+        "axobject-query": "^2.0.2",
+        "damerau-levenshtein": "^1.0.4",
+        "emoji-regex": "^7.0.2",
+        "has": "^1.0.3",
+        "jsx-ast-utils": "^2.0.1"
+      },
+      "dependencies": {
+        "aria-query": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz",
+          "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=",
+          "dev": true,
+          "requires": {
+            "ast-types-flow": "0.0.7",
+            "commander": "^2.11.0"
+          }
+        }
+      }
+    },
     "eslint-plugin-node": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz",
@@ -4227,6 +4331,88 @@
         "vue-eslint-parser": "^5.0.0"
       }
     },
+    "eslint-plugin-vue-a11y": {
+      "version": "0.0.28",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-vue-a11y/-/eslint-plugin-vue-a11y-0.0.28.tgz",
+      "integrity": "sha512-nbmxntyLIZgRGzqXwYIqQp6ITJUACFsuQOeXBt9tKUjYblKxgqMT7Y0P4nTxubd2Kba1G+XYLDwMio2vfGy5DQ==",
+      "dev": true,
+      "requires": {
+        "aria-query": "^0.7.1",
+        "chai": "^4.1.0",
+        "emoji-regex": "^7.0.0",
+        "eslint-plugin-jsx-a11y": "^6.0.2",
+        "eslint-plugin-vue": "^4.4.0",
+        "jsx-ast-utils": "^2.0.1",
+        "vue-eslint-parser": "^2.0.3"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "5.7.3",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+          "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+          "dev": true
+        },
+        "acorn-jsx": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+          "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+          "dev": true,
+          "requires": {
+            "acorn": "^3.0.4"
+          },
+          "dependencies": {
+            "acorn": {
+              "version": "3.3.0",
+              "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+              "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+              "dev": true
+            }
+          }
+        },
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "eslint-plugin-vue": {
+          "version": "4.7.1",
+          "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-4.7.1.tgz",
+          "integrity": "sha512-esETKhVMI7Vdli70Wt4bvAwnZBJeM0pxVX9Yb0wWKxdCJc2EADalVYK/q2FzMw8oKN0wPMdqVCKS8kmR89recA==",
+          "dev": true,
+          "requires": {
+            "vue-eslint-parser": "^2.0.3"
+          }
+        },
+        "espree": {
+          "version": "3.5.4",
+          "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+          "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+          "dev": true,
+          "requires": {
+            "acorn": "^5.5.0",
+            "acorn-jsx": "^3.0.0"
+          }
+        },
+        "vue-eslint-parser": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz",
+          "integrity": "sha512-ZezcU71Owm84xVF6gfurBQUGg8WQ+WZGxgDEQu1IHFBZNx7BFZg3L1yHxrCBNNwbwFtE1GuvfJKMtb6Xuwc/Bw==",
+          "dev": true,
+          "requires": {
+            "debug": "^3.1.0",
+            "eslint-scope": "^3.7.1",
+            "eslint-visitor-keys": "^1.0.0",
+            "espree": "^3.5.2",
+            "esquery": "^1.0.0",
+            "lodash": "^4.17.4"
+          }
+        }
+      }
+    },
     "eslint-scope": {
       "version": "3.7.1",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
@@ -5487,6 +5673,12 @@
       "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
       "dev": true
     },
+    "get-func-name": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+      "dev": true
+    },
     "get-stream": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -7111,6 +7303,15 @@
         "verror": "1.10.0"
       }
     },
+    "jsx-ast-utils": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz",
+      "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=",
+      "dev": true,
+      "requires": {
+        "array-includes": "^3.0.3"
+      }
+    },
     "killable": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -8324,6 +8525,12 @@
         "pify": "^3.0.0"
       }
     },
+    "pathval": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+      "dev": true
+    },
     "pbkdf2": {
       "version": "3.0.17",
       "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
@@ -10402,6 +10609,12 @@
         "prelude-ls": "~1.1.2"
       }
     },
+    "type-detect": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+      "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+      "dev": true
+    },
     "type-is": {
       "version": "1.6.16",
       "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",

+ 1 - 0
package.json

@@ -41,6 +41,7 @@
     "eslint-plugin-promise": "^4.0.1",
     "eslint-plugin-standard": "^4.0.0",
     "eslint-plugin-vue": "^5.2.2",
+    "eslint-plugin-vue-a11y": "0.0.28",
     "html-webpack-plugin": "^3.2.0",
     "jest": "^24.5.0",
     "jest-serializer-vue": "^2.0.2",

+ 6 - 2
src/components/Home/Posts.vue

@@ -2,10 +2,12 @@
   <section v-if="opened != null">
     <h2>{{ opened.title }}</h2>
     <p>{{ opened.body }}</p>
-    <span
+    <a
+      href="#"
       @click="closePost()"
+      @keydown.enter="openPost(post)"
       >
-      close</span>
+      close</a>
   </section>
   <ul v-else>
     <li
@@ -14,7 +16,9 @@
       >
       <h2>
         <a
+          :href="'#post-'+post.id"
           @click="openPost(post)"
+          @keydown.enter="openPost(post)"
           >
           {{ post.title }}</a></h2>
     </li>

+ 1 - 0
test/specs/Posts.spec.js

@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils'
 import Posts from '@/components/Home/Posts'
 
 // https://alligator.io/vuejs/testing-vue-with-jest/
+// https://www.synbioz.com/blog/testez_unitairement_application_vuejs_jest
 
 function mountComponentWithProps (Component, propsData) {
   const Constructor = Vue.extend(Component);