UI: Add initial puppeteer-based integrationtests

This CL introduces support for UI integrationtests.
Those tests are based on puppeteer (Chrome headless)
and work by injecting user actions into the real UI,
capturing screenshots and diffing them against
reference ones.

Each test() unit in ui_integrationtests.ts automatically
captures and diffs the screenshot at the end of the run.
In case of failures, diffs are uploaded to the CI GCS
bucket (gs://perfetto-ci-artifacts/$key/).

I got to a state where tests can be run both on Linux
and Mac successfully. There are few rendering differences
between the two, due to the fact that font rendering
seems platform specific. But with enough tweaks the
difference can be contained to sub-pixel antialiasing
and can be dealt with a threshold in the diff algorithm.

Bug: 190075400
Change-Id: I5fb35c41ba5f95a4761465b9d0128edd92414510
diff --git a/ui/package-lock.json b/ui/package-lock.json
index c0236d7..ec5e104 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -934,6 +934,15 @@
       "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz",
       "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg=="
     },
+    "@types/pixelmatch": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/@types/pixelmatch/-/pixelmatch-5.2.3.tgz",
+      "integrity": "sha512-p+nAQVYK/DUx7+s1Xyu9dqAg0gobf7VmJ+iDA4lljg1o4XRgQHr7R2h1NwFt3gdNOZiftxWB11+0TuZqXYf19w==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/prettier": {
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz",
@@ -4267,6 +4276,15 @@
       "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
       "dev": true
     },
+    "node-libpng": {
+      "version": "0.2.18",
+      "resolved": "https://registry.npmjs.org/node-libpng/-/node-libpng-0.2.18.tgz",
+      "integrity": "sha512-nr2j+Qn68ocw/0mfj09Yg8AEEdjrrQYMnFAWi8wLpwe2FMdLr36OFalIEkrJnwpqQxDybfqw7l1GH2wJ98wUIw==",
+      "dev": true,
+      "requires": {
+        "request": "^2.88.2"
+      }
+    },
     "node-modules-regexp": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
@@ -4789,6 +4807,15 @@
         "node-modules-regexp": "^1.0.0"
       }
     },
+    "pixelmatch": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz",
+      "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==",
+      "dev": true,
+      "requires": {
+        "pngjs": "^4.0.1"
+      }
+    },
     "pkg-dir": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@@ -4798,6 +4825,12 @@
         "find-up": "^4.0.0"
       }
     },
+    "pngjs": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz",
+      "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==",
+      "dev": true
+    },
     "posix-character-classes": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",