Repository: GoogleChrome/lighthouse
Pull request #8803 (2019-05-02 13:57:18)

tests: add tap targets to dobetterweb sample page
**Summary**

Include tap targets in the sample artifacts, so they are part of the tests and the now.sh preview.

brendankenny: might need to rebase this one? Pull `sample_v2_round_trip.json` and rerun the update:sample-json? That change was brutal for conflicts for some reason

Patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bcc51735a..7b4d425a0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -81,7 +81,7 @@ yarn run update:sample-artifacts ScriptElements # update just one artifact
 yarn run update:sample-json # update sample LHR based on sample artifacts
 ```
 
-When updating all artifacts, usually you'll need to revert changes to the `*.devtoolslog.json` and `*.trace.json` files and manually review changes to `artifacts.json` to make sure they are related to your work.
+When updating artifacts, usually you'll need to revert changes to the `*.devtoolslog.json` and `*.trace.json` files and manually review changes to `artifacts.json` to make sure they are related to your work.
 
 ## Tracking Errors
 
diff --git a/lighthouse-core/scripts/update-report-fixtures.js b/lighthouse-core/scripts/update-report-fixtures.js
index 300941ab6..e59f726d2 100644
--- a/lighthouse-core/scripts/update-report-fixtures.js
+++ b/lighthouse-core/scripts/update-report-fixtures.js
@@ -8,7 +8,6 @@
 const cli = require('../../lighthouse-cli/run.js');
 const cliFlags = require('../../lighthouse-cli/cli-flags.js');
 const assetSaver = require('../lib/asset-saver.js');
-
 const artifactPath = 'lighthouse-core/test/results/artifacts';
 
 const {server} = require('../../lighthouse-cli/test/fixtures/static-server.js');
@@ -63,7 +62,7 @@ async function update(artifactName) {
     // Revert everything except the one artifact
     const newArtifacts = await assetSaver.loadArtifacts(artifactPath);
     if (!(artifactName in newArtifacts) && !(artifactName in oldArtifacts)) {
-      console.warn(`❌ Unknown artifact name: '${artifactName}'. Reverting artifacts...`); // eslint-disable-line no-console
+      throw Error('Unknown artifact name: ' + artifactName);
     }
     const finalArtifacts = oldArtifacts;
     finalArtifacts[artifactName] = newArtifacts[artifactName];
diff --git a/package.json b/package.json
index 2014e4714..5b92e60b3 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,7 @@
     "ultradumbBenchmark": "./lighthouse-core/scripts/benchmark.js",
     "mixed-content": "./lighthouse-cli/index.js --chrome-flags='--headless' --preset=mixed-content",
     "minify-latest-run": "./lighthouse-core/scripts/lantern/minify-trace.js ./latest-run/defaultPass.trace.json ./latest-run/defaultPass.trace.min.json && ./lighthouse-core/scripts/lantern/minify-devtoolslog.js ./latest-run/defaultPass.devtoolslog.json ./latest-run/defaultPass.devtoolslog.min.json",
-    "compile-proto": "[ \"$(protoc --version)\" == 'libprotoc 3.6.1' ] && protoc --python_out=./ ./proto/lighthouse-result.proto && mv ./proto/*_pb2.py ./proto/scripts || (echo \"❌ Install protobuf to compile the proto file.\" && false)",
+    "compile-proto": "protoc --python_out=./ ./proto/lighthouse-result.proto && mv ./proto/*_pb2.py ./proto/scripts || (echo \"❌ Install protobuf ≥ 3.7.1 to compile the proto file.\" && false)",
     "build-proto-roundtrip": "cd proto/scripts && PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2 python json_roundtrip_via_proto.py"
   },
   "devDependencies": {
diff --git a/proto/sample_v2_round_trip.json b/proto/sample_v2_round_trip.json
index d9f5ba95c..3885c9a55 100644
--- a/proto/sample_v2_round_trip.json
+++ b/proto/sample_v2_round_trip.json
@@ -2356,16 +2356,53 @@
         "tap-targets": {
             "description": "Interactive elements like buttons and links should be large enough (48x48px), and have enough space around them, to be easy enough to tap without overlapping onto other elements. [Learn more](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design).",
             "details": {
-                "headings": [],
-                "items": [],
+                "headings": [
+                    {
+                        "itemType": "node", 
+                        "key": "tapTarget", 
+                        "text": "Tap Target"
+                    }, 
+                    {
+                        "itemType": "text", 
+                        "key": "size", 
+                        "text": "Size"
+                    }, 
+                    {
+                        "itemType": "node", 
+                        "key": "overlappingTarget", 
+                        "text": "Overlapping Target"
+                    }
+                ], 
+                "items": [
+                    {
+                        "height": 18.0, 
+                        "overlapScoreRatio": 0.8333333333333334, 
+                        "overlappingTarget": {
+                            "path": "3,HTML,1,BODY,18,BUTTON", 
+                            "selector": "body > button.small-button", 
+                            "snippet": "<button class=\"small-button\">Do something else</button>", 
+                            "type": "node"
+                        }, 
+                        "overlappingTargetScore": 720.0, 
+                        "size": "200x18", 
+                        "tapTarget": {
+                            "path": "3,HTML,1,BODY,17,BUTTON", 
+                            "selector": "body > button.small-button", 
+                            "snippet": "<button class=\"small-button\">Do something</button>", 
+                            "type": "node"
+                        }, 
+                        "tapTargetScore": 864.0, 
+                        "width": 200.0
+                    }
+                ], 
                 "type": "table"
-            },
-            "displayValue": "100% appropriately sized tap targets",
-            "id": "tap-targets",
-            "score": 1.0,
-            "scoreDisplayMode": "binary",
-            "title": "Tap targets are sized appropriately"
-        },
+            }, 
+            "displayValue": "0% appropriately sized tap targets", 
+            "id": "tap-targets", 
+            "score": 0.0, 
+            "scoreDisplayMode": "binary", 
+            "title": "Tap targets are not sized appropriately"
+        }, 
         "td-headers-attr": {
             "description": "Screen readers have features to make navigating tables easier. Ensuring `<td>` cells using the `[headers]` attribute only refer to other cells in the same table may improve the experience for screen reader users. [Learn more](https://dequeuniversity.com/rules/axe/3.1/td-headers-attr?application=lighthouse).",
             "id": "td-headers-attr",
@@ -3641,11 +3678,11 @@
                     "id": "structured-data",
                     "weight": 0.0
                 }
-            ],
-            "description": "These checks ensure that your page is optimized for search engine results ranking. There are additional factors Lighthouse does not check that may affect your search ranking. [Learn more](https://support.google.com/webmasters/answer/35769).",
-            "id": "seo",
-            "manualDescription": "Run these additional validators on your site to check additional SEO best practices.",
-            "score": 0.82,
+            ], 
+            "description": "These checks ensure that your page is optimized for search engine results ranking. There are additional factors Lighthouse does not check that may affect your search ranking. [Learn more](https://support.google.com/webmasters/answer/35769).", 
+            "id": "seo", 
+            "manualDescription": "Run these additional validators on your site to check additional SEO best practices.", 
+            "score": 0.73, 
             "title": "SEO"
         }
     },


Test patch:
diff --git a/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html b/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html
index a5fb28e31..5e0042bd4 100644
--- a/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html
+++ b/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html
@@ -182,6 +182,16 @@
 <!-- FAIL(efficient-animated-content): animated gif found -->
 <img src="lighthouse-rotating.gif" width="811" height="462">
 
+<!-- FAIL(tap-targets): buttons too close together -->
+<style>
+.small-button {
+  display: block;
+  width: 200px;
+}
+</style>
+<button class="small-button">Do something</button>
+<button class="small-button">Do something else</button>
+
 <!-- Some websites overwrite the original Error object. The captureJSCallUsage function
   relies on the native Error object and prepareStackTrace from V8. When overwriting the stack
   property the e.stack inside the gatherer won't be in the correct format
diff --git a/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js b/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js
index 230403e1b..c39d18480 100644
--- a/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js
+++ b/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js
@@ -155,12 +155,12 @@ module.exports = [
         },
         'dom-size': {
           score: 1,
-          numericValue: 31,
+          numericValue: 34,
           details: {
             items: [
-              {statistic: 'Total DOM Elements', value: '31'},
+              {statistic: 'Total DOM Elements', value: '34'},
               {statistic: 'Maximum DOM Depth', value: '3'},
-              {statistic: 'Maximum Child Elements', value: '29'},
+              {statistic: 'Maximum Child Elements', value: '32'},
             ],
           },
         },
diff --git a/lighthouse-core/test/report/proto-test.js b/lighthouse-core/test/report/proto-test.js
index 8282ffbf3..2c13b20ef 100644
--- a/lighthouse-core/test/report/proto-test.js
+++ b/lighthouse-core/test/report/proto-test.js
@@ -21,23 +21,10 @@ describe('round trip JSON comparison subsets', () => {
     sampleJson = JSON.parse(preprocessor.processForProto(sample));
   });
 
-  it('has the same audit results sans details', () => {
-    Object.keys(sampleJson.audits).forEach(audit => {
-      delete sampleJson.audits[audit].details;
-    });
-
-    expect(roundTripJson.audits).toMatchObject(sampleJson.audits);
-  });
-
-  it('has the same audit results & details if applicable', () => {
-    Object.keys(sampleJson.audits).forEach(auditId => {
-      expect(roundTripJson.audits[auditId]).toMatchObject(sampleJson.audits[auditId]);
-
-      if ('details' in sampleJson.audits[auditId]) {
-        expect(roundTripJson.audits[auditId].details)
-          .toMatchObject(sampleJson.audits[auditId].details);
-      }
-    });
+  it('has the same audit results and details (if applicable)', () => {
+    for (const auditId of Object.keys(sampleJson.audits)) {
+      expect(roundTripJson.audits[auditId]).toEqual(sampleJson.audits[auditId]);
+    }
   });
 
   it('has the same i18n rendererFormattedStrings', () => {
diff --git a/lighthouse-core/test/results/artifacts/artifacts.json b/lighthouse-core/test/results/artifacts/artifacts.json
index 8509b2cdd..93732cd0f 100644
--- a/lighthouse-core/test/results/artifacts/artifacts.json
+++ b/lighthouse-core/test/results/artifacts/artifacts.json
@@ -2002,7 +2002,40 @@
     "status": 404,
     "content": null
   },
-  "TapTargets": [],
+  "TapTargets": [
+    {
+      "clientRects": [
+        {
+          "width": 200,
+          "height": 18,
+          "left": 8,
+          "top": 1268.8125,
+          "right": 208,
+          "bottom": 1286.8125
+        }
+      ],
+      "snippet": "<button class=\"small-button\">Do something</button>",
+      "path": "3,HTML,1,BODY,17,BUTTON",
+      "selector": "body > button.small-button",
+      "href": ""
+    },
+    {
+      "clientRects": [
+        {
+          "width": 200,
+          "height": 18,
+          "left": 8,
+          "top": 1286.8125,
+          "right": 208,
+          "bottom": 1304.8125
+        }
+      ],
+      "snippet": "<button class=\"small-button\">Do something else</button>",
+      "path": "3,HTML,1,BODY,18,BUTTON",
+      "selector": "body > button.small-button",
+      "href": ""
+    }
+  ],
   "ServiceWorker": {
     "versions": [],
     "registrations": []
diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json
index c045c7cdd..6ab2a57a4 100644
--- a/lighthouse-core/test/results/sample_v2.json
+++ b/lighthouse-core/test/results/sample_v2.json
@@ -2979,15 +2979,52 @@
     },
     "tap-targets": {
       "id": "tap-targets",
-      "title": "Tap targets are sized appropriately",
+      "title": "Tap targets are not sized appropriately",
       "description": "Interactive elements like buttons and links should be large enough (48x48px), and have enough space around them, to be easy enough to tap without overlapping onto other elements. [Learn more](https://developers.google.com/web/fundamentals/accessibility/accessible-styles#multi-device_responsive_design).",
-      "score": 1,
+      "score": 0,
       "scoreDisplayMode": "binary",
-      "displayValue": "100% appropriately sized tap targets",
+      "displayValue": "0% appropriately sized tap targets",
       "details": {
         "type": "table",
-        "headings": [],
-        "items": []
+        "headings": [
+          {
+            "key": "tapTarget",
+            "itemType": "node",
+            "text": "Tap Target"
+          },
+          {
+            "key": "size",
+            "itemType": "text",
+            "text": "Size"
+          },
+          {
+            "key": "overlappingTarget",
+            "itemType": "node",
+            "text": "Overlapping Target"
+          }
+        ],
+        "items": [
+          {
+            "tapTarget": {
+              "type": "node",
+              "snippet": "<button class=\"small-button\">Do something</button>",
+              "path": "3,HTML,1,BODY,17,BUTTON",
+              "selector": "body > button.small-button"
+            },
+            "overlappingTarget": {
+              "type": "node",
+              "snippet": "<button class=\"small-button\">Do something else</button>",
+              "path": "3,HTML,1,BODY,18,BUTTON",
+              "selector": "body > button.small-button"
+            },
+            "tapTargetScore": 864,
+            "overlappingTargetScore": 720,
+            "overlapScoreRatio": 0.8333333333333334,
+            "size": "200x18",
+            "width": 200,
+            "height": 18
+          }
+        ]
       }
     },
     "hreflang": {
@@ -3623,7 +3660,7 @@
         }
       ],
       "id": "seo",
-      "score": 0.82
+      "score": 0.73
     },
     "pwa": {
       "title": "Progressive Web App",
@@ -5270,7 +5307,8 @@
         "audits[render-blocking-resources].details.headings[1].label",
         "audits[unminified-javascript].details.headings[1].label",
         "audits[uses-webp-images].details.headings[2].label",
-        "audits[uses-text-compression].details.headings[1].label"
+        "audits[uses-text-compression].details.headings[1].label",
+        "audits[tap-targets].details.headings[1].text"
       ],
       "lighthouse-core/audits/byte-efficiency/total-byte-weight.js | title": [
         "audits[total-byte-weight].title"
@@ -5456,7 +5494,7 @@
       "lighthouse-core/audits/seo/robots-txt.js | description": [
         "audits[robots-txt].description"
       ],
-      "lighthouse-core/audits/seo/tap-targets.js | title": [
+      "lighthouse-core/audits/seo/tap-targets.js | failureTitle": [
         "audits[tap-targets].title"
       ],
       "lighthouse-core/audits/seo/tap-targets.js | description": [
@@ -5465,11 +5503,17 @@
       "lighthouse-core/audits/seo/tap-targets.js | displayValue": [
         {
           "values": {
-            "decimalProportion": 1
+            "decimalProportion": 0
           },
           "path": "audits[tap-targets].displayValue"
         }
       ],
+      "lighthouse-core/audits/seo/tap-targets.js | tapTargetHeader": [
+        "audits[tap-targets].details.headings[0].text"
+      ],
+      "lighthouse-core/audits/seo/tap-targets.js | overlappingTargetHeader": [
+        "audits[tap-targets].details.headings[2].text"
+      ],
       "lighthouse-core/audits/seo/hreflang.js | title": [
         "audits.hreflang.title"
       ],