From fc3d4264395d88887cae1df2de1b931964f3e684 Mon Sep 17 00:00:00 2001 From: Mbonu Blessing <32465536+Nkemjiks@users.noreply.github.com> Date: Thu, 5 Sep 2019 22:50:27 +0100 Subject: [PATCH] test(docs): add visual testing using applitools (#4872) * test(docs): add visual testing using applitools * chore: delete other spec files * chore: change the core-js import --- docs_app/package-lock.json | 182 ++++++++-------- docs_app/package.json | 1 + docs_app/src/environments/environment.ts | 3 +- docs_app/tests/e2e/api.e2e-spec.ts | 69 ------ docs_app/tests/e2e/api.po.ts | 42 ---- docs_app/tests/e2e/app.e2e-spec.ts | 185 ---------------- docs_app/tests/e2e/app.po.ts | 81 ------- docs_app/tests/e2e/onerror.e2e-spec.ts | 203 ------------------ docs_app/tests/e2e/search.e2e-spec.ts | 28 --- docs_app/tests/e2e/visual-testing.e2e-spec.ts | 41 ++++ 10 files changed, 138 insertions(+), 697 deletions(-) delete mode 100644 docs_app/tests/e2e/api.e2e-spec.ts delete mode 100644 docs_app/tests/e2e/api.po.ts delete mode 100644 docs_app/tests/e2e/app.e2e-spec.ts delete mode 100644 docs_app/tests/e2e/app.po.ts delete mode 100644 docs_app/tests/e2e/onerror.e2e-spec.ts delete mode 100644 docs_app/tests/e2e/search.e2e-spec.ts create mode 100644 docs_app/tests/e2e/visual-testing.e2e-spec.ts diff --git a/docs_app/package-lock.json b/docs_app/package-lock.json index 73b376c501..b16599d120 100644 --- a/docs_app/package-lock.json +++ b/docs_app/package-lock.json @@ -100,6 +100,12 @@ "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==", "dev": true }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, "parse5": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", @@ -197,6 +203,12 @@ "uri-js": "^4.2.2" } }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, "rxjs": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", @@ -1274,12 +1286,18 @@ "version": "6.9.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", - "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "dependencies": { + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + } } }, "ajv-errors": { @@ -1563,7 +1581,6 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -1609,8 +1626,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assign-symbols": { "version": "1.0.0", @@ -1654,8 +1670,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.2", @@ -1680,14 +1695,12 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "axe-core": { "version": "3.2.2", @@ -1957,7 +1970,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -2482,8 +2494,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "catharsis": { "version": "0.8.9", @@ -2878,7 +2889,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -3327,8 +3337,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "corser": { "version": "2.0.1", @@ -3624,7 +3633,6 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -3658,6 +3666,11 @@ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3828,8 +3841,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "depd": { "version": "1.1.2", @@ -4198,7 +4210,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -4942,8 +4953,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "3.0.2", @@ -5066,8 +5076,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "eyes": { "version": "0.1.8", @@ -5075,11 +5084,32 @@ "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", "dev": true }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true + "eyes.sdk": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eyes.sdk/-/eyes.sdk-3.7.0.tgz", + "integrity": "sha512-WqzLMa7KRbmBZFZRIqjK38G6bSrI9Hjo5Ohxcv//3sB4gBZK9RPI3s5rOORB9C8VH4sNaeOoSB1cHAQ6sajC0g==", + "requires": { + "eyes.utils": "^3.6.4", + "request": "^2.88.0" + } + }, + "eyes.selenium": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eyes.selenium/-/eyes.selenium-3.7.0.tgz", + "integrity": "sha512-jC+w7lUH4uFhTi5jEr8iivnip2Ki0ktbdXdAXHU/dg2K73lypMFcN0v69kmRhhbSQB/vUZOlgA8lZkvdYWzjtQ==", + "requires": { + "eyes.sdk": "^3.7.0", + "eyes.utils": "^3.6.4" + } + }, + "eyes.utils": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/eyes.utils/-/eyes.utils-3.6.4.tgz", + "integrity": "sha512-nnYwjHJNLPdqf9/i//pp1R1CCq1Vz4sV+O688B6WW+ppuIBordaPxLbgGbYjZKDLq1XZ3cBsCiCdd/HRzl9TtA==", + "requires": { + "dateformat": "^3.0.3", + "png-async": "^0.9.4" + } }, "fast-glob": { "version": "2.2.7", @@ -5098,8 +5128,7 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "fast-levenshtein": { "version": "2.0.6", @@ -5732,14 +5761,12 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -5861,7 +5888,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -6276,7 +6304,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -6332,6 +6361,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6375,12 +6405,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -6431,7 +6463,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -6687,14 +6718,12 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -7096,7 +7125,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -7737,8 +7765,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-upper-case": { "version": "1.1.2", @@ -7809,8 +7836,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-api": { "version": "2.1.6", @@ -8265,8 +8291,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsdom": { "version": "15.1.1", @@ -8339,14 +8364,12 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -8357,8 +8380,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json3": { "version": "3.3.3", @@ -8462,7 +8484,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -9670,14 +9691,12 @@ "mime-db": { "version": "1.38.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", - "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", - "dev": true + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" }, "mime-types": { "version": "2.1.22", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", - "dev": true, "requires": { "mime-db": "~1.38.0" } @@ -10287,8 +10306,7 @@ "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "object-assign": { "version": "4.1.1", @@ -10917,8 +10935,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "4.0.1", @@ -10962,6 +10979,11 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, + "png-async": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/png-async/-/png-async-0.9.4.tgz", + "integrity": "sha512-B//AXX9TkneKfgtOpT1mdUnnhk2BImGD+a98vImsMU8uo1dBeHyW/kM2erWZ/CsYteTPU/xKG+t6T62heHkC3A==" + }, "portfinder": { "version": "1.0.20", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", @@ -11299,10 +11321,9 @@ "dev": true }, "psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", - "dev": true + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" }, "public-encrypt": { "version": "4.0.3", @@ -11354,8 +11375,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "q": { "version": "1.5.1", @@ -11372,8 +11392,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { "version": "5.1.1", @@ -12040,7 +12059,6 @@ "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -12284,8 +12302,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -12317,8 +12334,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { "version": "1.19.0", @@ -13262,7 +13278,6 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -14051,7 +14066,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -14060,8 +14074,7 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" } } }, @@ -14197,7 +14210,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -14205,8 +14217,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-check": { "version": "0.3.2", @@ -14674,7 +14685,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -14803,8 +14813,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8-compile-cache": { "version": "2.0.3", @@ -14853,7 +14862,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", diff --git a/docs_app/package.json b/docs_app/package.json index e961d93697..2e613cf91d 100644 --- a/docs_app/package.json +++ b/docs_app/package.json @@ -59,6 +59,7 @@ "@webcomponents/custom-elements": "^1.2.4", "classlist.js": "^1.1.20150312", "core-js": "^3.1.3", + "eyes.selenium": "^3.7.0", "rxjs": "^6.5.2", "tslib": "^1.10.0", "web-animations-js": "github:angular/web-animations-js#release_pr208", diff --git a/docs_app/src/environments/environment.ts b/docs_app/src/environments/environment.ts index 75dba29396..366d82684e 100644 --- a/docs_app/src/environments/environment.ts +++ b/docs_app/src/environments/environment.ts @@ -8,8 +8,7 @@ // // In order to load these polyfills early enough (before app code), polyfill.ts imports this file to // to change the order in the final bundle. -import 'core-js/es6/reflect'; -import 'core-js/es7/reflect'; +import 'core-js/es/reflect'; export const environment = { diff --git a/docs_app/tests/e2e/api.e2e-spec.ts b/docs_app/tests/e2e/api.e2e-spec.ts deleted file mode 100644 index 9ff6625eef..0000000000 --- a/docs_app/tests/e2e/api.e2e-spec.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { ApiPage } from './api.po'; - -describe('Api pages', function() { - it('should show direct subclasses of a class', () => { - const page = new ApiPage('api/forms/AbstractControlDirective'); - expect(page.getDescendants('class', true)).toEqual(['ControlContainer', 'NgControl']); - }); - - it('should show direct and indirect subclasses of a class', () => { - const page = new ApiPage('api/forms/AbstractControlDirective'); - expect(page.getDescendants('class')).toEqual(['ControlContainer', 'AbstractFormGroupDirective', 'NgControl']); - }); - - it('should show child interfaces that extend an interface', () => { - const page = new ApiPage('api/forms/Validator'); - expect(page.getDescendants('interface')).toEqual(['AsyncValidator']); - }); - - it('should show classes that implement an interface', () => { - const page = new ApiPage('api/animations/AnimationPlayer'); - expect(page.getDescendants('class')).toEqual(['NoopAnimationPlayer', 'MockAnimationPlayer']); - }); - - it('should show type params of type-aliases', () => { - const page = new ApiPage('api/common/http/HttpEvent'); - expect(page.getOverview('type-alias').getText()).toContain('type HttpEvent'); - }); - - it('should show readonly properties as getters', () => { - const page = new ApiPage('api/common/http/HttpRequest'); - expect(page.getOverview('class').getText()).toContain('get body: T | null'); - }); - - it('should not show parenthesis for getters', () => { - const page = new ApiPage('api/core/NgModuleRef'); - expect(page.getOverview('class').getText()).toContain('get injector: Injector'); - }); - - it('should show both type and initializer if set', () => { - const page = new ApiPage('api/common/HashLocationStrategy'); - expect(page.getOverview('class').getText()).toContain('path(includeHash: boolean = false): string'); - }); - - it('should show a "Properties" section if there are public properties', () => { - const page = new ApiPage('api/core/ViewContainerRef'); - expect(page.getSection('instance-properties').isPresent()).toBe(true); - }); - - it('should not show a "Properties" section if there are only internal properties', () => { - const page = new ApiPage('api/forms/FormControl'); - expect(page.getSection('instance-properties').isPresent()).toBe(false); - }); - - it('should show "impure" badge if pipe is not pure', () => { - const page = new ApiPage('api/common/AsyncPipe'); - const impureBadge = page.getBadge('impure-pipe'); - expect(impureBadge.isPresent()).toBe(true); - }); - - it('should show links to github', () => { - const page = new ApiPage('api/core/EventEmitter'); - /* tslint:disable:max-line-length */ - expect(page.ghLinks.get(0).getAttribute('href')) - .toMatch(/https:\/\/github\.com\/angular\/angular\/edit\/master\/packages\/core\/src\/event_emitter\.ts\?message=docs\(core\)%3A%20describe%20your%20change\.\.\.#L\d+-L\d+/); - expect(page.ghLinks.get(1).getAttribute('href')) - .toMatch(/https:\/\/github\.com\/angular\/angular\/tree\/[^/]+\/packages\/core\/src\/event_emitter\.ts#L\d+-L\d+/); - /* tslint:enable:max-line-length */ - }); -}); diff --git a/docs_app/tests/e2e/api.po.ts b/docs_app/tests/e2e/api.po.ts deleted file mode 100644 index b2bb4a3b15..0000000000 --- a/docs_app/tests/e2e/api.po.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { element, by } from 'protractor'; -import { SitePage } from './app.po'; - -export class ApiPage extends SitePage { - constructor(url: string) { - super(); - this.navigateTo(url); - } - - getDescendants(docType: string, onlyDirect = false) { - // This selector is horrible because we have potentially recursive HTML lists - // - // ul - // li - // code - // ul - // li - // code - // ul - // li - // code - // li - // code - // - // and we want to be able to pull out the code elements from only the first level - // if `onlyDirect` is set to `true`. - const selector = `.descendants.${docType} ${onlyDirect ? '>' : ''} ul > li > code`; - return element.all(by.css(selector)).map(item => item && item.getText()); - } - - getOverview(docType) { - return element(by.css(`.${docType}-overview`)); - } - - getSection(cls) { - return element(by.css(`section.${cls}`)); - } - - getBadge(cls) { - return element(by.css('.api-status-label.' + cls)); - } -} diff --git a/docs_app/tests/e2e/app.e2e-spec.ts b/docs_app/tests/e2e/app.e2e-spec.ts deleted file mode 100644 index 0f0fa2aefd..0000000000 --- a/docs_app/tests/e2e/app.e2e-spec.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { browser, by, element, ElementFinder } from 'protractor'; -import { SitePage } from './app.po'; - -describe('site App', function() { - let page: SitePage; - - beforeEach(() => { - SitePage.setWindowWidth(1050); // Make the window wide enough to show the SideNav side-by-side. - page = new SitePage(); - }); - - it('should show features text after clicking "Features"', () => { - page.navigateTo(''); - page.click(page.getTopMenuLink('features')); - expect(page.getDocViewerText()).toMatch(/Progressive web apps/i); - }); - - it('should set appropriate window titles', () => { - page.navigateTo(''); - expect(browser.getTitle()).toBe('Angular'); - - page.click(page.getTopMenuLink('features')); - expect(browser.getTitle()).toBe('Angular - FEATURES & BENEFITS'); - - page.click(page.homeLink); - expect(browser.getTitle()).toBe('Angular'); - }); - - it('should not navigate when clicking on nav-item headings (sub-menu toggles)', () => { - // Show the sidenav. - page.navigateTo('docs'); - expect(page.locationPath()).toBe('/docs'); - - // Get the top-level nav-item headings (sub-menu toggles). - const navItemHeadings = page.getNavItemHeadings(page.sidenav, 1); - - // Test all headings (and sub-headings). - expect(navItemHeadings.count()).toBeGreaterThan(0); - navItemHeadings.each(heading => testNavItemHeading(heading!, 1)); - - // Helpers - function expectToBeCollapsed(element: ElementFinder) { - expect(element.getAttribute('class')).toMatch(/\bcollapsed\b/); - expect(element.getAttribute('class')).not.toMatch(/\bexpanded\b/); - } - - function expectToBeExpanded(element: ElementFinder) { - expect(element.getAttribute('class')).not.toMatch(/\bcollapsed\b/); - expect(element.getAttribute('class')).toMatch(/\bexpanded\b/); - } - - function testNavItemHeading(heading: ElementFinder, level: number) { - const children = page.getNavItemHeadingChildren(heading, level); - - // Headings are initially collapsed. - expectToBeCollapsed(children); - - // Ensure heading does not cause navigation when expanding. - page.click(heading); - expectToBeExpanded(children); - expect(page.locationPath()).toBe('/docs'); - - // Recursively test child-headings (while this heading is expanded). - const nextLevel = level + 1; - const childNavItemHeadings = page.getNavItemHeadings(children, nextLevel); - childNavItemHeadings.each(childHeading => testNavItemHeading(childHeading!, nextLevel)); - - // Ensure heading does not cause navigation when collapsing. - page.click(heading); - expectToBeCollapsed(children); - expect(page.locationPath()).toBe('/docs'); - } - }); - - it('should show the tutorial index page at `/tutorial` after jitterbugging through features', () => { - // check that we can navigate directly to the tutorial page - page.navigateTo('tutorial'); - expect(page.getDocViewerText()).toMatch(/Tutorial: Tour of Heroes/i); - - // navigate to a different page - page.click(page.getTopMenuLink('features')); - expect(page.getDocViewerText()).toMatch(/Progressive web apps/i); - - // Show the menu - page.click(page.docsMenuLink); - - // Tutorial folder should still be expanded because this test runs in wide mode - // Navigate to the tutorial introduction via a link in the sidenav - page.click(page.getNavItem(/introduction/i)); - expect(page.getDocViewerText()).toMatch(/Tutorial: Tour of Heroes/i); - }); - - it('should render `{@example}` dgeni tags as `` elements with HTML escaped content', () => { - page.navigateTo('guide/component-styles'); - const codeExample = element.all(by.css('code-example')).first(); - expect(page.getInnerHtml(codeExample)).toContain('<h1>Tour of Heroes</h1>'); - }); - - describe('scrolling to the top', () => { - it('should scroll to the top when navigating to another page', () => { - page.navigateTo('guide/security'); - - page.scrollToBottom(); - expect(page.getScrollTop()).toBeGreaterThan(0); - - page.click(page.getNavItem(/api/i)); - expect(page.locationPath()).toBe('/api'); - expect(page.getScrollTop()).toBe(0); - }); - - it('should scroll to the top when navigating to the same page', () => { - page.navigateTo('guide/security'); - - page.scrollToBottom(); - expect(page.getScrollTop()).toBeGreaterThan(0); - - page.click(page.getNavItem(/security/i)); - expect(page.locationPath()).toBe('/guide/security'); - expect(page.getScrollTop()).toBe(0); - }); - }); - - describe('tutorial docs', () => { - it('should not render a paragraph element inside the h1 element', () => { - page.navigateTo('tutorial/toh-pt1'); - expect(element(by.css('h1 p')).isPresent()).toBeFalsy(); - }); - }); - - describe('google analytics', () => { - - it('should call ga with initial URL', done => { - let path: string; - page.navigateTo('api'); - page.locationPath() - .then(p => path = p) - .then(() => page.ga()) - .then(calls => { - // The last call (length-1) will be the `send` command - // The second to last call (length-2) will be the command to `set` the page url - expect(calls[calls.length - 2]).toEqual(['set', 'page', path]); - done(); - }); - }); - - it('should call ga with new URL on navigation', done => { - let path: string; - page.navigateTo(''); - page.click(page.getTopMenuLink('features')); - page.locationPath() - .then(p => path = p) - .then(() => page.ga()) - .then(calls => { - // The last call (length-1) will be the `send` command - // The second to last call (length-2) will be the command to `set` the page url - expect(calls[calls.length - 2]).toEqual(['set', 'page', path]); - done(); - }); - }); - }); - - describe('404 page', () => { - it('should add or remove the "noindex" meta tag depending upon the validity of the page', () => { - page.navigateTo(''); - expect(element(by.css('meta[name="googlebot"]')).isPresent()).toBeFalsy(); - expect(element(by.css('meta[name="robots"]')).isPresent()).toBeFalsy(); - - page.navigateTo('does/not/exist'); - expect(element(by.css('meta[name="googlebot"][content="noindex"]')).isPresent()).toBeTruthy(); - expect(element(by.css('meta[name="robots"][content="noindex"]')).isPresent()).toBeTruthy(); - - page.click(page.getTopMenuLink('features')); - expect(element(by.css('meta[name="googlebot"]')).isPresent()).toBeFalsy(); - expect(element(by.css('meta[name="robots"]')).isPresent()).toBeFalsy(); - }); - - it('should search the index for words found in the url', () => { - page.navigateTo('http/router'); - const results = page.getSearchResults(); - - expect(results).toContain('Http'); - expect(results).toContain('Router'); - }); - }); -}); diff --git a/docs_app/tests/e2e/app.po.ts b/docs_app/tests/e2e/app.po.ts deleted file mode 100644 index 1194620da2..0000000000 --- a/docs_app/tests/e2e/app.po.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { browser, element, by, promise, ElementFinder, ExpectedConditions } from 'protractor'; - -const githubRegex = /https:\/\/github.com\/angular\/angular\//; - -export class SitePage { - - links = element.all(by.css('md-toolbar a')); - homeLink = element(by.css('a.home')); - docsMenuLink = element(by.cssContainingText('aio-top-menu a', 'Docs')); - sidenav = element(by.css('mat-sidenav')); - docViewer = element(by.css('aio-doc-viewer')); - codeExample = element.all(by.css('aio-doc-viewer pre > code')); - ghLinks = this.docViewer - .all(by.css('a')) - .filter((a: ElementFinder) => a.getAttribute('href').then(href => githubRegex.test(href))); - - static setWindowWidth(newWidth: number) { - const win = browser.driver.manage().window(); - return win.getSize().then(oldSize => win.setSize(newWidth, oldSize.height)); - } - - getNavItem(pattern: RegExp) { - return element.all(by.css('aio-nav-item .vertical-menu-item')) - .filter(element => element.getText().then(text => pattern.test(text))) - .first(); - } - getNavItemHeadings(parent: ElementFinder, level: number) { - const targetSelector = `aio-nav-item .vertical-menu-item.heading.level-${level}`; - return parent.all(by.css(targetSelector)); - } - getNavItemHeadingChildren(heading: ElementFinder, level: number) { - const targetSelector = `.heading-children.level-${level}`; - const script = `return arguments[0].parentNode.querySelector('${targetSelector}');`; - return element(() => browser.executeScript(script, heading)); - } - getTopMenuLink(path) { return element(by.css(`aio-top-menu a[href="${path}"]`)); } - - ga() { return browser.executeScript('return window["ga"].q') as promise.Promise; } - locationPath() { return browser.executeScript('return document.location.pathname') as promise.Promise; } - - navigateTo(pageUrl) { - // Navigate to the page, disable animations, and wait for Angular. - return browser.get('/' + pageUrl) - .then(() => browser.executeScript('document.body.classList.add(\'no-animations\')')) - .then(() => browser.waitForAngular()); - } - - getDocViewerText() { - return this.docViewer.getText(); - } - - getInnerHtml(element) { - // `getInnerHtml` was removed from webDriver and this is the workaround. - // See https://github.com/angular/protractor/blob/master/CHANGELOG.md#breaking-changes - return browser.executeScript('return arguments[0].innerHTML;', element); - } - - getScrollTop() { - return browser.executeScript('return window.pageYOffset'); - } - - scrollToBottom() { - return browser.executeScript('window.scrollTo(0, document.body.scrollHeight)'); - } - - click(element: ElementFinder) { - return element.click().then(() => browser.waitForAngular()); - } - - enterSearch(query: string) { - const input = element(by.css('.search-container input[type=search]')); - input.clear(); - input.sendKeys(query); - } - - getSearchResults() { - const results = element.all(by.css('.search-results li')); - browser.wait(ExpectedConditions.presenceOf(results.first()), 8000); - return results.map(link => link && link.getText()); - } -} diff --git a/docs_app/tests/e2e/onerror.e2e-spec.ts b/docs_app/tests/e2e/onerror.e2e-spec.ts deleted file mode 100644 index 70549b4cd0..0000000000 --- a/docs_app/tests/e2e/onerror.e2e-spec.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { browser } from 'protractor'; -import { SitePage } from './app.po'; - -/* tslint:disable:max-line-length */ - -describe('onerror handler', function() { - let page: SitePage; - - beforeAll(() => { - page = new SitePage(); - page.navigateTo(''); - }); - - - it('(called without an error object) should call ga with a payload based on the message, url, row and column arguments', async () => { - const message1 = await callOnError('Error: some error message', 'some-file.js', 12, 3, undefined); - expect(message1).toEqual('some error message\nsome-file.js:12:3'); - const message2 = await callOnError('Error: some error message', undefined, undefined, undefined, undefined); - expect(message2).toEqual('some error message\nnull:?:?'); - }); - - it('(called without an error object) should call ga with a payload that is no longer that 150 characters', async () => { - const message = await callOnError( - 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' + - 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz', - 'some-file.js', 12, 3, undefined); - expect(message).toEqual( - 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' + - 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst'); - }); - - it('(called with a Firefox on android style error) should call ga with a payload based on the error object', async () => { - const message = await callOnError('Error: something terrible has happened. oh no. oh no.', undefined, undefined, undefined, { - stack: `AppComponent@https://example.com/app/app.component.ts:31:29 -createClass@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:12200:20 -createDirectiveInstance@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:12049:37 -createViewNodes@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:13487:53 -createRootView@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:13377:5 -callWithDebugContext@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:14778:39 -debugCreateRootView@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:14079:12 -ComponentFactory_.prototype.create@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:10998:37 -ComponentFactoryBoundToModule.prototype.create@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:3958:16 -ApplicationRef.prototype.bootstrap@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:5769:40 -PlatformRef.prototype._moduleDoBootstrap/<@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:5496:74 -PlatformRef.prototype._moduleDoBootstrap@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:5496:13 -PlatformRef.prototype.bootstrapModuleFactory/ { - const message = await callOnError('Error: something terrible has happened. oh no. oh no.', undefined, undefined, undefined, { - stack: `AppComponent - createClass - createDirectiveInstance - createViewNodes - createRootView - callWithDebugContext - create - bootstrap - forEach@[native code] - _moduleDoBootstrap - - onInvoke - run - - onInvokeTask - runTask - drainMicroTaskQueue - promiseReactionJob@[native code]` }); - - expect(message).toEqual(`something terrible has happened. oh no. oh no. -AppComponent -createClass -createDirectiveInstance -createViewNodes -createRootView -callWithDebugContext -cr`); - }); - - it('(called with a Opera 50 style error) should call ga with a payload based on the error object', async () => { - const message = await callOnError('Error: something terrible has happened. oh no. oh no.', undefined, undefined, undefined, { - stack: `Error: something terrible has happened. oh no. oh no. - at new AppComponent (https://example.com/app/app.component.ts:31:29) - at createClass (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:12200:20) - at createDirectiveInstance (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:12049:37) - at createViewNodes (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:13487:53) - at createRootView (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:13377:5) - at callWithDebugContext (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:14778:42) - at Object.debugCreateRootView [as createRootView] (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:14079:12) - at ComponentFactory_.create (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:10998:46) - at ComponentFactoryBoundToModule.create (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:3958:29) - at ApplicationRef.bootstrap (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:5769:57)` }); - - expect(message).toEqual(`something terrible has happened. oh no. oh no. -new AppComponent@app.component.ts:31:29 -createClass@core.umd.js:12200:20 -createDirectiveInstance@core.u`); - }); - - it('(called with a Chrome 64 style error) should call ga with a payload based on the error object', async () => { - const message = await callOnError('Error: something terrible has happened. oh no. oh no.', undefined, undefined, undefined, { - stack: `Error: something terrible has happened. oh no. oh no. - at new AppComponent (https://example.com/app/app.component.ts:31:29) - at createClass (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:12200:20) - at createDirectiveInstance (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:12049:37) - at createViewNodes (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:13487:53) - at createRootView (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:13377:5) - at callWithDebugContext (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:14778:42) - at Object.debugCreateRootView [as createRootView] (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:14079:12) - at ComponentFactory_.create (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:10998:46) - at ComponentFactoryBoundToModule.create (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:3958:29) - at ApplicationRef.bootstrap (https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:5769:57)` }); - - expect(message).toEqual(`something terrible has happened. oh no. oh no. -new AppComponent@app.component.ts:31:29 -createClass@core.umd.js:12200:20 -createDirectiveInstance@core.u`); - }); - - it('(called with a Firefox 58 style error) should call ga with a payload based on the error object', async () => { - const message = await callOnError('Error: something terrible has happened. oh no. oh no.', undefined, undefined, undefined, { - stack: `AppComponent@https://example.com/app/app.component.ts:31:29 -createClass@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:12200:20 -createDirectiveInstance@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:12049:37 -createViewNodes@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:13487:53 -createRootView@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:13377:5 -callWithDebugContext@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:14778:39 -debugCreateRootView@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:14079:12 -ComponentFactory_.prototype.create@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:10998:37 -ComponentFactoryBoundToModule.prototype.create@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:3958:16 -ApplicationRef.prototype.bootstrap@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:5769:40 -PlatformRef.prototype._moduleDoBootstrap/<@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:5496:74 -PlatformRef.prototype._moduleDoBootstrap@https://example.com/packages/@angular/core@5.0.0/bundles/core.umd.js:5496:13 -PlatformRef.prototype.bootstrapModuleFactory/ { - const message = await callOnError('Error: something terrible has happened. oh no. oh no.', undefined, undefined, undefined, { - stack: `Error: something terrible has happened. oh no. oh no. - at AppComponent (eval code:31:21) - at createClass (eval code:12200:13) - at createDirectiveInstance (eval code:12049:5) - at createViewNodes (eval code:13487:21) - at createRootView (eval code:13377:5) - at callWithDebugContext (eval code:14778:9) - at debugCreateRootView (eval code:14079:5) - at ComponentFactory_.prototype.create (eval code:10998:9) - at ComponentFactoryBoundToModule.prototype.create (eval code:3958:9) - at ApplicationRef.prototype.bootstrap (eval code:5769:9)` }); - - expect(message).toEqual(`something terrible has happened. oh no. oh no. -AppComponent@???:31:21 -createClass@???:12200:13 -createDirectiveInstance@???:12049:5 -createViewNodes@???`); - }); - - async function callOnError(message, url, line, column, error) { - await browser.executeScript(function() { - // reset the ga queue - (window as any).ga.q.length = 0; - // post the error to the handler - window.onerror(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]); - }, message, url, line, column, error); - const gaCalls = await page.ga(); - const exceptionCall = gaCalls.find(call => call[0] === 'send' && call[1] === 'exception'); - if (exceptionCall) { - const payload = exceptionCall[2]; - expect(payload.exFatal).toBe(true); - return payload.exDescription; - } - } -}); diff --git a/docs_app/tests/e2e/search.e2e-spec.ts b/docs_app/tests/e2e/search.e2e-spec.ts deleted file mode 100644 index 84bd4e64d6..0000000000 --- a/docs_app/tests/e2e/search.e2e-spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { SitePage } from './app.po'; - -describe('site search', () => { - let page; - - beforeEach(() => { - page = new SitePage(); - page.navigateTo(''); - }); - - it('should find pages when searching by a partial word in the title', () => { - page.enterSearch('ngCont'); - expect(page.getSearchResults()).toContain('NgControl'); - - page.enterSearch('accessor'); - expect(page.getSearchResults()).toContain('ControlValueAccessor'); - }); - - it('should find API docs whose instance member name matches the search query', () => { - page.enterSearch('decode'); - expect(page.getSearchResults()).toContain('HttpParameterCodec'); - }); - - it('should find API docs whose static method name matches the search query', () => { - page.enterSearch('compose'); - expect(page.getSearchResults()).toContain('Validators'); - }); -}); diff --git a/docs_app/tests/e2e/visual-testing.e2e-spec.ts b/docs_app/tests/e2e/visual-testing.e2e-spec.ts new file mode 100644 index 0000000000..d1284f3bf5 --- /dev/null +++ b/docs_app/tests/e2e/visual-testing.e2e-spec.ts @@ -0,0 +1,41 @@ +import { browser } from 'protractor'; + +const Eyes = require('eyes.selenium').Eyes; +const eyes = new Eyes(); + +describe('RxJS Docs', function() { + it('shows the landing page', () => { + eyes.open(browser, 'Landing Page', 'RxJS Docs'); + browser.get(''); + eyes.checkWindow('Landing page!'); + eyes.close(); + }); + + it('shows the overview page', () => { + eyes.open(browser, 'Overview Page', 'RxJS Docs'); + browser.get('/guide/overview'); + eyes.checkWindow('Overview page!'); + eyes.close(); + }); + + it('shows the API page', () => { + eyes.open(browser, 'API Page', 'RxJS Docs'); + browser.get('/api'); + eyes.checkWindow('API page!'); + eyes.close(); + }); + + it('shows the migration page', () => { + eyes.open(browser, 'Migration Page', 'RxJS Docs'); + browser.get('/guide/v6/migration'); + eyes.checkWindow('Migration page!'); + eyes.close(); + }); + + it('shows the team page', () => { + eyes.open(browser, 'Team Page', 'RxJS Docs'); + browser.get('/team'); + eyes.checkWindow('Team page!'); + eyes.close(); + }); +});