From c0ea4bf1d02a00d167b74d5bcb9b0bd8a77f03aa Mon Sep 17 00:00:00 2001 From: Abigail Gervase Date: Tue, 18 Jul 2017 13:46:31 -0400 Subject: [PATCH 1/2] Bring in Automated tests and update WebdriverIO dependency --- .../xdmod/automated_tests/.eslintrc.json | 17 + .../modules/xdmod/automated_tests/.gitignore | 3 + .../xdmod/automated_tests/package-lock.json | 1489 +++++++++++++++++ .../xdmod/automated_tests/package.json | 25 + .../modules/xdmod/automated_tests/readme.md | 126 ++ .../automated_tests/template.secrets.json | 9 + .../automated_tests/test/helpers/auth.js | 7 + .../test/helpers/getScreenshotTitle.js | 16 + .../test/helpers/handleScreenshots.js | 19 + .../automated_tests/test/helpers/index.js | 1 + .../test/helpers/instructions.js | 14 + .../test/helpers/metricExplorer.js | 87 + .../automated_tests/test/specs/xdmod/about.js | 101 ++ .../test/specs/xdmod/about.page.js | 33 + .../test/specs/xdmod/loginPage.page.js | 53 + .../test/specs/xdmod/mainToolbar.js | 38 + .../test/specs/xdmod/mainToolbar.page.js | 57 + .../test/specs/xdmod/metricExplorer.js | 451 +++++ .../test/specs/xdmod/metricExplorer.page.js | 266 +++ .../test/specs/xdmod/reportGenerator.js | 107 ++ .../test/specs/xdmod/reportGenerator.page.js | 128 ++ .../test/specs/xdmod/usageTab.js | 29 + .../test/specs/xdmod/usageTab.page.js | 18 + .../xdmod/automated_tests/wdio-sauce.conf.js | 249 +++ .../xdmod/automated_tests/wdio.conf.js | 239 +++ .../getChartSeriesPointLocation.js | 41 + .../automated_tests/webdriverHelpers/index.js | 1 + .../webdriverHelpers/waitAndClick.js | 14 + .../webdriverHelpers/waitAndSet.js | 65 + .../webdriverHelpers/waitForChart.js | 14 + .../webdriverHelpers/waitForInvisible.js | 13 + .../waitForLoadedThenClick.js | 15 + .../webdriverHelpers/waitUntilAnimEnd.js | 32 + .../waitUntilAnimEndAndClick.js | 19 + .../waitUntilChartLoadsBySeries.js | 14 + .../webdriverHelpers/waitUntilNotExist.js | 13 + 36 files changed, 3823 insertions(+) create mode 100644 open_xdmod/modules/xdmod/automated_tests/.eslintrc.json create mode 100644 open_xdmod/modules/xdmod/automated_tests/.gitignore create mode 100644 open_xdmod/modules/xdmod/automated_tests/package-lock.json create mode 100644 open_xdmod/modules/xdmod/automated_tests/package.json create mode 100644 open_xdmod/modules/xdmod/automated_tests/readme.md create mode 100644 open_xdmod/modules/xdmod/automated_tests/template.secrets.json create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/helpers/auth.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/helpers/getScreenshotTitle.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/helpers/handleScreenshots.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/helpers/index.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/helpers/instructions.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/helpers/metricExplorer.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.page.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/loginPage.page.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.page.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.page.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.page.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.page.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/wdio-sauce.conf.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/wdio.conf.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/getChartSeriesPointLocation.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/index.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndClick.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndSet.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForChart.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForInvisible.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForLoadedThenClick.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEnd.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEndAndClick.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilChartLoadsBySeries.js create mode 100644 open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilNotExist.js diff --git a/open_xdmod/modules/xdmod/automated_tests/.eslintrc.json b/open_xdmod/modules/xdmod/automated_tests/.eslintrc.json new file mode 100644 index 0000000000..7ecd1b566b --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/.eslintrc.json @@ -0,0 +1,17 @@ +{ + "env": { + "mocha": true, + "node": true, + "es6": true + }, + "globals": { + "expect": false, + "browser": false, + "testHelpers": false, + "$": false + }, + "rules": { + "class-methods-use-this": [0], + "no-underscore-dangle": [0] + } +} diff --git a/open_xdmod/modules/xdmod/automated_tests/.gitignore b/open_xdmod/modules/xdmod/automated_tests/.gitignore new file mode 100644 index 0000000000..7bea03640c --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/.gitignore @@ -0,0 +1,3 @@ +# Screenshots +/xdmod +/xdmod.tar.gz diff --git a/open_xdmod/modules/xdmod/automated_tests/package-lock.json b/open_xdmod/modules/xdmod/automated_tests/package-lock.json new file mode 100644 index 0000000000..a7e3329b2b --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/package-lock.json @@ -0,0 +1,1489 @@ +{ + "name": "selenium-tests", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "adm-zip": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz", + "integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E=", + "dev": true + }, + "agent-base": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "dev": true, + "requires": { + "extend": "3.0.1", + "semver": "5.0.3" + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=" + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true + }, + "babel-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", + "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", + "requires": { + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", + "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", + "requires": { + "assertion-error": "1.0.2", + "deep-eql": "0.1.3", + "type-detect": "1.0.0" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.2", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "cheerio": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", + "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", + "requires": { + "css-select": "1.0.0", + "dom-serializer": "0.1.0", + "entities": "1.1.1", + "htmlparser2": "3.8.3", + "lodash": "3.10.1" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", + "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "core-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" + }, + "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=" + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "css-select": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", + "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", + "requires": { + "boolbase": "1.0.0", + "css-what": "1.0.0", + "domutils": "1.4.3", + "nth-check": "1.0.1" + } + }, + "css-what": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", + "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=" + }, + "dashdash": { + "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" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "requires": { + "type-detect": "0.1.1" + }, + "dependencies": { + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=" + } + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "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 + }, + "diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=" + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" + } + } + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", + "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", + "requires": { + "domelementtype": "1.3.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "end-of-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" + }, + "escape-string-regexp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", + "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=" + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "extsprintf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", + "dev": true + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "1.2.0" + } + }, + "fibers": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/fibers/-/fibers-1.0.15.tgz", + "integrity": "sha1-IvA5yPGLhWGQ+75N7PBWFUwerpw=" + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=" + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, + "getpass": { + "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" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "requires": { + "inherits": "2.0.3", + "minimatch": "0.3.0" + } + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=" + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "dev": true + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.3.0", + "domutils": "1.5.1", + "entities": "1.0.0", + "readable-stream": "1.1.14" + }, + "dependencies": { + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" + } + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "https-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", + "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", + "dev": true, + "requires": { + "agent-base": "2.1.1", + "debug": "2.2.0", + "extend": "3.0.1" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "is-my-json-valid": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", + "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "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 + }, + "jade": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", + "requires": { + "commander": "0.6.1", + "mkdirp": "0.3.0" + }, + "dependencies": { + "commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=" + }, + "mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=" + } + } + }, + "jodid25519": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "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 + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, + "optional": true + } + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "jsprim": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", + "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, + "optional": true + } + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + }, + "mime-db": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", + "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", + "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", + "requires": { + "commander": "2.3.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.2", + "glob": "3.2.11", + "growl": "1.9.2", + "jade": "0.26.3", + "mkdirp": "0.5.1", + "supports-color": "1.2.0", + "to-iso-string": "0.0.2" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + }, + "nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "requires": { + "boolbase": "1.0.0" + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" + }, + "object.assign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz", + "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=", + "requires": { + "define-properties": "1.1.2", + "function-bind": "1.1.0", + "object-keys": "1.0.11" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" + } + }, + "require-dir": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/require-dir/-/require-dir-0.3.2.tgz", + "integrity": "sha1-wdXHXp+//eny5rM+OD209ZS1pqk=" + }, + "rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "dev": true, + "requires": { + "glob": "7.1.2" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", + "dev": true + }, + "sauce-connect-launcher": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-1.2.2.tgz", + "integrity": "sha1-c0bMj73EQxkTI0ObBzNFH181IfI=", + "dev": true, + "requires": { + "adm-zip": "0.4.7", + "async": "0.9.2", + "https-proxy-agent": "1.0.0", + "lodash": "3.10.1", + "rimraf": "2.6.1" + } + }, + "selenium-standalone": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/selenium-standalone/-/selenium-standalone-6.5.0.tgz", + "integrity": "sha1-Xsr/3LFXmf5plU5hQ3kaOL+I39E=", + "dev": true, + "requires": { + "async": "2.5.0", + "commander": "2.11.0", + "cross-spawn": "5.1.0", + "debug": "2.6.8", + "lodash": "4.17.4", + "minimist": "1.2.0", + "mkdirp": "0.5.1", + "progress": "1.1.8", + "request": "2.79.0", + "tar-stream": "1.5.2", + "urijs": "1.18.10", + "which": "1.2.14", + "yauzl": "2.8.0" + }, + "dependencies": { + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "bl": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", + "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.2.14" + } + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.11.0", + "is-my-json-valid": "2.16.0", + "pinkie-promise": "2.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "dev": true + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "qs": "6.3.2", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.4.3", + "uuid": "3.0.1" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tar-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.2.tgz", + "integrity": "sha1-+8bG6DwaGdTLSMfZYXH8JI7/x78=", + "dev": true, + "requires": { + "bl": "1.2.1", + "end-of-stream": "1.4.0", + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true + } + } + }, + "semver": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sshpk": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", + "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", + "dev": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "supports-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=" + }, + "to-iso-string": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", + "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=" + }, + "tough-cookie": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "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" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "type-detect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=" + }, + "urijs": { + "version": "1.18.10", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.18.10.tgz", + "integrity": "sha1-uURj6rpZoaeWA2pGe7YzxmfyIas=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", + "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", + "dev": true + }, + "verror": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "dev": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wdio-mocha-framework": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/wdio-mocha-framework/-/wdio-mocha-framework-0.5.10.tgz", + "integrity": "sha1-0fa1sRKahF8nNnLZsq0MS083y6E=", + "requires": { + "babel-runtime": "6.23.0", + "mocha": "2.5.3", + "wdio-sync": "0.6.14" + } + }, + "wdio-sauce-service": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/wdio-sauce-service/-/wdio-sauce-service-0.4.0.tgz", + "integrity": "sha1-OtXc7e4MXNGRGMooe6meYZgs+kk=", + "dev": true, + "requires": { + "request": "2.81.0", + "sauce-connect-launcher": "1.2.2" + } + }, + "wdio-selenium-standalone-service": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/wdio-selenium-standalone-service/-/wdio-selenium-standalone-service-0.0.9.tgz", + "integrity": "sha1-yA1P9Il0TVoLkdUYl2SRbUwMhWQ=", + "dev": true, + "requires": { + "fs-extra": "0.30.0", + "selenium-standalone": "6.5.0" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + } + } + }, + "wdio-sync": { + "version": "0.6.14", + "resolved": "https://registry.npmjs.org/wdio-sync/-/wdio-sync-0.6.14.tgz", + "integrity": "sha1-odzVkHuh0EFUquYXbGItkQw8qbM=", + "requires": { + "babel-runtime": "6.23.0", + "fibers": "1.0.15", + "object.assign": "4.0.4" + } + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "dev": true, + "requires": { + "buffer-crc32": "0.2.13", + "fd-slicer": "1.0.1" + } + } + } +} diff --git a/open_xdmod/modules/xdmod/automated_tests/package.json b/open_xdmod/modules/xdmod/automated_tests/package.json new file mode 100644 index 0000000000..ca3b41352f --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/package.json @@ -0,0 +1,25 @@ +{ + "name": "selenium-tests", + "version": "1.0.0", + "description": "Selenium Tests for XDMod", + "main": "index.js", + "scripts": { + "test": "wdio wdio.conf.js", + "test-sauce": "wdio wdio-sauce.conf.js" + }, + "author": "Ben Plessinger", + "license": "GPL-3.0", + "dependencies": { + "chai": "^3.4.1", + "cheerio": "^0.19.0", + "mocha": "^2.3.4", + "require-dir": "^0.3.0", + "wdio-mocha-framework": "^0.5.10", + "webdriverio": "^4.8.0" + }, + "repository": "https://github.com/ubccr/xdmod", + "devDependencies": { + "wdio-sauce-service": "^0.4.0", + "wdio-selenium-standalone-service": "0.0.9" + } +} diff --git a/open_xdmod/modules/xdmod/automated_tests/readme.md b/open_xdmod/modules/xdmod/automated_tests/readme.md new file mode 100644 index 0000000000..b8511d32d5 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/readme.md @@ -0,0 +1,126 @@ +# Automated Regression tests for the XDMod Frontend + +Based on [webdriver.io][wd] and [webdriverCSS][wdc] + +## Requirements + +### webdriver.io installed globally + +```bash +npm -g install webdriverio +``` + +or if you want run it from node modules + +```bash +npm install webdriverio +``` + +### webdriverCSS webdriverCSS will need [GraphicsMagick][gm] + +For most up to date instructions follow these [instructions][wdc-reqs] +To install this GraphicsMagick + +#### Mac OS X using [Homebrew](http://mxcl.github.io/homebrew/) + +```sh +brew install graphicsmagick +``` + +#### Ubuntu using apt-get + +```sh +sudo apt-get install graphicsmagick +``` + +#### Windows + +Download and install executables for [GraphicsMagick][gmd]. + +### Selenium + +To run this without the use of a selenium grid (not yet ready) +The recommended way to install selenium is using [selenium standalone][ss] + +### Optional + +[webdriverCSS Admin][wdc-admin] is used to more easily compare screenshots. +There are plans to make a shared instance of this for now it is run locally. + +## Setup + +```bash +npm install +``` + +### wdio.conf.js/wdio-sauce.conf.js + +#### host + +change the baseurl to point to the environment you want it pointed to. + +```javascript +// Set a base URL in order to shorten url command calls. If your url parameter starts +// with "/", the base url gets prepended. +baseUrl: "https://tas-reference-dbs.ccr.xdmod.org", +``` + +#### browser Options + +Change the browser to run the tests in by changing the browserName + +```javascript +capabilities: [{ + //browserName: "firefox", + browserName: "phantomjs", + //This allows phantomjs to use self signed certs + "phantomjs.cli.args": [ + "--ignore-ssl-errors=true", + //"--ssl-protocol=tlsv1", + "--web-security=false", + "--debug=false" + ] +}], +``` +Choose/add another browser to `wdio-sauce.conf.js`, use the [Platform Configurator](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/) and add specifications using the same syntax of the `chr` and `ff` browsers. + +In `mochaOpts`, set the `timeout` to desired time length. + +Set `maxInstances` to the desired number of concurrent tests to run at a time. +*Note:* The XDMoD SauceLabs account allows for a max of 5 concurrent tests at a time. + +If running tests through SauceLabs, enter the correct `key` for the `xdmod-sauce` account. + +#### template.secrets.json + +```bash +cp template.secrets.json .secrets.json +``` + +modify .secrets.json to have correct username, password, and display name for user being tested. + +## Run + +### run tests locally + +```bash +npm test +``` + +### run tests through sauce labs + +```bash +npm run test-sauce +``` + +and see the fun that is automated ui testing. + + + +[wd]: http://webdriver.io/ +[wdc]: https://github.com/webdriverio/webdrivercss +[wdc-reqs]: https://github.com/webdriverio/webdrivercss#install +[ss]: https://github.com/vvo/selenium-standalone +[gm]: http://www.graphicsmagick.org/ +[gmd]: http://www.graphicsmagick.org/download.html +[wdc-admin]: https://github.com/webdriverio/webdrivercss-adminpanel diff --git a/open_xdmod/modules/xdmod/automated_tests/template.secrets.json b/open_xdmod/modules/xdmod/automated_tests/template.secrets.json new file mode 100644 index 0000000000..e68665f906 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/template.secrets.json @@ -0,0 +1,9 @@ +{ + "role": { + "po": { + "username": "USERNAME", + "password": "PASSWORD", + "display": "DISPAY NAME" + } + } +} diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/auth.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/auth.js new file mode 100644 index 0000000000..0151cef6a8 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/helpers/auth.js @@ -0,0 +1,7 @@ +'use strict'; + +var roles = require('./../../.secrets.json').role; + +module.exports = { + roles: roles +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/getScreenshotTitle.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/getScreenshotTitle.js new file mode 100644 index 0000000000..37f1872d24 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/helpers/getScreenshotTitle.js @@ -0,0 +1,16 @@ +/* + * Generate a screenshot name based on the base url and the capabilities + * TODO: Update options to have this configurable instead of assuming + * + * @param {object} browser - the browser object since it has the options + * @param {string} screenshotCategory - element to click on + * + * @returns string + */ +module.exports = function getScreenshotTitle(browser, screenshotCategory) { + return [ + screenshotCategory, + browser.desiredCapabilities.browserName.replace(" ", "."), + browser.options.baseUrl.replace(/https?/, "").replace(/\//g, "").replace(":", "") + ].join("."); +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/handleScreenshots.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/handleScreenshots.js new file mode 100644 index 0000000000..04948f3750 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/helpers/handleScreenshots.js @@ -0,0 +1,19 @@ +/* + * Handle errors from screenshots taken from webdrivercss + * + * @param {object} err - errors + * @param {object} res - results + * + */ +module.exports = function handleScreenshots(err, res ) { + expect(err).to.equal(undefined); + for(var screenshotSection in res){ + if(res.hasOwnProperty(screenshotSection)){ + var thisSection = res[screenshotSection]; + var len = thisSection.length; + while(len--){ + expect(thisSection[len].isWithinMisMatchTolerance).to.equal(true, thisSection[len].message); + } + } + } +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/index.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/index.js new file mode 100644 index 0000000000..f7c749d520 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/helpers/index.js @@ -0,0 +1 @@ +module.exports = require('require-dir')(); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/instructions.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/instructions.js new file mode 100644 index 0000000000..cdfb4279fc --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/helpers/instructions.js @@ -0,0 +1,14 @@ +//TODO: Look into moving these to files... +var sections = { + jobViewer: { + instructions: '
No job is selected for viewing

Please refer to the instructions below:



For more information, please refer to the User Manual
' + }, + metricExplorer: { + instructions: '
No data is available for viewing

Please refer to the instructions below:



For more information, please refer to the User Manual
' + } + }; + //cheerio = require("cheerio"); + +module.exports = function instructions(browser, section, selector) { + expect(browser.getHTML(selector + " .x-grid-empty")).to.equal(sections[section].instructions); +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/metricExplorer.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/metricExplorer.js new file mode 100644 index 0000000000..0466104792 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/helpers/metricExplorer.js @@ -0,0 +1,87 @@ +module.exports = { + tab: "#main_tab_panel__metric_explorer", + metricCatalogEntryByName: function(name) { + return "//div[@id=\"metric_explorer\"]//ul[@class=\"x-tree-root-ct x-tree-arrows\"]//a[@class=\"x-tree-node-anchor\"]//span[contains(text(), \"" + name + "\")]"; + }, + metricCatalogEntryExpanderByName: function(name) { + return "//div[@id=\"metric_explorer\"]//ul[@class=\"x-tree-root-ct x-tree-arrows\"]//span[contains(text(), \"" + name + "\")]/ancestor::li//img[@class=\"x-tree-ec-icon x-tree-elbow-end-plus\"]"; + }, + metricContextEntryByName: function(name) { + return "//div[@class=\"x-menu x-menu-floating x-layer x-menu-nosep\"]//span[contains(text(), \"" + name + "\")]"; + }, + title: "//*[local-name()=\'svg\']/*[local-name()=\'text\' and @class=\'highcharts-title\']/*[local-name()=\'tspan\']", + contextMenuItemByText: function(text) { + return "//div[@class=\"x-menu x-menu-floating x-layer x-menu-nosep\"]//span[contains(text(), \"" + text + "\")]"; + }, + resizableWindowByTitle: function(title) { + return "//div[contains(@class, \"x-window\") and contains(@class, \"x-resizable-pinned\") and contains(@style, \"visibility: visible\")]//span[@class=\"x-window-header-text\" and text()[contains(.,\"" + title + "\")]]"; + }, + rawDataEntryByIndex: function(index) { + index = index !== undefined ? index : 1; + return "(//div[contains(@class, 'x-window') and contains(@style, 'visibility: visible')]//div[contains(@class, 'x-grid3-body')]//div[contains(@class, 'x-grid3-cell-inner') and contains(@class, 'x-grid3-col-local_job_id')])[" + index + "]"; + }, + startDate: "#metric_explorer input[id^=start_field_ext]", + endDate: "#metric_explorer input[id^=end_field_ext]", + container: "#metric_explorer", + load: { + button: function meLoadButtonId() { + return "button=Load Chart"; + }, + firstSaved: ".x-menu-floating:not(.x-hide-offsets) .x-grid3-body .x-grid3-row-first", + // This will return the id for the chart number specified in a zero based manner. + // This does not take into account the selected item + chartNum: function meChartByIndex(number) { + number = number + 1; + return ".x-menu-floating:not(.x-hide-offsets) .x-grid3-body > div:nth-child(" + number + ")"; + } + }, + addData: { + button: ".x-btn-text.add_data", + secondLevel: ".x-menu-floating:not(.x-hide-offsets):not(.x-menu-nosep)" + }, + data: { + button: "button=Data", + container: "", + modal: { + updateButton: "button=Update", + groupBy: { + input: "input[name=dimension]" + } + } + }, + deleteChart: "", + undo: function meUndoButtonId() { + return "#" + $container("button.x-btn-text-icon") + .closest("table") + .attr("id"); + }, + options: { + aggregate: "#aggregate_cb", + button: "#metric_explorer button.chartoptions", + trendLine: "#me_trend_line", + swap: "#me_chart_swap_xy", + title: "div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*=\"visibility: visible\"] #me_chart_title" + }, + chart: { + svg: "#metric_explorer > div > .x-panel-body-noborder > .x-panel-noborder svg", + title: "#hc-panelmetric_explorer svg .undefinedtitle", + titleInput: "div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*=\"visibility: visible\"] input[type=text]", + titleOkButton: "div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*=\"visibility: visible\"] table.x-btn.x-btn-noicon.x-box-item:first-child button", + titleCancelButton: "div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*=\"visibility: visible\"] table.x-btn.x-btn-noicon.x-box-item:last-child button", + contextMenu: { + container: "#metric-explorer-chartoptions-context-menu", + legend: "#metric-explorer-chartoptions-legend", + addData: "#metric-explorer-chartoptions-add-data", + addFilter: "#metric-explorer-chartoptions-add-filter" + + }, + axis: "#metric_explorer .highcharts-xaxis-labels" + }, + catalog: { + container: "#metric_explorer > div > .x-panel-body-noborder > .x-border-panel:not(.x-panel-noborder)", + tree: "#metric_explorer > div > .x-panel-body-noborder > .x-border-panel:not(.x-panel-noborder) .x-tree-root-ct" + }, + buttonMenu: { + firstLevel: ".x-menu-floating:not(.x-hide-offsets)" + } +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.js new file mode 100644 index 0000000000..c2a660d628 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.js @@ -0,0 +1,101 @@ +var logIn = require('./loginPage.page.js'); +var loginName = testHelpers.auth.roles.po.username; +var loginPassword = testHelpers.auth.roles.po.password; +var displayName = testHelpers.auth.roles.po.display; +var Abt = require('./about.page.js'); + +describe('About', function about() { + logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); + describe('Logged In Test', function loggedInTests() { + it('Verify About is the Last Tab', function aboutIsTheLastTab() { + browser.waitForVisible(Abt.tab, 30000); + expect(browser.getText(Abt.last_tab)).to.equal('About'); + }); + + it('Select Tab', function selectTab() { + browser.waitForLoadedThenClick(Abt.tab, 50000); + browser.waitForVisible(Abt.container, 20000); + }); + describe('Check Nav Entries', function checkNavEntries() { + it('XDMoD', function checkNavEntryXDMoD() { + Abt.checkTab('XDMoD'); + }); + it('Open XDMoD', function checkNavEntryXDMoD() { + Abt.checkTab('Open XDMoD'); + }); + it('SUPReMM', function checkNavEntrySUPReMM() { + Abt.checkTab('SUPReMM'); + }); + it('Roadmap', function checkNavEntryXDMoD() { + Abt.checkRoadmap(); + }); + it('Team', function checkNavEntryXDMoD() { + Abt.checkTab('Team'); + }); + it('Publications', function checkNavEntryXDMoD() { + Abt.checkTab('Publications'); + }); + it('Presentations', function checkNavEntryXDMoD() { + Abt.checkTab('Presentations'); + }); + it('Links', function checkNavEntryXDMoD() { + Abt.checkTab('Links'); + }); + it('Release Notes', function checkNavEntryXDMoD() { + Abt.checkTab('Release Notes'); + }); + }); + }); + + describe('Logged Out Tests', function loggedInTests() { + it('Click the logout link', function clickLogout() { + browser.waitForLoadedThenClick('#logout_link', 50000); + }); + it('Display Logged out State', function clickLogout() { + browser.waitUntilNotExist('.ext-el-mask-msg'); + $('a[href*=actionLogin]').waitForExist(); + }); + + it('Verify About is the Last Tab', function aboutIsTheLastTab() { + browser.waitForVisible(Abt.tab, 30000); + expect(browser.getText(Abt.last_tab)).to.equal('About'); + }); + + it('Select Tab', function selectTab() { + browser.waitForLoadedThenClick(Abt.tab, 50000); + browser.waitForVisible(Abt.container, 20000); + }); + describe('Check Nav Entries', function checkNavEntries() { + it('XDMoD', function checkNavEntryXDMoD() { + Abt.checkTab('XDMoD'); + }); + it('Open XDMoD', function checkNavEntryXDMoD() { + Abt.checkTab('Open XDMoD'); + }); + it('SUPReMM', function checkNavEntrySUPReMM() { + Abt.checkTab('SUPReMM'); + }); + it('Roadmap', function checkNavEntryXDMoD() { + Abt.checkRoadmap(); + }); + it('Team', function checkNavEntryXDMoD() { + Abt.checkTab('Team'); + }); + it('Publications', function checkNavEntryXDMoD() { + Abt.checkTab('Publications'); + }); + it('Presentations', function checkNavEntryXDMoD() { + Abt.checkTab('Presentations'); + }); + it('Links', function checkNavEntryXDMoD() { + Abt.checkTab('Links'); + }); + it('Release Notes', function checkNavEntryXDMoD() { + Abt.checkTab('Release Notes'); + }); + }); + }); + logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); + logIn.logout(); +}); + diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.page.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.page.js new file mode 100644 index 0000000000..f5650a265b --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.page.js @@ -0,0 +1,33 @@ +class About { + constructor() { + this.tab = '//ul[contains(@class, "x-tab-strip")]//span[text()="About"]'; + this.container = '//div[@id="about_xdmod"]'; + this.center = '//div[@id="about_xdmod"]//div[contains(@class, "x-panel-body") and contains(@class, "x-border-layout-ct")]/div[contains(@class,"x-panel") and contains(@class,"x-panel-reset") and contains(@class,"x-border-panel")]'; + this.last_tab = '//ul[contains(@class, "x-tab-strip")]//li[contains(@class, "tab-strip")][last()]'; + } + + navEntry(name) { + return '//div[@class="x-tree-root-node"]//div[contains(@class,"x-tree-node-el")]//span[contains(text(),"' + name + '")]'; + } + + checkTab(name) { + browser.waitForLoadedThenClick(this.navEntry(name), 50000); + $(this.container).waitForText(50000); + // browser.takeScreenshot(name.replace(' ',''), this.center, "xdmod"); + } + + checkRoadmap() { + browser.waitForLoadedThenClick(this.navEntry('Roadmap')); + browser.pause(20000); + browser.waitForExist('iframe#about_roadmap', 30000); + browser.frame('about_roadmap', function (err, result) { + expect(err).to.be.a('undefined'); + expect(result).to.not.be.a('null'); + }); + browser.waitForExist('.trello-lists', 30000); + browser.waitForText('.trello-lists', 30000); + browser.frameParent(); + } + +} +module.exports = new About(); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/loginPage.page.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/loginPage.page.js new file mode 100644 index 0000000000..0394214664 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/loginPage.page.js @@ -0,0 +1,53 @@ +class LoginPage { + login(title, theUrl, loginName, loginPassword, displayName) { + describe('General', function () { + it('Verify Logo and Title', function () { + browser.url(theUrl); + expect(browser.getTitle()).to.equal(title); + // $(this.logo).waitForVisible(2000); + $('#logo').waitForVisible(2000); + var logoSize = browser.getElementSize('#logo'); + expect(logoSize.width).to.equal(93); + expect(logoSize.height).to.equal(32); + }); + }); + describe('Login', function login() { + it('Click the login link', function clickLogin() { + browser.waitUntilNotExist('.ext-el-mask-msg'); + $('a[href*=actionLogin]').click(); + }); + it('Should Login', function doLogin() { + $('.x-window-header-text=Welcome To XDMoD').waitForExist(20000); + $('#wnd_login iframe').waitForExist(20000); + browser.frame($('#wnd_login iframe').value); + $('#txt_login_username input').setValue(loginName); + $('#txt_login_password input').setValue(loginPassword); + $('#btn_sign_in .x-btn-mc').click(); + }); + it('Display Logged in Users Name', function () { + $('#welcome_message').waitForExist(60000); + expect($('#welcome_message').getText()).to.equal(displayName); + }); + }); + } + logout() { + describe('Logout', function logout() { + it('Click the logout link', function clickLogout() { + browser.pause(1000); + $('#logout_link').waitForVisible(); + $('#logout_link').click(); + }); + it('Display Logged out State', function clickLogout() { + browser.waitUntilNotExist('.ext-el-mask-msg'); + $('a[href*=actionLogin]').waitForExist(); + }); + }); +/* + describe("Update Screenshot Repository", function screenshots() { + it("Should upload screenshots", function screenshotsSync() { + //return browser.sync(); + }); + });*/ + } +} +module.exports = new LoginPage(); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.js new file mode 100644 index 0000000000..6c79d77c0a --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.js @@ -0,0 +1,38 @@ +var logIn = require('./loginPage.page.js'); +var loginName = testHelpers.auth.roles.po.username; +var loginPassword = testHelpers.auth.roles.po.password; +var displayName = testHelpers.auth.roles.po.display; +var mTb = require('./mainToolbar.page.js'); +var mainTab; + +describe('Main Toolbar', function () { + logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); + describe('Check Tab', function xdmod() { + it('Get Browser Tab ID', function () { + mainTab = browser.getCurrentTabId(); + }); + it("About should change 'Tabs'", function () { + mTb.checkAbout(); + }); + }); + describe('Contact Us', function () { + for (var type in mTb.contactTypes) { + if (mTb.contactTypes.hasOwnProperty(type)) { + it(type, function () { + mTb.contactFunc(type); + }); + } + } + }); + describe('Help', function () { + for (var type in mTb.helpTypes) { + if (mTb.helpTypes.hasOwnProperty(type)) { + it(type, function () { + mTb.helpFunc(type, mainTab); + browser.pause(1500); + }); + } + } + }); + logIn.logout(); +}); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.page.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.page.js new file mode 100644 index 0000000000..a34803d0b3 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.page.js @@ -0,0 +1,57 @@ +class MainToolbar { + constructor() { + this.helpTypes = { + Manual: '#global-toolbar-help-user-manual', + 'You Tube': '#global-toolbar-help-youtube' + }; + this.contactTypes = { + 'Submit Support Request': '#global-toolbar-contact-us-submit-support-request', + 'Send Message': '#global-toolbar-contact-us-send-message', + 'Request Feature': '#global-toolbar-contact-us-request-feature' + }; + this.toolbarClose = '.x-window .x-tool-close'; + this.toolbarAbout = '#global-toolbar-about'; + this.contactus = '#global-toolbar-contact-us'; + this.help = '#help_button'; + this.about = '#about_xdmod'; + this.container = '.x-window'; + this.header = '.x-window .x-window-header .x-window-header-text'; + this.floatlayer = 'div.x-menu.x-menu-floating.x-layer'; + this.note = '.x-window.x-notification'; + } + helpFunc(type, mainTab) { + $(this.help).click(); + browser.waitForExist(this.floatlayer); + browser.waitForExist(this.helpTypes[type]); + browser.click(this.helpTypes[type]); + var ids = browser.windowHandles().value; + var id = ids.length; + expect(id).to.equal(2); + while (id--) { + if (ids[id] !== mainTab) { + browser.window(ids[id]); + browser.close(); + } + } + browser.window(mainTab); + } + contactFunc(type) { + browser.waitUntilNotExist(this.note); + $(this.contactus).click(); + browser.waitForExist(this.floatlayer); + browser.waitForExist(this.contactTypes[type]); + browser.click(this.contactTypes[type]); + browser.waitForExist(this.container); + expect(browser.getText(this.header)).to.be.equal(type); + browser.pause(500); + browser.waitForExist(this.toolbarClose); + browser.click(this.toolbarClose); + } + checkAbout() { + browser.waitForExist(this.toolbarAbout); + browser.pause(5000); + browser.click(this.toolbarAbout); + browser.waitForExist(this.about); + } +} +module.exports = new MainToolbar(); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.js new file mode 100644 index 0000000000..0a1cf6c023 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.js @@ -0,0 +1,451 @@ +var logIn = require('./loginPage.page.js'); +var me = require('./metricExplorer.page.js'); +var cheerio = require('cheerio'); +describe('Metric Explorer', function metricExplorer() { + var baselineDate = { + start: '2016-12-22', + end: '2017-01-01' + }; + var $container; + var actions = { + chart: { + load: function (chartNumber) { + var mychartNumber = chartNumber || 0; + it('Load Chart', function () { + me.actionLoadChart(mychartNumber); + }); + }, + contextMenu: { + open: function chartContextMenuOpen() { + it('Open Chart Context Menu', function () { + // TODO: Find a better way to open this. Currently there is a chance + // that the click will open the dataseries menu + browser.waitAndClick('#hc-panelmetric_explorer', 10000); + }); + }, + addData: function () { + it('Should Display', function () { + browser.waitAndClick('#hc-panelmetric_explorer', 10000); + browser.waitAndClick(me.selectors.chart.contextMenu.addData, 10000); + browser.waitForVisible('#metric-explorer-chartoptions-add-data-menu', 10000); + browser.click('#logo'); + }); + }, + addFilter: function () { + it('Should Display', function () { + browser.waitAndClick('#hc-panelmetric_explorer', 10000); + browser.waitAndClick(me.selectors.chart.contextMenu.addFilter, 10000); + browser.waitForVisible('#metric-explorer-chartoptions-add-filter-menu', 10000); + browser.click('#logo'); + }); + }, + legend: function () { + it('Click Legend', function selectLegend() { + browser.waitAndClick(me.selectors.chart.contextMenu.legend, 10000); + }); + }, + setLegendPosition: function chartContextMenuLegendPosition(position) { + describe('Set Legend ' + position, function setLegend() { + actions.chart.contextMenu.open(); + actions.chart.contextMenu.legend(); + it('Click ' + position, function selectLegendPosition() { + var posId = me.selectors.chart.contextMenu.legend + '-' + + position.toLowerCase().replace(/ /g, '-'); + browser.waitAndClick(posId); + browser.waitForChart(); + }); + }); + } + } + } + }; + var loginName = testHelpers.auth.roles.po.username; + var loginPassword = testHelpers.auth.roles.po.password; + var displayName = testHelpers.auth.roles.po.display; + logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); + describe('Select Tab', function xdmod() { + it('Selected', function meSelect() { + browser.waitForLoadedThenClick(me.selectors.tab); + browser.waitForVisible(me.selectors.container, 3000); + $container = cheerio.load(browser.getHTML(me.selectors.container)); + }); + }); + describe('Basic Scenarios', function basicScenarios() { + it('Has Instructions', function meConfirmInstructions() { + testHelpers.instructions(browser, 'metricExplorer', me.selectors.container); + }); + it('Instructions look the same as previous run', function () { + browser.waitForVisible(me.selectors.catalog.container, 10000); + // browser.takeScreenshot(moduleName, me.selectors.container, "instructions") + }); + it('Has three toolbars', function meConfirmToolbars() { + expect($container('.x-toolbar').length).to.equal(3); + }); + it('Has one canned Date Picker', function meConfirmDatePicker() { + // TODO: Make Datepicker have a unique name + expect($container('table[id^=canned_dates]').length).to.equal(1); + }); + + it('Set a known start date', function meSetStartEnd() { + browser.waitForVisible(me.selectors.startDate, 10000); + browser.click(me.selectors.startDate); + browser.setValue(me.selectors.startDate, baselineDate.start); + }); + + it('Set a known end date', function meSetStartEnd() { + browser.waitForVisible(me.selectors.endDate, 10000); + browser.click(me.selectors.endDate); + browser.setValue(me.selectors.endDate, baselineDate.end); + }); + it("'Add Data' via toolbar", function meAddData1() { + // click on CPU Hours: Total + me.addDataViaMenu('.ext-el-mask-msg', '3'); + browser.waitAndClick('#adp_submit_button'); + }); + it('Scratchpad looks the same as previous run', function () { + browser.waitForChart(); + // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.01.source") + browser.pause(5000); + }); + + it("'Add Data' again via toolbar", function meAddData2() { + me.addDataViaToolbar(); + }); + it('Chart looks the same as previous run', function () { + browser.waitForChart(); + // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.02.sources") + }); + it('Switch to aggregate chart (expect incompatible metric error)', function () { + me.switchToAggregate(); + // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.02.aggregate") + }); + it('Undo Scratch Pad switch to aggregate', function () { + me.undoAggregateOrTrendLine($container); + }); + it('Chart looks the same as previous run', function () { + browser.waitForChart(); + // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.undo.02.aggregate") + browser.pause(3000); + }); + it('Undo Scratch Pad second source', function meUndoScratchPad() { + browser.waitAndClick(me.undo($container)); + // The mouse stays and causes a hover, lets move the mouse somewhere else + browser.waitAndClick('.xtb-text.logo93'); + }); + it('Chart looks the same as previous run', function () { + // browser.waitForChart(); + // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.undo.02.source") + browser.pause(3000); + }); + /* + it("Swap the X and Y axis", function(){ + me.axisSwap() + }); + */ + it('Attempt Delete Scratchpad Chart', function meDeleteScratchPad() { + me.attemptDeleteScratchpad(cheerio); + }); + it('Chart looks the same as previous run', function () { + // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.delete.confirm") + browser.pause(1000); + }); + it('Delete Scratchpad Chart', function meValidateDeletedScratchPad() { + browser.waitAndClick(me.selectors.deleteChart); + }); + it('Chart looks the same as previous run', function () { + // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.delete.complete") + browser.pause(1000); + }); + it('Open load chart dialog', function meLoadChart() { + browser.click(me.selectors.load.button()); + }); + it('Load chart dialog looks the same as previous run', function () { + // browser.takeScreenshot(moduleName, me.selectors.container, "load.dialog") + browser.pause(1000); + }); + it('Open chart from load dialog', function meOpenChart() { + // TODO: Need to make sure to select the same chart every time, not just the first for screenshots + browser.waitAndClick(me.selectors.load.chartNum(0)); + browser.waitForChart(); + }); + it('Loaded chart looks the same as previous run', function () { + // browser.takeScreenshot(moduleName, me.selectors.container, "load.chart") + browser.pause(1000); + }); + it('Open Chart Options', function meChartOptions() { + browser.waitAndClick(me.selectors.options.button); + }); + it('Chart options looks the same as previous run', function () { + // browser.takeScreenshot(moduleName, me.selectors.container, "chart.options") + browser.pause(1000); + }); + it('Show Trend Line via Chart Options', function meAddTrendLine() { + browser.waitAndClick(me.selectors.options.trendLine); + browser.waitAndClick(me.selectors.options.button); + }); + it('Trend Line looks the same as previous run', function () { + browser.waitForChart(); + // browser.takeScreenshot(moduleName, me.selectors.container, "chart.trendline") + browser.pause(3000); + }); + it('Undo Trend Line', function meUndoTrendLine() { + me.undoAggregateOrTrendLine($container); + browser.waitForChart(); + }); + it('Undo Trend Line looks the same as previous run', function () { + // browser.takeScreenshot(moduleName, me.selectors.container, "saved.chart.undo.trendline") + browser.pause(2000); + }); + }); + describe('Context Menu', function contextMenu() { + it('Start with scratchpad', function () { + browser.refresh(); + browser.pause(10000); + me.clear(); + browser.pause(2000); + }); + + it('Attempt Delete Scratchpad Chart', function meDeleteScratchPad() { + me.attemptDeleteScratchpad(cheerio); + }); + it('Delete Scratchpad Chart', function meValidateDeletedScratchPad() { + browser.waitAndClick(me.selectors.deleteChart); + }); + + it('Set a known start date', function meSetStartEnd() { + browser.waitForVisible('#metric_explorer input[id^=start_field_ext]', 10000); + browser.setValue('#metric_explorer input[id^=start_field_ext]', baselineDate.start); + }); + + it('Set a known end date', function meSetStartEnd() { + browser.waitForVisible('#metric_explorer input[id^=end_field_ext]', 10000); + browser.setValue('#metric_explorer input[id^=end_field_ext]', baselineDate.end); + }); + + it('Wait For Metric Catalog', function () { + browser.pause(3000); + browser.waitUntilNotExist('.ext-el-mask-msg'); + browser.waitForVisible(me.selectors.catalog.container, 10000); + }); + it('Generic Starting Point', function () { + me.genericStartingPoint(); + }); + + describe('Add Data Menu', function () { + actions.chart.contextMenu.addData(); + actions.chart.contextMenu.addData(); + }); + describe('Add Filter Menu', function () { + actions.chart.contextMenu.addFilter(); + actions.chart.contextMenu.addFilter(); + }); + describe('Legend Menus', function () { + actions.chart.contextMenu.setLegendPosition('Top Left'); + actions.chart.contextMenu.setLegendPosition('Top Right'); + browser.pause(5000); + describe('Verify after load', function () { + actions.chart.load(1); + actions.chart.contextMenu.open(); + actions.chart.contextMenu.legend(); + it('legend Items set Properly', function () { + browser.waitForVisible('#metric-explorer-chartoptions-legend-options .x-menu-item-checked', 2000); + var legendText = browser.getText('#metric-explorer-chartoptions-legend-options .x-menu-item-checked'); + // TODO: figure out why the line above was written and why it fails + expect(legendText).to.equal('Bottom Center (Default)', 'Loaded chart has non default legend'); + }); + }); + }); + }); + describe('Pie Charts', function pieCharts() { + describe("Can't use timeseries data", function noTimeSeries() { + it('Start with scratchpad', function () { + me.clear(); + }); + it("Add Data via the 'Add Data' Menu", function addData() { + // 'Add Data' via the 'Add Data' menu: + // 'Add Data' -> Jobs -> CPU Hours: Total -> 'Add' + // wait for the global mask to disapear + me.addDataViaMenu('.ext-el-mask-msg', '2'); + }); + it("Set 'Group By' to resource", function findGroupBy() { + me.setGroupByToResource(); + }); + it("'Add' data", function add() { + browser.waitAndClick('#adp_submit_button'); + browser.waitUntilNotExist('.ext-el-mask'); + }); + it('Verify that the chart has been rendered', function chartRendered() { + // Attempt to ascertain if the HighChartPanel ( the panel that contains the chart contents ) is hidden or not. + // Pause so we can determine if the chart was actually loaded. + browser.waitForVisible('#hc-panelmetric_explorer', 3000); + // If the chart was successfully loaded / rendered this should return false. + var execReturn = browser.execute('return CCR.xdmod.ui.metricExplorer.chartViewPanel.items.get(0).hidden;').value; + expect(execReturn).to.equal(false); + }); + it('Chart looks the same as previous run', function () { + // browser.takeScreenshot(moduleName, me.selectors.container, "pie.loaded"); + }); + it("Select the 'Data' toolbar button", function selectData() { + browser.click(me.selectors.data.button); + }); + it('Click the First Row', function jobsRow() { + browser.waitForVisible('.x-menu-floating:not(.x-hide-offsets)'); + browser.execute('return CCR.xdmod.ui.metricExplorer.datasetsGridPanel.getView().getRow(0)').doubleClick(); + }); + it("Set 'Display Type' to 'Pie'", function clickDisplayType() { + me.setToPie(); + }); + it('Verify error message', function checkErrorMessage() { + me.verifyError(); + }); + }); + describe('Aggregate data', function useAggregateData() { + it('Start with scratchpad', function freshChart() { + me.clear(); + }); + }); // Aggregate data + }); // Pie Charts + describe('Chart Interactions', function chartInteractions() { + it('Should start with a new chart', function newChart() { + me.clear(); + }); + describe('Should start start with a dataset', function dataset() { + it("Add Data via the 'Add Data' Menu", function addData() { + // 'Add Data' via the 'Add Data' menu: + // 'Add Data' -> Jobs -> CPU Hours: Total -> 'Add' + // wait for the global mask to disapear + me.addDataViaMenu('div.x-panel.x-masked-relative.x-masked', '2'); + }); + it("Set 'Group By' to resource", function findGroupBy() { + me.setGroupByToResource(); + }); + it("'Add' data", function add() { + browser.waitAndClick('#adp_submit_button'); + browser.waitUntilNotExist('.ext-el-mask'); + }); + it('Verify that the chart has been rendered', function chartRendered() { + // Attempt to ascertain if the HighChartPanel ( the panel that contains the chart contents ) is hidden or not. + // Pause so we can determine if the chart was actually loaded. + browser.waitForChart(); + browser.pause(750); + // If the chart was successfully loaded / rendered this should return false. + var execReturn = browser.execute('return CCR.xdmod.ui.metricExplorer.chartViewPanel.items.get(0).hidden;'); + expect(execReturn.value).to.equal(false); + }); + it('Chart looks the same as previous run', function () { + // browser.takeScreenshot(moduleName, me.selectors.container, "highcharts.loaded") + }); + }); // Should start with a dataset. + + describe('Chart Titles', function chartTitle() { + describe('Update the Chart Title with a value that contains html entities', function editChartTitleDialog() { + it('Click the Chart Title element', function clickChartTitleElement() { + browser.waitAndClick(me.selectors.chart.title); + browser.waitForVisible(me.selectors.chart.titleInput, 3000); + }); + + it('Update the Chart Title input element', function editChartTitle() { + browser.pause(2000); + browser.clearElement(me.selectors.chart.titleInput); + browser.setValue(me.selectors.chart.titleInput, me.newTitle); + }); + + it('Click the Ok element', function clickOkElement() { + browser.pause(2000); + browser.waitAndClick(me.selectors.chart.titleOkButton); + }); + + it('Chart Title element should be updated', function checkChartTitle() { + browser.pause(2500); + me.verifyHighChartsTitle(me.newTitle); + }); + + it('Chart Title in Chart Options should be updated', function verifyChartOptions() { + me.chartTitleInOptionsUpdated(); + }); + }); + + describe('Set the title to a value that does not include html entities', function noHtmlEntities() { + it('click the Chart Title', function clickChartTitle() { + browser.waitForVisible(me.selectors.chart.title, 3000); + browser.click(me.selectors.chart.title); + browser.waitForVisible(me.selectors.chart.titleInput, 3000); + }); + + it('clear the title field', function clearTitleField() { + browser.clearElement(me.selectors.chart.titleInput); + }); + + it('set the title field to a value that does not contain html entities.', function setWithNoEntities() { + browser.pause(500); + browser.setValue(me.selectors.chart.titleInput, me.originalTitle); + browser.pause(2000); + }); + + it("click 'ok' to confirm the change", function confirmTheChange() { + browser.click(me.selectors.chart.titleOkButton); + browser.waitForVisible(me.selectors.chart.title, 3000); + }); + + it('get the new value from the chart title to verify that it has in fact changed', function checkNewValue() { + browser.pause(500); + var execReturn = browser.execute('return document.querySelector("' + me.selectors.chart.title + '").textContent;'); + expect(execReturn.value).to.be.a('string'); + expect(execReturn.value).to.equal(me.originalTitle); + }); + }); + + describe('Arrow Keys', function () { + it('Arrow keys can be used in chart options title', function () { + me.arrowKeys(); + }); + }); + describe('Accept html entity input via the Chart Options -> Chart Title element.', function editChartTitleChartOptions() { + it('set the Chart Options -> Chart Title value with html entities', function setTitleWithHtmlEntities() { + browser.pause(2000); + me.setTitleWithOptionsMenu(me.newTitle); + browser.pause(2000); + }); + it('click the Chart Options button again', function clickChartOptions() { + browser.waitForChart(); + browser.waitAndClick(me.selectors.options.button); + browser.waitForChart(); + browser.pause(3000); + }); + it('verify that the HighCharts chart title has the new value', function highChartsTitle() { + me.verifyHighChartsTitle(me.newTitle); + }); + it('verify that the Edit Chart Title Modal has the new value', function chartTitleModal() { + me.verifyEditChartTitle(); + }); + }); + + describe('Providing an empty title value', function shouldAcceptEmptyTitle() { + it('Set the chart title to an empty value', function setTitleEmpty() { + me.setChartTitleViaChart(''); + }); + + it('Get the new chart title and confirm that no svg element was generated', function confirmEmptyChartTitle() { + browser.pause(500); + var titleChange = browser.execute('return document.querySelector("' + me.selectors.chart.title + '");'); + // expect(titleChange.state).to.equal('success'); + expect(titleChange._status).to.equal(0); + expect(titleChange.value).to.equal(null); + }); + }); + + describe('Providing an exceptionally large title should be ok', function shouldNotAcceptLargeTitle() { + var largeTitle = me.generateTitle(900); + it('Set the chart title to an exceptionally large value (' + largeTitle.length + ')', function setALargeTitle() { + me.setTitleWithOptionsMenu(largeTitle); + browser.waitAndClick(me.selectors.options.button); + }); + + it('Confirm that the chart title has been changed', function confirmTheTitleWasSet() { + me.confirmChartTitleChange(largeTitle); + }); + }); + }); + }); + logIn.logout(); +}); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.page.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.page.js new file mode 100644 index 0000000000..bc497e3afb --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.page.js @@ -0,0 +1,266 @@ +class MetricExplorer { + constructor() { + this.meselectors = testHelpers.metricExplorer; + this.originalTitle = '(untitled query 2)'; + this.newTitle = '"& (untitled query) 2 &"'; + this.possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + this.selectors = { + tab: '#main_tab_panel__metric_explorer', + startDate: '#metric_explorer input[id^=start_field_ext]', + endDate: '#metric_explorer input[id^=end_field_ext]', + container: '#metric_explorer', + load: { + button: function meLoadButtonId() { + return 'button=Load Chart'; + }, + firstSaved: '.x-menu-floating:not(.x-hide-offsets) .x-grid3-body .x-grid3-row-first', + chartNum: function meChartByIndex(number) { + var mynumber = number + 1; + return '.x-menu-floating:not(.x-hide-offsets) .x-grid3-body > div:nth-child(' + mynumber + ')'; + } + }, + addData: { + button: '.x-btn-text.add_data', + secondLevel: '.x-menu-floating:not(.x-hide-offsets):not(.x-menu-nosep)' + }, + data: { + button: 'button=Data', + container: '', + modal: { + updateButton: 'button=Update', + groupBy: { + input: 'input[name=dimension]' + } + } + }, + deleteChart: '', + options: { + aggregate: '#aggregate_cb', + button: '#metric_explorer button.chartoptions', + trendLine: '#me_trend_line', + swap: '#me_chart_swap_xy', + title: 'div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*="visibility: visible"] #me_chart_title' + }, + chart: { + svg: '#metric_explorer > div > .x-panel-body-noborder > .x-panel-noborder svg', + title: '#hc-panelmetric_explorer svg .undefinedtitle', + titleInput: 'div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*="visibility: visible"] input[type=text]', + titleOkButton: 'div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*="visibility: visible"] table.x-btn.x-btn-noicon.x-box-item:first-child button', + titleCancelButton: 'div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*="visibility: visible"] table.x-btn.x-btn-noicon.x-box-item:last-child button', + contextMenu: { + container: '#metric-explorer-chartoptions-context-menu', + legend: '#metric-explorer-chartoptions-legend', + addData: '#metric-explorer-chartoptions-add-data', + addFilter: '#metric-explorer-chartoptions-add-filter' + + }, + axis: '#metric_explorer .highcharts-yaxis-labels' + }, + catalog: { + container: '#metric_explorer > div > .x-panel-body-noborder > .x-border-panel:not(.x-panel-noborder)', + tree: '#metric_explorer > div > .x-panel-body-noborder > .x-border-panel:not(.x-panel-noborder) .x-tree-root-ct' + }, + buttonMenu: { + firstLevel: '.x-menu-floating:not(.x-hide-offsets)' + } + }; + } + undo($container) { + return '#' + $container('button.x-btn-text-icon') + .closest('table') + .attr('id'); + } + clear() { + browser.refresh(); + browser.waitForVisible('#logout_link', 3000); + // expect(browser.isVisible("#metric_explorer .x-grid-empty")).to.equal(false, "Empty chart not visible"); + } + generateTitle(size) { + var result = ''; + for (var i = 0; i < size; i++) { + result += this.possible.charAt(Math.floor(Math.random() * this.possible.length)); + } + return result; + } + setToPie() { + browser.execute("return document.getElementsByName('display_type')[0];").click(); + browser.execute("return document.querySelector('div.x-layer.x-combo-list[style*=\"visibility: visible\"] div.x-combo-list-inner div.x-combo-list-item:last-child');").click(); + } + + verifyError() { + var invalidChart = browser.execute("return document.querySelectorAll('div.x-window.x-window-plain.x-window-dlg[style*=\"visibility: visible\"] span.x-window-header-text')[0];").getText(); + expect(invalidChart).to.equal('Invalid Chart Display Type'); + var errorText = browser.execute("return document.querySelectorAll('div.x-window.x-window-plain.x-window-dlg[style*=\"visibility: visible\"] span.ext-mb-text')[0];").getText(); + expect(errorText).to.contain('You cannot display timeseries data in a pie chart.'); + expect(errorText).to.contain('Please change the dataset or display type.'); + } + + arrowKeys() { + browser.waitForChart(); + browser.waitForLoadedThenClick(this.selectors.options.button); + browser.waitForLoadedThenClick(this.selectors.options.title); + var cursorPosition = browser.execute('return document.getElementById("me_chart_title").selectionStart;'); + // expect(cursorPosition.state).to.equal("success"); + expect(cursorPosition._status).to.equal(0); + expect(cursorPosition.value).to.equal(this.originalTitle.length, 'Cursor Position not at end'); + browser.keys('Arrow_Up'); + var newPosition = browser.execute('return document.getElementById("me_chart_title").selectionStart;'); + // expect(newPosition.state).to.equal("success"); + expect(newPosition._status).to.equal(0); + expect(newPosition.value).to.equal(0, 'Cursor Position not at begining'); + browser.waitAndClick(this.selectors.options.button); + } + addDataViaMenu(maskName, n) { + browser.waitUntilNotExist(maskName); + browser.waitForVisible(this.selectors.catalog.container, 5000); + browser.waitAndClick(this.selectors.addData.button); + browser.waitAndClick(this.selectors.buttonMenu.firstLevel + ' ul li:nth-child(3)'); + browser.waitAndClick(this.selectors.addData.secondLevel + ' ul li:nth-child(' + n + ')'); + } + setTitleWithOptionsMenu(title) { + browser.waitForChart(); + browser.waitAndClick(this.selectors.options.button); + browser.waitForVisible(this.selectors.options.title, 5000); + browser.clearElement(this.selectors.options.title); + browser.pause(500); + browser.setValue(this.selectors.options.title, title); + } + verifyHighChartsTitle(title) { + var execReturn = browser.execute('return Ext.util.Format.htmlDecode(document.querySelector("' + this.selectors.chart.title + '").textContent);'); + expect(execReturn._status).to.equal(0); + expect(execReturn.value).to.be.a('string'); + expect(execReturn.value).to.equal(title); + } + verifyEditChartTitle() { + browser.waitAndClick(this.selectors.chart.title); + browser.waitForVisible(this.selectors.chart.titleInput); + var titleValue = browser.getValue(this.selectors.chart.titleInput); + expect(titleValue).to.be.a('string'); + expect(titleValue).to.equal(this.newTitle); + browser.waitAndClick(this.selectors.chart.titleOkButton); + browser.waitForChart(); + } + setChartTitleViaChart(title) { + browser.waitForChart(); + browser.waitAndClick(this.selectors.chart.title); + browser.waitForVisible(this.selectors.chart.titleInput); + browser.clearElement(this.selectors.chart.titleInput); + browser.setValue(this.selectors.chart.titleInput, title); + browser.pause(500); + browser.waitAndClick(this.selectors.chart.titleOkButton); + } + setGroupByToResource() { + browser.click(this.selectors.data.modal.groupBy.input); + browser.pause(1000); + browser.execute("return document.querySelectorAll('div.x-layer.x-combo-list[style*=\"visibility: visible\"] .x-combo-list-item:nth-child(10)')[0];").click(); + } + axisSwap() { + var axisFirstChildText = ''; + var axisSecondChildText = ''; + axisFirstChildText = browser.getText(this.selectors.chart.axis + ' text'); + browser.waitAndClick(this.selectors.options.button); + browser.waitAndClick(this.selectors.options.swap); + // browser.pause(1000); + axisSecondChildText = browser.getText(this.selectors.chart.axis + ' text'); + // browser.waitForChart(); + browser.pause(1000); + browser.waitAndClick(this.selectors.options.button); + // browser.pause(1000); + expect(axisFirstChildText[1]).to.not.equal(axisSecondChildText[1]); + browser.pause(10000); + } + chartTitleInOptionsUpdated() { + browser.waitForChart(); + browser.waitAndClick(this.selectors.options.button); + browser.waitForVisible(this.selectors.options.title, 3000); + var res1 = browser.getValue(this.selectors.options.title); + expect(res1).to.be.a('string'); + var res2 = browser.execute(function (text) { + return Ext.util.Format.htmlDecode(text); + }, res1); + expect(res2.value).to.equal(this.newTitle); + browser.waitForChart(); + browser.waitAndClick(this.selectors.options.button); + } + attemptDeleteScratchpad(cheerio) { + browser.waitAndClick('.x-btn-text.delete2'); + // this gets the buttons, however, not able to get just the yes button + // $$(".x-window-dlg .x-toolbar-cell:not(.x-hide-offsets) table"); + browser.waitForVisible('.x-window-dlg .x-toolbar-cell:not(.x-hide-offsets) table'); + browser.getHTML('.x-window-dlg .x-toolbar-cell:not(.x-hide-offsets) table')[0]; + var $yesButton = cheerio.load(browser.getHTML('.x-window-dlg .x-toolbar-cell:not(.x-hide-offsets) table')[0]); + this.selectors.deleteChart = '#' + $yesButton('table').attr('id'); + } + actionLoadChart(chartNumber) { + browser.pause(3000); + browser.waitAndClick(this.selectors.load.button(), 2000); + browser.waitAndClick(this.selectors.load.chartNum(chartNumber), 2000); + browser.waitForChart(); + } + addDataViaToolbar() { + browser.click(this.selectors.addData.button); + // Click on Jobs + browser.waitAndClick(this.selectors.buttonMenu.firstLevel + ' ul li:nth-child(3)'); + // click on CPU Hours: Per Job + browser.waitAndClick(this.selectors.addData.secondLevel + ' ul li:nth-child(2)'); + browser.waitAndClick('#adp_submit_button'); + } + genericStartingPoint() { + browser.waitAndClick(this.selectors.addData.button); + // Click on Jobs (5 on original site) + browser.waitAndClick(this.selectors.buttonMenu.firstLevel + ' ul li:nth-child(3)'); + // click on CPU Hours: Total + browser.waitAndClick(this.selectors.addData.secondLevel + ' ul li:nth-child(3)', 1000); + // browser.waitAndClick("#adp_submit_button", 4000) + browser.click('#adp_submit_button'); + } + confirmChartTitleChange(largeTitle) { + browser.waitForChart(); + browser.pause(2000); + var titleChange = browser.execute('return document.querySelector("' + this.selectors.chart.title + '").textContent;'); + // expect(titleChange.state).to.equal('success'); + expect(titleChange._status).to.equal(0); + expect(titleChange.value).to.be.a('string'); + expect(titleChange.value).to.equal(largeTitle); + } + + switchToAggregate() { + browser.pause(3000); + browser.waitAndClick(this.selectors.options.button); + browser.waitAndClick(this.selectors.options.aggregate); + browser.waitForChart(); + } + + undoAggregateOrTrendLine($container) { + browser.pause(3000); + browser.waitAndClick(this.undo($container)); + browser.pause(3000); + // The mouse stays and causes a hover, lets move the mouse somewhere else + browser.waitAndClick('.xtb-text.logo93'); + } + + clickFirstDataPoint() { + var seriesIndex = 0; + var pointIndex = 0; + browser.moveToObject('#hc-panelmetric_explorer', 0, 0); + var pointLocation = browser.getChartSeriesPointLocation('hc-panelmetric_explorer', seriesIndex, pointIndex).value; + expect(pointLocation.left).to.be.a('number'); + expect(pointLocation.top).to.be.a('number'); + browser.moveTo(null, pointLocation.left, pointLocation.top); + browser.buttonDown(); + browser.buttonUp(); + browser.execute('return document.querySelectorAll("svg g.highcharts-series-group g.highcharts-markers.highcharts-tracker path")[' + seriesIndex + '];').click(); + browser.pause(10000); + } + saveChartTitle() { + browser.pause(5000); + browser.waitForLoadedThenClick(this.meselectors.options.button); + browser.waitForVisible(this.meselectors.options.title, 30000); + expect(browser.getValue(this.meselectors.options.title)).to.be.a('string'); + var chartTitle = browser.getValue(this.meselectors.options.title); + return (chartTitle); + } +} + +module.exports = new MetricExplorer(); + diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.js new file mode 100644 index 0000000000..2571c7bdb2 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.js @@ -0,0 +1,107 @@ +var logIn = require('./loginPage.page.js'); +var rg = require('./reportGenerator.page.js'); + +describe('Report Generator', function reportGenerator() { + var loginName = testHelpers.auth.roles.po.username; + var loginPassword = testHelpers.auth.roles.po.password; + var displayName = testHelpers.auth.roles.po.display; + logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); + var columnIndex = 1; + var reportName = 'TAS Report 1'; + var startDate = '2016-12-20'; + var endDate = '2017-01-01'; + var currentSchedule; + describe('Report Generator', function xdmod() { + it('Click on the Report Generator Tab', function clickTab() { + browser.waitForVisible(rg.mask, 50000, true); + browser.waitAndClick(rg.tabForName(rg.name)); + browser.waitAndClick(rg.tabForName(rg.name)); + }); + + it('Open the report to test', function selectReport() { + browser.waitForVisible(rg.tableRowForColumnText(columnIndex, reportName), 30000); + browser.doubleClick(rg.tableRowForColumnText(columnIndex, reportName)); + }); + + it('Edit the timeframe for the selected report', function editTimeFrame() { + browser.waitAndClick(rg.editDateForRowByIndex(1)); + }); + + it('Wait for Date Editor to be visible', function waitForEditorVisibility() { + browser.waitForVisible(rg.dateEditorcmp, 30000); + }); + + it("Select 'Specific' for the timeframe type", function setTimeFrameType() { + browser.click(rg.radioButton(rg.radial.specific)); + }); + + it('Clear start and end date', function clearStartAndEndDate() { + browser.setValue(rg.startDateField(), ''); + browser.setValue(rg.endDateField(), ''); + }); + + it('Press the update button, expect error about start date', function pressUpdateButton() { + rg.pressUpdateExpectError('start date'); + }); + + it('Set a start date', function setStartDate() { + browser.click(rg.startDateField()); + browser.setValue(rg.startDateField(), startDate); + }); + + it('Press the update button, expect error about end date', function pressUpdateButton() { + rg.pressUpdateExpectError('end date'); + }); + + it('Set an end date', function setEndDate() { + browser.click(rg.startDateField()); + browser.setValue(rg.endDateField(), endDate); + }); + + it('Press the update button', function pressUpdateButton() { + rg.pressUpdate(); + }); + + it('Verify that the date has been changed', function verifyDateChange() { + rg.verifyDateChange(startDate, endDate); + }); + + it('Save the Report', function saveTheReport() { + rg.saveTheReport(); + }); + + it('Close the report', function closeReport() { + browser.click(rg.returnToMyReportsButton()); + browser.waitForVisible(rg.tableRowForColumnText(columnIndex, reportName), 30000); + }); + + it('Open the report', function openReportAgain() { + browser.doubleClick(rg.tableRowForColumnText(columnIndex, reportName)); + }); + + it('Get the current Report Schedule', function getCurrentReportSchedule() { + browser.waitForVisible(rg.cmp(), 30000); + currentSchedule = browser.getValue(rg.cmp()); + }); + + it('Change the Report Schedule', function changeReportSchedule() { + browser.click(rg.cmp()); + browser.click(rg.selectionByName(rg.nextValue(currentSchedule))); + }); + + it('Save the Report', function saveTheReport() { + rg.saveTheReport(); + browser.waitForVisible(rg.chartUpdateInProgressByIndex(1), 50000, true); + }); + + it('Close the report', function closeReport() { + browser.click(rg.returnToMyReportsButton()); + browser.waitForVisible(rg.tableRowForColumnText(columnIndex, reportName), 30000); + }); + + it('Validate that the Schedule has been changed', function validateScheduleChange() { + browser.isExisting(rg.tableRowForColumnText(3, rg.nextValue(currentSchedule))); + }); + logIn.logout(); + }); +}); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.page.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.page.js new file mode 100644 index 0000000000..6af2340dbf --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.page.js @@ -0,0 +1,128 @@ +class ReportGenerator { + constructor() { + this.name = 'Report Generator'; + this.contents = "//div[@id='report_generator']"; + this.dateEditorcmp = "//div[contains(@class, 'chart_date_editor')]"; + this.radial = { + periodic: 'Periodic', + specific: 'Specific' + }; + this.items = [ + 'Once', + 'Daily', + 'Weekly', + 'Monthly', + 'Quarterly', + 'Semi-annually', + 'Annually' + ]; + this.mask = "//div[contains(@class, 'ext-el-mask')]"; + } + + radioButton(value) { + return this.dateEditorcmp + "//input[@type='radio' and contains(@class, 'x-form-radio') and @value='" + value + "']"; + } + + startDateField() { + return this.dateEditorcmp + "//input[@type='text' and @id='report_generator_edit_date_start_date_field']"; + } + + endDateField() { + return this.dateEditorcmp + "//input[@type='text' and @id='report_generator_edit_date_end_date_field']"; + } + + updateButton() { + return this.dateEditorcmp + "//button[contains(@class, 'chart_date_editor_update_button')]"; + } + + errorMessageContains(message) { + return this.dateEditorcmp + "//div[contains(@class, 'overlay_message') and text()[contains(., '" + message + "')]]"; + } + + cmp() { + return this.contents + "//input[@type='text' and @id='report_generator_report_schedule']"; + } + + selectionByName(name) { + return "//div[contains(@class, 'x-combo-list') and contains(@style, 'visibility: visible')]//div[contains(@class, 'x-combo-list-item') and text()[contains(.,'" + name + "')]]"; + } + + nextValue(value) { + var values = this.items; + var index = values.indexOf(value) + 1; + if (index === values.length) { + index = 0; + } + return values[index]; + } + + tabForName(name) { + return "//div[contains(@class, 'x-tab-panel-header')]//span[contains(@class, 'x-tab-strip-text') and text()[contains(., '" + name + "')]]"; + } + + tableRowForColumnText(columnIndex, text) { + return this.contents + "//div[contains(@class, 'x-grid3-row')]//table[contains(@class, 'x-grid3-row-table')]//div[contains(@class, 'x-grid3-cell-inner') and contains(@class, x-grid3-col-" + columnIndex + ") and text()[contains(., '" + text + "')]]"; + } + + tableRowByRowIndex(rowIndex) { + var myrowIndex; + if (typeof rowIndex !== 'number') { + myrowIndex = 1; + } else if (rowIndex < 1) { + myrowIndex = 1; + } else { + myrowIndex = rowIndex; + } + return '(' + this.contents + "//div[@id='CurrentNewchartbaseTab_queueGrid']//div[contains(@class, 'x-grid3-row')])[" + myrowIndex + ']'; + } + + editDateForRowByIndex(rowIndex, byImage) { + var newbyImage = byImage !== undefined ? byImage : false; + if (newbyImage === true) { + return this.tableRowByRowIndex(rowIndex) + "//a[@id='report_generator_timeframe_selector_img']"; + } + return this.tableRowByRowIndex(rowIndex) + "//a[@id='report_generator_timeframe_selector']"; + } + + chartUpdateInProgressByIndex(rowIndex) { + return this.tableRowByRowIndex(rowIndex) + "//img[contains(@src, 'report_gen_thumbnail_progress')]"; + } + + saveReportButton() { + return this.contents + "//button[contains(@class, 'btn_save') and text()[contains(.,'Save')]]"; + } + + saveReportMessage() { + return "//div[contains(@class, 'x-window') and @id='report_generator_message' and contains(@style, 'visibility: visible')]"; + } + + returnToMyReportsButton() { + return this.contents + "//button[contains(@class, 'btn_return_to_overview')]"; + } + + saveTheReport() { + browser.click(this.saveReportButton()); + browser.waitForVisible(this.saveReportMessage(), 50000); + browser.waitForVisible(this.saveReportMessage(), 50000, true); + } + pressUpdate() { + browser.pause(4000); + browser.click(this.updateButton()); + browser.pause(4000); + browser.waitForVisible(this.dateEditorcmp, 50000, true); + browser.waitForVisible(this.chartUpdateInProgressByIndex(1), 50000, true); + } + verifyDateChange(startDate, endDate) { + var dateChange = browser.getText(this.editDateForRowByIndex(1)); + var hasStartDate = dateChange.indexOf(startDate) >= 0; + var hasEndDate = dateChange.indexOf(endDate) >= 0; + expect(hasStartDate).to.equal(true); + expect(hasEndDate).to.equal(true); + } + pressUpdateExpectError(error) { + browser.click(this.updateButton()); + browser.waitForVisible(this.errorMessageContains(error), 60000); + browser.waitForVisible(this.errorMessageContains(error), 60000, true); + } +} +module.exports = new ReportGenerator(); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.js new file mode 100644 index 0000000000..4d17438ff1 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.js @@ -0,0 +1,29 @@ +var logIn = require('./loginPage.page.js'); +var usg = require('./usageTab.page.js'); + +describe('Usage', function () { + var loginName = testHelpers.auth.roles.po.username; + var loginPassword = testHelpers.auth.roles.po.password; + var displayName = testHelpers.auth.roles.po.display; + logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); + var baselineDate = { + start: '2016-12-25', + end: '2017-01-02' + }; + describe('Usage Tab', function xdmod() { + it('Selected', function () { + browser.waitForLoadedThenClick(usg.tab).call(); + }); + it('Set a known start and end date', function meSetStartEnd() { + browser.setValue(usg.startField, baselineDate.start); + browser.setValue(usg.endField, baselineDate.end); + }); + it('Select Job Size Min', function () { + browser.waitForLoadedThenClick(usg.jobSizeMin); + }); + it('Legend Text is Correct', function () { + usg.checkLegendText('Screwdriver'); + }); + }); + logIn.logout(); +}); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.page.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.page.js new file mode 100644 index 0000000000..f02ad6c7f4 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.page.js @@ -0,0 +1,18 @@ +class Usage { + constructor() { + this.tab = '#main_tab_panel__tg_usage'; + this.startField = '#tg_usage input[id^=start_field_ext]'; + this.endField = '#tg_usage input[id^=end_field_ext]'; + this.jobSizeMin = '.x-tree-root-node > li:nth-child(1) > ul:nth-child(2) > li:nth-child(5)'; + this.legendText = 'g.highcharts-legend-item'; + } + + checkLegendText(text) { + browser.waitForChart(); + browser.pause(2500); + browser.waitForExist(this.legendText, 50000); + expect(browser.getText(this.legendText)).to.equal(text); + } + +} +module.exports = new Usage(); diff --git a/open_xdmod/modules/xdmod/automated_tests/wdio-sauce.conf.js b/open_xdmod/modules/xdmod/automated_tests/wdio-sauce.conf.js new file mode 100644 index 0000000000..8d4cae3c44 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/wdio-sauce.conf.js @@ -0,0 +1,249 @@ +var ie = {browserName: 'internet explorer'}; +ie['platform'] = 'Windows 10'; +ie['version'] = '11.103'; +ie['screenResolution'] = '1280x1024'; + +var ff = {browserName: 'firefox'}; +ff['platform'] = 'Windows 10'; +ff['version'] = '45.0'; +ff['screenResolution'] = '2560x1600'; + +var chr = {browserName: 'chrome'}; +chr['platform'] = 'Windows 10'; +chr['version'] = '48.0'; +chr['screenResolution'] = '2560x1600'; + +sf = {browserName: 'safari'}; +sf['platform'] = 'macOS 10.12'; +sf['version'] = '10.0'; +sf['screenResolution'] = '1024x768'; + +exports.config = { + // Sauce Labs Login, comment out user and key to run tests locally + user: "xdmod-sauce", + key: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", // enter key before running + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. Notice that, if you are calling `wdio` from an + // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working + // directory is where your package.json resides, so `wdio` will be called from there. + // + specs: ["./test/specs/**/*.js"], + + // Patterns to exclude. + exclude: [ + /* + "./test/specs/xdmod/about.js", + "./test/specs/xdmod/jobViewer.js", + "./test/specs/xdmod/mainToolbar.js", + "./test/specs/xdmod/metricExplorer.js", + "./test/specs/xdmod/reportGenerator.js", + "./test/specs/xdmod/usageTab.js", + */ + + // pageObject files should always be excluded + "./test/**/*.page.js" + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilties at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude option in + // order to group specific specs to a specific capability. + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + // **NOTE** if no browserName is specified webdriverio defaults to firefox + // Webdriver.io has the ability to run multiple browsers at once + // uncomment the different objects to enable each browser + // uncomment multiple objects to enable multiple at the same time + // Please bear in mind that if the tests are manipulating saved state on the server + // then running multiple logins concurrently could cause problems. + + + // Define how many instances should be started at the same time. Let's + // say you have 3 different capabilities (Chrome, Firefox, and Safari) + // and you have set maxInstances to 1, wdio will spawn 3 processes. + // Therefore, if you have 10 spec files and you set maxInstances to 10; + // all spec files will get tested at the same time and 30 processes will + // get spawned. The property handles how many capabilities from the same + // test should run tests. + // The XDMoD SauceLabs account has a limit of 5 concurrent sessions. + maxInstances: 5, + //maxInstances: 1, + + + capabilities: [ + /* + { + browserName: "firefox" + }, + */ + /* + { + browserName: "phantomjs", + "phantomjs.cli.args": [ + "--ignore-ssl-errors=true", + "--web-security=false", + "--debug=false" + ] + }, + */ + /* + { + browserName: "chrome", + "chromeOptions": { + "args": [ + "incognito", + "disable-extensions", + "start-maximized", + + // For some reason start-maximized doesnt always work on mac + // so lets default its size + // for retina display the default is: window-size=2560,1600 but that is double what it should be... + + "window-size=1280,800" + ] + } + }, + */ + //ie, + //sf, + ff, + chr + + ], + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + + // By default WebdriverIO commands are executed in a synchronous way using + // the wdio-sync package. If you still want to run your tests in an async way + // e.g. using promises you can set the sync option to false. + sync: true, + //sync: false, + // Level of logging verbosity. + logLevel: "silent", + // + // Enables colors for log output. + coloredLogs: true, + // + // Saves a screenshot to a given path if a command fails. + // Comment out to disable feature. + //screenshotPath: "./errorShots/", + // + // Set a base URL in order to shorten url command calls. If your url parameter starts + // with "/", the base url gets prepended. + //baseUrl: "https://xdmod-dev.ccr.buffalo.edu", + baseUrl: "https://tas-reference-dbs.ccr.xdmod.org", + // + // Default timeout for all waitForXXX commands. + waitforTimeout: 10000, + // + // Initialize the browser instance with a WebdriverIO plugin. The object should have the + // plugin name as key and the desired plugin options as property. Make sure you have + // the plugin installed before running any tests. The following plugins are currently + // available: + // WebdriverCSS: https://github.com/webdriverio/webdrivercss + // WebdriverRTC: https://github.com/webdriverio/webdriverrtc + // Browserevent: https://github.com/webdriverio/browserevent + // plugins: { + // webdrivercss: { + // screenshotRoot: "my-shots", + // failedComparisonsRoot: "diffs", + // misMatchTolerance: 0.05, + // screenWidth: [320,480,640,1024] + // }, + // webdriverrtc: {}, + // browserevent: {} + // }, + // + services: ['sauce'], + // Framework you want to run your specs with. + // The following are supported: mocha, jasmine and cucumber + // see also: http://webdriver.io/guide/testrunner/frameworks.html + // + // Make sure you have the node package for the specific framework installed before running + // any tests. If not please install the following package: + // Mocha: `$ npm install mocha` + // Jasmine: `$ npm install jasmine` + // Cucumber: `$ npm install cucumber` + framework: "mocha", + // + // Test reporter for stdout. + // The following are supported: dot (default), spec and xunit + // see also: http://webdriver.io/guide/testrunner/reporters.html + reporter: "spec", + // + // Options to be passed to Mocha. + // See the full list at http://mochajs.org/ + mochaOpts: { + ui: "bdd", + timeout: 100000 + }, + // + // ===== + // Hooks + // ===== + // Run functions before or after the test. If one of them returns with a promise, WebdriverIO + // will wait until that promise got resolved to continue. + // + // Gets executed before all workers get launched. + onPrepare: function onPrepare() { + // do something + }, + // + // Gets executed before test execution begins. At this point you will have access to all global + // variables like `browser`. It is the perfect place to define custom commands. + before: function before() { + global.testHelpers = require("./test/helpers"); + var webdriverHelpers = require("./webdriverHelpers"); + for(var extension in webdriverHelpers){ + if(webdriverHelpers.hasOwnProperty(extension) && typeof webdriverHelpers[extension] === "function"){ + browser.addCommand(extension, webdriverHelpers[extension].bind(browser)); + } + else { + console.warning("Not Adding: ", extension, typeof webdriverHelpers[extension]); + } + } + /* + require("webdrivercss") + .init(browser, { + screenshotRoot: "xdmod", + // this is used to upload screenshots to a shared repository + api: "https://screenshots.ben.dev/api/repositories/", + misMatchTolerance: 0.05 + });*/ + /* jshint ignore:start */ + var chai = require("chai"); + expect = chai.expect; + /* jshint ignore:end */ + //browser.sync(); + /* + * Comment this out to make the window not maximize. + */ + //browser.windowHandleMaximize(); + }, + // + // Gets executed after all tests are done. You still have access to all global variables from + // the test. + after: function after( /*failures, pid*/ ) { + // do something + }, + // + // Gets executed after all workers got shut down and the process is about to exit. It is not + // possible to defer the end of the process using a promise. + onComplete: function onComplete() { + // do something + } +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/wdio.conf.js b/open_xdmod/modules/xdmod/automated_tests/wdio.conf.js new file mode 100644 index 0000000000..75ca464cb6 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/wdio.conf.js @@ -0,0 +1,239 @@ +var ie = {browserName: 'internet explorer'}; +ie['platform'] = 'Windows 10'; +ie['version'] = '11.103'; +ie['screenResolution'] = '1280x1024'; + +var ff = {browserName: 'firefox'}; +ff['platform'] = 'Windows 10'; +ff['version'] = '45.0'; +ff['screenResolution'] = '2560x1600'; + +var chr = {browserName: 'chrome'}; +chr['platform'] = 'Windows 10'; +chr['version'] = '48.0'; +chr['screenResolution'] = '2560x1600'; + +sf = {browserName: 'safari'}; +sf['platform'] = 'macOS 10.12'; +sf['version'] = '10.0'; +sf['screenResolution'] = '1024x768'; + +exports.config = { + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. Notice that, if you are calling `wdio` from an + // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working + // directory is where your package.json resides, so `wdio` will be called from there. + // + specs: ["./test/specs/**/*.js"], + + // Patterns to exclude. + exclude: [ + /* + "./test/specs/xdmod/about.js", + "./test/specs/xdmod/jobViewer.js", + "./test/specs/xdmod/mainToolbar.js", + "./test/specs/xdmod/metricExplorer.js", + "./test/specs/xdmod/reportGenerator.js", + "./test/specs/xdmod/usageTab.js", + */ + + // pageObject files should always be excluded + "./test/**/*.page.js" + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilties at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude option in + // order to group specific specs to a specific capability. + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + // **NOTE** if no browserName is specified webdriverio defaults to firefox + // Webdriver.io has the ability to run multiple browsers at once + // uncomment the different objects to enable each browser + // uncomment multiple objects to enable multiple at the same time + // Please bear in mind that if the tests are manipulating saved state on the server + // then running multiple logins concurrently could cause problems. + + + // Define how many instances should be started at the same time. Let's + // say you have 3 different capabilities (Chrome, Firefox, and Safari) + // and you have set maxInstances to 1, wdio will spawn 3 processes. + // Therefore, if you have 10 spec files and you set maxInstances to 10; + // all spec files will get tested at the same time and 30 processes will + // get spawned. The property handles how many capabilities from the same + // test should run tests. + maxInstances: 5, + //maxInstances: 1, + + + capabilities: [ + /* + { + browserName: "firefox" + }, + */ + /* + { + browserName: "phantomjs", + "phantomjs.cli.args": [ + "--ignore-ssl-errors=true", + "--web-security=false", + "--debug=false" + ] + }, + */ + ///* + { + browserName: "chrome", + "chromeOptions": { + "args": [ + "incognito", + "disable-extensions", + "start-maximized", + + // For some reason start-maximized doesnt always work on mac + // so lets default its size + // for retina display the default is: window-size=2560,1600 but that is double what it should be... + + "window-size=1280,800" + ] + } + }, + //*/ + ], + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + + // By default WebdriverIO commands are executed in a synchronous way using + // the wdio-sync package. If you still want to run your tests in an async way + // e.g. using promises you can set the sync option to false. + sync: true, + //sync: false, + // Level of logging verbosity. + logLevel: "silent", + // + // Enables colors for log output. + coloredLogs: true, + // + // Saves a screenshot to a given path if a command fails. + // Comment out to disable feature. + //screenshotPath: "./errorShots/", + // + // Set a base URL in order to shorten url command calls. If your url parameter starts + // with "/", the base url gets prepended. + //baseUrl: "https://xdmod-dev.ccr.buffalo.edu", + baseUrl: "https://tas-reference-dbs.ccr.xdmod.org", + // + // Default timeout for all waitForXXX commands. + waitforTimeout: 10000, + // + // Initialize the browser instance with a WebdriverIO plugin. The object should have the + // plugin name as key and the desired plugin options as property. Make sure you have + // the plugin installed before running any tests. The following plugins are currently + // available: + // WebdriverCSS: https://github.com/webdriverio/webdrivercss + // WebdriverRTC: https://github.com/webdriverio/webdriverrtc + // Browserevent: https://github.com/webdriverio/browserevent + // plugins: { + // webdrivercss: { + // screenshotRoot: "my-shots", + // failedComparisonsRoot: "diffs", + // misMatchTolerance: 0.05, + // screenWidth: [320,480,640,1024] + // }, + // webdriverrtc: {}, + // browserevent: {} + // }, + // + services: ['selenium-standalone'], + // Framework you want to run your specs with. + // The following are supported: mocha, jasmine and cucumber + // see also: http://webdriver.io/guide/testrunner/frameworks.html + // + // Make sure you have the node package for the specific framework installed before running + // any tests. If not please install the following package: + // Mocha: `$ npm install mocha` + // Jasmine: `$ npm install jasmine` + // Cucumber: `$ npm install cucumber` + framework: "mocha", + // + // Test reporter for stdout. + // The following are supported: dot (default), spec and xunit + // see also: http://webdriver.io/guide/testrunner/reporters.html + reporter: "spec", + // + // Options to be passed to Mocha. + // See the full list at http://mochajs.org/ + mochaOpts: { + ui: "bdd", + timeout: 100000 + }, + // + // ===== + // Hooks + // ===== + // Run functions before or after the test. If one of them returns with a promise, WebdriverIO + // will wait until that promise got resolved to continue. + // + // Gets executed before all workers get launched. + onPrepare: function onPrepare() { + // do something + }, + // + // Gets executed before test execution begins. At this point you will have access to all global + // variables like `browser`. It is the perfect place to define custom commands. + before: function before() { + global.testHelpers = require("./test/helpers"); + var webdriverHelpers = require("./webdriverHelpers"); + for(var extension in webdriverHelpers){ + if(webdriverHelpers.hasOwnProperty(extension) && typeof webdriverHelpers[extension] === "function"){ + browser.addCommand(extension, webdriverHelpers[extension].bind(browser)); + } + else { + console.warning("Not Adding: ", extension, typeof webdriverHelpers[extension]); + } + } + /* + require("webdrivercss") + .init(browser, { + screenshotRoot: "xdmod", + // this is used to upload screenshots to a shared repository + api: "https://screenshots.ben.dev/api/repositories/", + misMatchTolerance: 0.05 + });*/ + /* jshint ignore:start */ + var chai = require("chai"); + expect = chai.expect; + /* jshint ignore:end */ + //browser.sync(); + /* + * Comment this out to make the window not maximize. + */ + //browser.windowHandleMaximize(); + }, + // + // Gets executed after all tests are done. You still have access to all global variables from + // the test. + after: function after( /*failures, pid*/ ) { + // do something + }, + // + // Gets executed after all workers got shut down and the process is about to exit. It is not + // possible to defer the end of the process using a promise. + onComplete: function onComplete() { + // do something + } +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/getChartSeriesPointLocation.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/getChartSeriesPointLocation.js new file mode 100644 index 0000000000..f23ea5bdb2 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/getChartSeriesPointLocation.js @@ -0,0 +1,41 @@ +/** + * Attempt to retrieve the location ( top, left ) relative to the provided + * containerId of the point in the series ( pointIndex, seriesIndex ). A top + * and left offset can also be supplied. + * + * @param {String} containerId - the 'id' property of the container that + * contains the Highcharts instance. + * NOTE: this is an Ext id so no '#'. + * @param {Number} [seriesIndex=0] - the index of the series that contains + * the point to be located. + * @param {Number} [pointIndex=0] - the index of the point to be located. + * + * @return {Object} in the form: + * { + * top: , + * left: + * } + **/ +module.exports = function getChartSeriesPointLocation( + containerId, + seriesIndex, + pointIndex) { + seriesIndex = seriesIndex !== undefined ? seriesIndex : 0; + pointIndex = pointIndex !== undefined ? pointIndex : 0; + return this.execute(function(containerId, seriesIndex, pointIndex) { + + var cmp = Ext.getCmp(containerId); + var axes = cmp.chart.axes; + var xAxis = axes[0]; + var yAxis = axes[1]; + var series = cmp.chart.series[seriesIndex]; + var point = series.data[pointIndex]; + var top = yAxis.toPixels(point.options.y); + var left = xAxis.toPixels(point.options.x); + + return { + top: Number(top.toFixed(0)), + left: Number(left.toFixed(0)) + }; + }, containerId, seriesIndex, pointIndex); +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/index.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/index.js new file mode 100644 index 0000000000..f7c749d520 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/index.js @@ -0,0 +1 @@ +module.exports = require('require-dir')(); diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndClick.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndClick.js new file mode 100644 index 0000000000..8e0b353fd9 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndClick.js @@ -0,0 +1,14 @@ +/* + * Wait for selector to be visible then click on it + * + * @param {string} selector - element to click on + * @param {Number} [ms=5000] - Milliseconds to wait for element to be visible + * + * @uses commands/waitForVisible, commands/click + */ +module.exports = function waitAndClick(selector, ms) { + ms = ms || 5000; + + this.waitForVisible(selector, ms); + return this.click(selector); +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndSet.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndSet.js new file mode 100644 index 0000000000..92db9245b5 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndSet.js @@ -0,0 +1,65 @@ +/** + * The default validation function that is to be used if one is not provided by + * the user. + * + * @param {*} expected - the right hand side of the simple equality statement. + * ie. the value that the selector was set to. + * @param {*} actual - the left hand side of the simple equality statement. + * ie. the value that was retrieved from the selector. + **/ +var DEFAULT_VALIDATE_FUNCTION = function(expected, actual) { + expect(actual).to.equal(expected); +}; + +/** + * Wait for the element identified by the provided selector to be visible and + * then set it's value to the provided value. To more accurately simulate a user + * setting a value the click argument defaults to true. Also, as a simple sanity + * check, validate is also defaulted to true with a default validate function + * that just checks that the value that the selector was set to is what is + * retrieved via a getValue. + * + * @param {String} selector - will be used to identify the element. + * @param {*} value - the value to use while performing a setValue + * on the now visible element. + * @param {Number} [ms=5000] - the amount of time to wait for the selector + * to become visible. + * @param {Boolean} [click=true] - A value of true indicates that a click + * event will be executed before the setValue + * for the provided selector. A value of false + * indicates that the click event should be + * skipped. + * @param {Boolean} [validate=true] - validate that the value the selector + * is set to matches the value that is + * retrieved after the setValue is + * performed. + * @param {Function} [validateFunc=function(expected, actual){ + * expect(actual).to.be.equal(expected); + * } + * ] - The function that will be used to validate the value retrieved + * from the selector if the validate argument is true. + **/ +module.exports = function waitAndSet(selector, value, ms, click, validate, validateFunc) { + ms = ms || 5000; + click = click !== undefined ? click : true; + validate = validate !== undefined ? validate : true; + validateFunc = typeof validateFunc === 'function' ? validateFunc : DEFAULT_VALIDATE_FUNCTION; + + if (click === true && validate === true) { + this.waitForVisible(selector, ms); + this.click(selector); + this.setValue(selector, value); + return this.getValue(selector) + } else if (click === true && validate === false) { + this.waitForVisible(selector, ms); + this.click(selector); + return this.setValue(selector, value); + } else if (click === false && validate === true) { + this.waitForVisible(selector, ms); + this.setValue(selector, value); + return this.getValue(selector); + } else if (click === false && validate === false) { + this.waitForVisible(selector, ms); + return this.setValue(selector, value); + } +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForChart.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForChart.js new file mode 100644 index 0000000000..a6053aad9a --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForChart.js @@ -0,0 +1,14 @@ +/* + * Wait for chart to load + * TODO: Find a better way to determine if chart is rendered + * + * @param {Number} [ms=3000] - Milliseconds to wait for chat to be visible + * + * @uses commands/waitForVisible, protocol/pause + */ + +module.exports = function waitForChart(ms) { + ms = ms || 3000; + + return this.waitForVisible(".ext-el-mask-msg", 9000, true) +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForInvisible.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForInvisible.js new file mode 100644 index 0000000000..eb8bc8360a --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForInvisible.js @@ -0,0 +1,13 @@ +/* + * Wait for selector to be invisible + * + * @param {string} selector - element to check + * @param {Number} [ms=500] - Milliseconds to wait for element to be invisible + * + * @uses commands/waitForVisible + */ + +module.exports = function waitForInvisible(selector, ms) { + ms = ms || 1000; + return this.waitForVisible(selector, ms, true); +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForLoadedThenClick.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForLoadedThenClick.js new file mode 100644 index 0000000000..630fba885d --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForLoadedThenClick.js @@ -0,0 +1,15 @@ +/* + * Wait for loadingMask to not exist and selector to exist then click on selector + * + * @param {string} selector - element to click on + * @param {Number} [maskMs=500] - Milliseconds to wait for mask to not exist + * @param {Number} [clickMs=500] - Milliseconds to wait for selector to be visible + * + * @uses commands/waitForVisible, helpers/waitAndClick + */ +module.exports = function waitForLoadedThenClick(selector, maskMs, clickMs){ + maskMs = maskMs || 9000; + clickMs = clickMs || 5000; + browser.waitForVisible(".ext-el-mask-msg", maskMs, true); + return browser.click(selector); +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEnd.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEnd.js new file mode 100644 index 0000000000..1575c9f173 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEnd.js @@ -0,0 +1,32 @@ +/* + * Wait for selector to stop animating, where animation is defined + * as moving in the view. + * + * @param {string} selector - element to click on + * @param {Number} [ms=9000] - Milliseconds to wait for element to be visible + * @param {Number} [interval=250] - interval between element location checks + * + * @uses commands/waitUntil commands/getLocationInView + */ + +module.exports = function waitUntilAnimEnd(selector, ms, interval) { + ms = ms || 9000; + interval = interval || 250; + + var initialLoc = {x: -1, y:-1}; + + this.waitForVisible(selector, ms) + return this.waitUntil(function() { + + var loc = this.getLocationInView(selector) + if(loc.x === initialLoc.x && loc.y === initialLoc.y) { + return true; + } + else { + initialLoc = loc; + } + return false; + }, ms, interval); + + +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEndAndClick.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEndAndClick.js new file mode 100644 index 0000000000..530faab615 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEndAndClick.js @@ -0,0 +1,19 @@ +/* + * Wait for selector to stop animating then click on it + * + * @param {string} selector - element to click on + * @param {string} [button=left] which mouse key to use ["left", "middle", "right"] + * @param {Number} [ms=9000] - Milliseconds to wait for element to stop moving + * @param {Number} [interval=250] - interval between element location checks + * + * @uses waitUntilAnimEnd commands/buttonPress + */ + +module.exports = function waitUntilAnimEndAndClick(selector, button, ms, interval) { + button = button || 'left'; + ms = ms || 9000; + interval = interval || 250; + this.waitUntilAnimEnd(selector, ms,interval); + this.moveToObject(selector); + return this.buttonPress(button); +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilChartLoadsBySeries.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilChartLoadsBySeries.js new file mode 100644 index 0000000000..c4a8c860f4 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilChartLoadsBySeries.js @@ -0,0 +1,14 @@ +/** + * Wait for the Highchart that contains the provided series to load. + * + * @param {String} series - name of the series to be used to further + * identify the Highcharts instance. + * @param {Number} [ms=9000] - Milliseconds to wait for the element to + **/ +module.exports = function waitUntilChartLoadsBySeries(series, ms) { + ms = ms || 9000; + return this.waitForVisible( + "//*[local-name() = 'svg']//*[local-name() = 'g' and contains(@class, 'highcharts-axis')]//*[local-name() = 'tspan' and text()[contains(., '" + series + "')]]", + ms + ); +}; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilNotExist.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilNotExist.js new file mode 100644 index 0000000000..d859c6c345 --- /dev/null +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilNotExist.js @@ -0,0 +1,13 @@ +/* + * Wait for selector to be visible then click on it + * + * @param {string} selector - element to click on + * @param {Number} [ms=9000] - Milliseconds to wait for element to be visible + * + * @uses commands/waitForExist + */ + +module.exports = function waitUntilNotExist(selector, ms) { + ms = ms || 9000; + return this.waitForExist(selector, ms, true); +}; From 3e3dff1a6ef49b4fe286a87f967d5be9ed67b705 Mon Sep 17 00:00:00 2001 From: Ben Plessinger Date: Tue, 18 Jul 2017 13:46:51 -0400 Subject: [PATCH 2/2] Cleanup --- .../xdmod/automated_tests/.eslintrc.json | 3 +- .../modules/xdmod/automated_tests/.gitignore | 1 + .../xdmod/automated_tests/package-lock.json | 1073 +++++++++++++++-- .../modules/xdmod/automated_tests/readme.md | 114 +- .../automated_tests/template.secrets.json | 2 +- .../automated_tests/test/helpers/auth.js | 2 +- .../test/helpers/getScreenshotTitle.js | 16 - .../test/helpers/handleScreenshots.js | 19 - .../test/helpers/instructions.js | 16 +- .../test/helpers/metricExplorer.js | 169 +-- .../automated_tests/test/specs/xdmod/about.js | 7 +- .../test/specs/xdmod/about.page.js | 2 +- .../test/specs/xdmod/mainToolbar.js | 10 +- .../test/specs/xdmod/metricExplorer.js | 43 +- .../test/specs/xdmod/metricExplorer.page.js | 7 +- .../test/specs/xdmod/reportGenerator.js | 6 +- .../test/specs/xdmod/usageTab.js | 6 +- .../xdmod/automated_tests/wdio-sauce.conf.js | 425 +++---- .../xdmod/automated_tests/wdio.conf.js | 412 +++---- .../getChartSeriesPointLocation.js | 40 +- .../webdriverHelpers/waitAndClick.js | 12 +- .../webdriverHelpers/waitAndSet.js | 43 +- .../webdriverHelpers/waitForChart.js | 10 +- .../webdriverHelpers/waitForInvisible.js | 10 +- .../waitForLoadedThenClick.js | 16 +- .../webdriverHelpers/waitUntilAnimEnd.js | 31 +- .../waitUntilAnimEndAndClick.js | 20 +- .../waitUntilChartLoadsBySeries.js | 6 +- .../webdriverHelpers/waitUntilNotExist.js | 10 +- 29 files changed, 1616 insertions(+), 915 deletions(-) delete mode 100644 open_xdmod/modules/xdmod/automated_tests/test/helpers/getScreenshotTitle.js delete mode 100644 open_xdmod/modules/xdmod/automated_tests/test/helpers/handleScreenshots.js diff --git a/open_xdmod/modules/xdmod/automated_tests/.eslintrc.json b/open_xdmod/modules/xdmod/automated_tests/.eslintrc.json index 7ecd1b566b..845881951c 100644 --- a/open_xdmod/modules/xdmod/automated_tests/.eslintrc.json +++ b/open_xdmod/modules/xdmod/automated_tests/.eslintrc.json @@ -2,9 +2,10 @@ "env": { "mocha": true, "node": true, - "es6": true + "es6": true }, "globals": { + "require": false, "expect": false, "browser": false, "testHelpers": false, diff --git a/open_xdmod/modules/xdmod/automated_tests/.gitignore b/open_xdmod/modules/xdmod/automated_tests/.gitignore index 7bea03640c..bae8c22473 100644 --- a/open_xdmod/modules/xdmod/automated_tests/.gitignore +++ b/open_xdmod/modules/xdmod/automated_tests/.gitignore @@ -1,3 +1,4 @@ # Screenshots /xdmod /xdmod.tar.gz +/errorShots diff --git a/open_xdmod/modules/xdmod/automated_tests/package-lock.json b/open_xdmod/modules/xdmod/automated_tests/package-lock.json index a7e3329b2b..bdbcb70b58 100644 --- a/open_xdmod/modules/xdmod/automated_tests/package-lock.json +++ b/open_xdmod/modules/xdmod/automated_tests/package-lock.json @@ -24,29 +24,189 @@ "version": "4.11.8", "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, "requires": { "co": "4.6.0", "json-stable-stringify": "1.0.1" } }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "archiver": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz", + "integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=", + "requires": { + "archiver-utils": "1.3.0", + "async": "2.5.0", + "buffer-crc32": "0.2.13", + "glob": "7.1.2", + "lodash": "4.17.4", + "readable-stream": "2.3.3", + "tar-stream": "1.5.4", + "walkdir": "0.0.11", + "zip-stream": "1.2.0" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.7" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "requires": { + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "lazystream": "1.0.0", + "lodash": "4.17.4", + "normalize-path": "2.1.1", + "readable-stream": "2.3.3" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.7" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } }, "asn1": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" }, "assert-plus": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" }, "assertion-error": { "version": "1.0.2", @@ -54,28 +214,39 @@ "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=" }, "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "requires": { + "lodash": "4.17.4" + }, + "dependencies": { + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + } + } }, "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": "1.1.3", + "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", + "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=" }, "aws-sign2": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" }, "aws4": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" }, "babel-runtime": { "version": "6.23.0", @@ -89,19 +260,59 @@ "balanced-match": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", - "dev": true + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" }, "bcrypt-pbkdf": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, "optional": true, "requires": { "tweetnacl": "0.14.5" } }, + "bl": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", + "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", + "requires": { + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -111,7 +322,6 @@ "version": "2.10.1", "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, "requires": { "hoek": "2.16.3" } @@ -120,7 +330,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", - "dev": true, "requires": { "balanced-match": "0.4.2", "concat-map": "0.0.1" @@ -129,14 +338,12 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" }, "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=" }, "chai": { "version": "3.5.0", @@ -152,7 +359,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, "requires": { "ansi-styles": "2.2.1", "escape-string-regexp": "1.0.2", @@ -164,8 +370,7 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } }, @@ -181,17 +386,28 @@ "lodash": "3.10.1" } }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", + "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "combined-stream": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "dev": true, "requires": { "delayed-stream": "1.0.0" } @@ -201,11 +417,55 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=" }, + "compress-commons": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.0.tgz", + "integrity": "sha1-WFhwku8g03y1i68AARLJJ4/3O58=", + "requires": { + "buffer-crc32": "0.2.13", + "crc32-stream": "2.0.0", + "normalize-path": "2.1.1", + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "core-js": { "version": "2.4.1", @@ -217,15 +477,81 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "crc": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", + "integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms=" + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "requires": { + "crc": "3.4.4", + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "cryptiles": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, "requires": { "boom": "2.10.1" } }, + "css": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz", + "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", + "requires": { + "inherits": "2.0.3", + "source-map": "0.1.43", + "source-map-resolve": "0.3.1", + "urix": "0.1.0" + } + }, + "css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", + "requires": { + "css": "2.2.1" + } + }, "css-select": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", @@ -237,6 +563,11 @@ "nth-check": "1.0.1" } }, + "css-value": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", + "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=" + }, "css-what": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", @@ -246,7 +577,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" }, @@ -254,8 +584,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=" } } }, @@ -282,6 +611,11 @@ } } }, + "deepmerge": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.3.2.tgz", + "integrity": "sha1-FmNpFinU2/42T6EqKk8KqGqjoFA=" + }, "define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", @@ -294,8 +628,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=" }, "diff": { "version": "1.4.0", @@ -343,17 +676,20 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, "optional": true, "requires": { "jsbn": "0.1.1" } }, + "ejs": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.6.tgz", + "integrity": "sha1-R5Y2v6P+Ox3r1SCH8KyyBLTxnIg=" + }, "end-of-stream": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", - "dev": true, "requires": { "once": "1.4.0" } @@ -371,14 +707,22 @@ "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "external-editor": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", + "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", + "requires": { + "iconv-lite": "0.4.18", + "jschardet": "1.5.0", + "tmp": "0.0.31" + } }, "extsprintf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", - "dev": true + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=" }, "fd-slicer": { "version": "1.0.1", @@ -394,6 +738,21 @@ "resolved": "https://registry.npmjs.org/fibers/-/fibers-1.0.15.tgz", "integrity": "sha1-IvA5yPGLhWGQ+75N7PBWFUwerpw=" }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + } + } + }, "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", @@ -402,14 +761,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.1.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, "requires": { "asynckit": "0.4.0", "combined-stream": "1.0.5", @@ -419,14 +776,21 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "function-bind": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=" }, + "gaze": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", + "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", + "requires": { + "globule": "1.2.0" + } + }, "generate-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", @@ -446,7 +810,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" }, @@ -454,8 +817,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=" } } }, @@ -468,6 +830,49 @@ "minimatch": "0.3.0" } }, + "globule": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz", + "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=", + "requires": { + "glob": "7.1.2", + "lodash": "4.17.4", + "minimatch": "3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.7" + } + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, "growl": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", @@ -476,14 +881,12 @@ "har-schema": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "dev": true + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" }, "har-validator": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", - "dev": true, "requires": { "ajv": "4.11.8", "har-schema": "1.0.5" @@ -493,7 +896,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, "requires": { "ansi-regex": "2.1.1" }, @@ -501,16 +903,19 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" } } }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, "hawk": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, "requires": { "boom": "2.10.1", "cryptiles": "2.0.5", @@ -521,8 +926,7 @@ "hoek": { "version": "2.16.3", "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" }, "htmlparser2": { "version": "3.8.3", @@ -556,7 +960,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, "requires": { "assert-plus": "0.2.0", "jsprim": "1.4.0", @@ -574,11 +977,15 @@ "extend": "3.0.1" } }, + "iconv-lite": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", + "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "1.4.0", "wrappy": "1.0.2" @@ -589,6 +996,38 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "inquirer": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz", + "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=", + "requires": { + "ansi-escapes": "1.4.0", + "chalk": "1.1.3", + "cli-cursor": "2.1.0", + "cli-width": "2.1.0", + "external-editor": "2.0.4", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx": "4.1.0", + "string-width": "2.1.0", + "strip-ansi": "3.0.1", + "through": "2.3.8" + }, + "dependencies": { + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + } + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, "is-my-json-valid": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", @@ -601,6 +1040,11 @@ "xtend": "4.0.1" } }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, "is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", @@ -610,8 +1054,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=" }, "isarray": { "version": "0.0.1", @@ -627,8 +1070,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=" }, "jade": { "version": "0.26.3", @@ -655,7 +1097,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", - "dev": true, "optional": true, "requires": { "jsbn": "0.1.1" @@ -665,20 +1106,22 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, "optional": true }, + "jschardet": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.0.tgz", + "integrity": "sha512-+Q8JsoEQbrdE+a/gg1F9XO92gcKXgpE5UACqr0sIubjDmBEkd+OOWPGzQeMrWSLxd73r4dHxBeRW7edHu5LmJQ==" + }, "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-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, "requires": { "jsonify": "0.0.0" } @@ -686,8 +1129,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=" }, "jsonfile": { "version": "2.4.0", @@ -710,8 +1152,7 @@ "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" }, "jsonpointer": { "version": "4.0.1", @@ -723,7 +1164,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.0.2", @@ -734,8 +1174,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=" } } }, @@ -757,6 +1196,48 @@ } } }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "lodash": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", @@ -770,18 +1251,21 @@ "mime-db": { "version": "1.27.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", - "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", - "dev": true + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=" }, "mime-types": { "version": "2.1.15", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", - "dev": true, "requires": { "mime-db": "1.27.0" } }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" + }, "minimatch": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", @@ -826,6 +1310,24 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "1.0.2" + } + }, + "npm-install-package": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/npm-install-package/-/npm-install-package-2.1.0.tgz", + "integrity": "sha1-1+/jz816sAYUuJbqUxGdyaslkSU=" + }, "nth-check": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", @@ -837,8 +1339,7 @@ "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" }, "object-keys": { "version": "1.0.11", @@ -859,16 +1360,36 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1.0.2" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "pend": { "version": "1.2.0", @@ -879,8 +1400,7 @@ "performance-now": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "dev": true + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" }, "pinkie": { "version": "2.0.4", @@ -900,8 +1420,7 @@ "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "progress": { "version": "1.1.8", @@ -918,14 +1437,22 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "q": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=" }, "qs": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, "readable-stream": { "version": "1.1.14", @@ -943,11 +1470,15 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" }, + "remove-trailing-separator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", + "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=" + }, "request": { "version": "2.81.0", "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "dev": true, "requires": { "aws-sign2": "0.6.0", "aws4": "1.6.0", @@ -978,6 +1509,25 @@ "resolved": "https://registry.npmjs.org/require-dir/-/require-dir-0.3.2.tgz", "integrity": "sha1-wdXHXp+//eny5rM+OD209ZS1pqk=" }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "rgb2hex": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.0.tgz", + "integrity": "sha1-zNVfhgrgxcTqN1BLlY5ELY0SMls=" + }, "rimraf": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", @@ -1012,11 +1562,23 @@ } } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "2.1.0" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=" + }, "safe-buffer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", - "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", - "dev": true + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" }, "sauce-connect-launcher": { "version": "1.2.2", @@ -1025,10 +1587,27 @@ "dev": true, "requires": { "adm-zip": "0.4.7", - "async": "0.9.2", + "async": "2.5.0", "https-proxy-agent": "1.0.0", - "lodash": "3.10.1", + "lodash": "4.17.4", "rimraf": "2.6.1" + }, + "dependencies": { + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + } } }, "selenium-standalone": { @@ -1258,20 +1837,47 @@ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, "sntp": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, "requires": { "hoek": "2.16.3" } }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "requires": { + "amdefine": "1.0.1" + } + }, + "source-map-resolve": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", + "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", + "requires": { + "atob": "1.1.3", + "resolve-url": "0.2.1", + "source-map-url": "0.3.0", + "urix": "0.1.0" + } + }, + "source-map-url": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", + "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=" + }, "sshpk": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", - "dev": true, "requires": { "asn1": "0.2.3", "assert-plus": "1.0.0", @@ -1287,8 +1893,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=" } } }, @@ -1297,17 +1902,34 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, + "string-width": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz", + "integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=", + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "2.1.1" }, @@ -1315,8 +1937,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" } } }, @@ -1325,6 +1946,64 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=" }, + "tar-stream": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz", + "integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=", + "requires": { + "bl": "1.2.1", + "end-of-stream": "1.4.0", + "readable-stream": "2.3.3", + "xtend": "4.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "requires": { + "os-tmpdir": "1.0.2" + } + }, "to-iso-string": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", @@ -1334,7 +2013,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", - "dev": true, "requires": { "punycode": "1.4.1" } @@ -1343,7 +2021,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" } @@ -1352,7 +2029,6 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, "optional": true }, "type-detect": { @@ -1366,27 +2042,60 @@ "integrity": "sha1-uURj6rpZoaeWA2pGe7YzxmfyIas=", "dev": true }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uuid": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", - "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", - "dev": true + "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=" + }, + "validator": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-7.0.0.tgz", + "integrity": "sha1-x03rgGNRL6w1VHk45vCxUEooL9I=" }, "verror": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", - "dev": true, "requires": { "extsprintf": "1.0.2" } }, + "walkdir": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz", + "integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=" + }, + "wdio-dot-reporter": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.8.tgz", + "integrity": "sha1-NhlVdtoNmYIQxxlIy7ZfW/Eb/GU=" + }, "wdio-mocha-framework": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/wdio-mocha-framework/-/wdio-mocha-framework-0.5.10.tgz", @@ -1448,6 +2157,71 @@ "object.assign": "4.0.4" } }, + "webdriverio": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-4.8.0.tgz", + "integrity": "sha1-1Skpt0kID4mWf24WFAUcvIFy0TI=", + "requires": { + "archiver": "1.3.0", + "babel-runtime": "6.23.0", + "css-parse": "2.0.0", + "css-value": "0.0.1", + "deepmerge": "1.3.2", + "ejs": "2.5.6", + "gaze": "1.1.2", + "glob": "7.1.2", + "inquirer": "3.0.6", + "json-stringify-safe": "5.0.1", + "mkdirp": "0.5.1", + "npm-install-package": "2.1.0", + "optimist": "0.6.1", + "q": "1.5.0", + "request": "2.81.0", + "rgb2hex": "0.1.0", + "safe-buffer": "5.0.1", + "supports-color": "3.2.3", + "url": "0.11.0", + "validator": "7.0.0", + "wdio-dot-reporter": "0.0.8", + "wgxpath": "1.0.0" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.7" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "wgxpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wgxpath/-/wgxpath-1.0.0.tgz", + "integrity": "sha1-7vikudVYzEla06mit1FZfs2a9pA=" + }, "which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", @@ -1457,17 +2231,20 @@ "isexe": "2.0.0" } }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "yallist": { "version": "2.1.2", @@ -1484,6 +2261,56 @@ "buffer-crc32": "0.2.13", "fd-slicer": "1.0.1" } + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "requires": { + "archiver-utils": "1.3.0", + "compress-commons": "1.2.0", + "lodash": "4.17.4", + "readable-stream": "2.3.3" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } } } } diff --git a/open_xdmod/modules/xdmod/automated_tests/readme.md b/open_xdmod/modules/xdmod/automated_tests/readme.md index b8511d32d5..5725d14a61 100644 --- a/open_xdmod/modules/xdmod/automated_tests/readme.md +++ b/open_xdmod/modules/xdmod/automated_tests/readme.md @@ -1,93 +1,81 @@ -# Automated Regression tests for the XDMod Frontend +# Automated Regression tests for the XDMoD Frontend -Based on [webdriver.io][wd] and [webdriverCSS][wdc] +Based on [webdriver.io][wd] -## Requirements - -### webdriver.io installed globally +## Setup ```bash -npm -g install webdriverio +npm install ``` -or if you want run it from node modules +This will not work with a "clean" reference database yet. -```bash -npm install webdriverio -``` +You will need to perform the following steps -### webdriverCSS webdriverCSS will need [GraphicsMagick][gm] +1. Login as the user you want the tests to run as +2. Goto the Metric Explorer +3. Add Data -For most up to date instructions follow these [instructions][wdc-reqs] -To install this GraphicsMagick + 1. Jobs + 2. CPU Hours: Total + 3. Group By None (if using Metric Catalog) -#### Mac OS X using [Homebrew](http://mxcl.github.io/homebrew/) +4. Save -```sh -brew install graphicsmagick -``` +5. Save Changes -#### Ubuntu using apt-get +6. Check Available For Report -```sh -sudo apt-get install graphicsmagick -``` +7. Switch to the Report Generator Tab +8. Click new +9. Drag untitled query 1 from the Available Charts to Included Charts +10. Click Save -#### Windows +### wdio.conf.js/wdio-sauce.conf.js -Download and install executables for [GraphicsMagick][gmd]. +#### host -### Selenium +Change the baseUrl to point to the environment you want it pointed to. -To run this without the use of a selenium grid (not yet ready) -The recommended way to install selenium is using [selenium standalone][ss] +By default this uses the "reference" database set up on . -### Optional +```javascript + // Set a base URL in order to shorten url command calls. If your url parameter starts + // with "/", the base url gets prepended. + baseUrl: "https://tas-reference-dbs.ccr.xdmod.org", +``` -[webdriverCSS Admin][wdc-admin] is used to more easily compare screenshots. -There are plans to make a shared instance of this for now it is run locally. +#### browser Options -## Setup +Change the browser to run the tests in by changing the list of browsers in the capabilities array. -```bash -npm install +``` +InternetExplorer +FireFox +Chrome +Safari +PhantomJS ``` -### wdio.conf.js/wdio-sauce.conf.js - -#### host - -change the baseurl to point to the environment you want it pointed to. +By default the tests run only in Chrome. ```javascript -// Set a base URL in order to shorten url command calls. If your url parameter starts -// with "/", the base url gets prepended. -baseUrl: "https://tas-reference-dbs.ccr.xdmod.org", +capabilities: [ + Chrome +], ``` -#### browser Options +##### SauceLabs -Change the browser to run the tests in by changing the browserName +Choose/add another browser to `wdio-sauce.conf.js`, use the [Platform Configurator](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/) and add specifications using the same syntax of the `Chrome` and `FireFox` browsers. -```javascript -capabilities: [{ - //browserName: "firefox", - browserName: "phantomjs", - //This allows phantomjs to use self signed certs - "phantomjs.cli.args": [ - "--ignore-ssl-errors=true", - //"--ssl-protocol=tlsv1", - "--web-security=false", - "--debug=false" - ] -}], -``` -Choose/add another browser to `wdio-sauce.conf.js`, use the [Platform Configurator](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/) and add specifications using the same syntax of the `chr` and `ff` browsers. +#### Other Options -In `mochaOpts`, set the `timeout` to desired time length. +In `mochaOpts`, set the `timeout` to desired time length. -Set `maxInstances` to the desired number of concurrent tests to run at a time. -*Note:* The XDMoD SauceLabs account allows for a max of 5 concurrent tests at a time. +Set `maxInstances` to the desired number of concurrent tests to run at a time. + +_Note:_ The XDMoD SauceLabs account allows for a max of 5 concurrent tests at a time. If running tests through SauceLabs, enter the correct `key` for the `xdmod-sauce` account. @@ -115,12 +103,4 @@ npm run test-sauce and see the fun that is automated ui testing. - - [wd]: http://webdriver.io/ -[wdc]: https://github.com/webdriverio/webdrivercss -[wdc-reqs]: https://github.com/webdriverio/webdrivercss#install -[ss]: https://github.com/vvo/selenium-standalone -[gm]: http://www.graphicsmagick.org/ -[gmd]: http://www.graphicsmagick.org/download.html -[wdc-admin]: https://github.com/webdriverio/webdrivercss-adminpanel diff --git a/open_xdmod/modules/xdmod/automated_tests/template.secrets.json b/open_xdmod/modules/xdmod/automated_tests/template.secrets.json index e68665f906..82d3f98795 100644 --- a/open_xdmod/modules/xdmod/automated_tests/template.secrets.json +++ b/open_xdmod/modules/xdmod/automated_tests/template.secrets.json @@ -1,6 +1,6 @@ { "role": { - "po": { + "centerdirector": { "username": "USERNAME", "password": "PASSWORD", "display": "DISPAY NAME" diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/auth.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/auth.js index 0151cef6a8..883adf8ab7 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/helpers/auth.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/helpers/auth.js @@ -3,5 +3,5 @@ var roles = require('./../../.secrets.json').role; module.exports = { - roles: roles + roles: roles }; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/getScreenshotTitle.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/getScreenshotTitle.js deleted file mode 100644 index 37f1872d24..0000000000 --- a/open_xdmod/modules/xdmod/automated_tests/test/helpers/getScreenshotTitle.js +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Generate a screenshot name based on the base url and the capabilities - * TODO: Update options to have this configurable instead of assuming - * - * @param {object} browser - the browser object since it has the options - * @param {string} screenshotCategory - element to click on - * - * @returns string - */ -module.exports = function getScreenshotTitle(browser, screenshotCategory) { - return [ - screenshotCategory, - browser.desiredCapabilities.browserName.replace(" ", "."), - browser.options.baseUrl.replace(/https?/, "").replace(/\//g, "").replace(":", "") - ].join("."); -}; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/handleScreenshots.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/handleScreenshots.js deleted file mode 100644 index 04948f3750..0000000000 --- a/open_xdmod/modules/xdmod/automated_tests/test/helpers/handleScreenshots.js +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Handle errors from screenshots taken from webdrivercss - * - * @param {object} err - errors - * @param {object} res - results - * - */ -module.exports = function handleScreenshots(err, res ) { - expect(err).to.equal(undefined); - for(var screenshotSection in res){ - if(res.hasOwnProperty(screenshotSection)){ - var thisSection = res[screenshotSection]; - var len = thisSection.length; - while(len--){ - expect(thisSection[len].isWithinMisMatchTolerance).to.equal(true, thisSection[len].message); - } - } - } -}; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/instructions.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/instructions.js index cdfb4279fc..abf42397aa 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/helpers/instructions.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/helpers/instructions.js @@ -1,14 +1,10 @@ -//TODO: Look into moving these to files... +// TODO: Look into moving these to files... var sections = { - jobViewer: { - instructions: '
No job is selected for viewing

Please refer to the instructions below:



For more information, please refer to the User Manual
' - }, - metricExplorer: { - instructions: '
No data is available for viewing

Please refer to the instructions below:



For more information, please refer to the User Manual
' - } - }; - //cheerio = require("cheerio"); + metricExplorer: { + instructions: '
No data is available for viewing

Please refer to the instructions below:



For more information, please refer to the User Manual
' + } +}; module.exports = function instructions(browser, section, selector) { - expect(browser.getHTML(selector + " .x-grid-empty")).to.equal(sections[section].instructions); + expect(browser.getHTML(selector + ' .x-grid-empty')).to.equal(sections[section].instructions); }; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/helpers/metricExplorer.js b/open_xdmod/modules/xdmod/automated_tests/test/helpers/metricExplorer.js index 0466104792..7096775fe1 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/helpers/metricExplorer.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/helpers/metricExplorer.js @@ -1,87 +1,88 @@ module.exports = { - tab: "#main_tab_panel__metric_explorer", - metricCatalogEntryByName: function(name) { - return "//div[@id=\"metric_explorer\"]//ul[@class=\"x-tree-root-ct x-tree-arrows\"]//a[@class=\"x-tree-node-anchor\"]//span[contains(text(), \"" + name + "\")]"; - }, - metricCatalogEntryExpanderByName: function(name) { - return "//div[@id=\"metric_explorer\"]//ul[@class=\"x-tree-root-ct x-tree-arrows\"]//span[contains(text(), \"" + name + "\")]/ancestor::li//img[@class=\"x-tree-ec-icon x-tree-elbow-end-plus\"]"; - }, - metricContextEntryByName: function(name) { - return "//div[@class=\"x-menu x-menu-floating x-layer x-menu-nosep\"]//span[contains(text(), \"" + name + "\")]"; - }, - title: "//*[local-name()=\'svg\']/*[local-name()=\'text\' and @class=\'highcharts-title\']/*[local-name()=\'tspan\']", - contextMenuItemByText: function(text) { - return "//div[@class=\"x-menu x-menu-floating x-layer x-menu-nosep\"]//span[contains(text(), \"" + text + "\")]"; - }, - resizableWindowByTitle: function(title) { - return "//div[contains(@class, \"x-window\") and contains(@class, \"x-resizable-pinned\") and contains(@style, \"visibility: visible\")]//span[@class=\"x-window-header-text\" and text()[contains(.,\"" + title + "\")]]"; - }, - rawDataEntryByIndex: function(index) { - index = index !== undefined ? index : 1; - return "(//div[contains(@class, 'x-window') and contains(@style, 'visibility: visible')]//div[contains(@class, 'x-grid3-body')]//div[contains(@class, 'x-grid3-cell-inner') and contains(@class, 'x-grid3-col-local_job_id')])[" + index + "]"; - }, - startDate: "#metric_explorer input[id^=start_field_ext]", - endDate: "#metric_explorer input[id^=end_field_ext]", - container: "#metric_explorer", - load: { - button: function meLoadButtonId() { - return "button=Load Chart"; - }, - firstSaved: ".x-menu-floating:not(.x-hide-offsets) .x-grid3-body .x-grid3-row-first", - // This will return the id for the chart number specified in a zero based manner. - // This does not take into account the selected item - chartNum: function meChartByIndex(number) { - number = number + 1; - return ".x-menu-floating:not(.x-hide-offsets) .x-grid3-body > div:nth-child(" + number + ")"; - } - }, - addData: { - button: ".x-btn-text.add_data", - secondLevel: ".x-menu-floating:not(.x-hide-offsets):not(.x-menu-nosep)" - }, - data: { - button: "button=Data", - container: "", - modal: { - updateButton: "button=Update", - groupBy: { - input: "input[name=dimension]" - } - } - }, - deleteChart: "", - undo: function meUndoButtonId() { - return "#" + $container("button.x-btn-text-icon") - .closest("table") - .attr("id"); - }, - options: { - aggregate: "#aggregate_cb", - button: "#metric_explorer button.chartoptions", - trendLine: "#me_trend_line", - swap: "#me_chart_swap_xy", - title: "div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*=\"visibility: visible\"] #me_chart_title" - }, - chart: { - svg: "#metric_explorer > div > .x-panel-body-noborder > .x-panel-noborder svg", - title: "#hc-panelmetric_explorer svg .undefinedtitle", - titleInput: "div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*=\"visibility: visible\"] input[type=text]", - titleOkButton: "div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*=\"visibility: visible\"] table.x-btn.x-btn-noicon.x-box-item:first-child button", - titleCancelButton: "div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*=\"visibility: visible\"] table.x-btn.x-btn-noicon.x-box-item:last-child button", - contextMenu: { - container: "#metric-explorer-chartoptions-context-menu", - legend: "#metric-explorer-chartoptions-legend", - addData: "#metric-explorer-chartoptions-add-data", - addFilter: "#metric-explorer-chartoptions-add-filter" + tab: '#main_tab_panel__metric_explorer', + metricCatalogEntryByName: function (name) { + return '//div[@id="metric_explorer"]//ul[@class="x-tree-root-ct x-tree-arrows"]//a[@class="x-tree-node-anchor"]//span[contains(text(), "' + name + '")]'; + }, + metricCatalogEntryExpanderByName: function (name) { + return '//div[@id="metric_explorer"]//ul[@class="x-tree-root-ct x-tree-arrows"]//span[contains(text(), "' + name + '")]/ancestor::li//img[@class="x-tree-ec-icon x-tree-elbow-end-plus"]'; + }, + metricContextEntryByName: function (name) { + return '//div[@class="x-menu x-menu-floating x-layer x-menu-nosep"]//span[contains(text(), "' + name + '")]'; + }, + title: "//*[local-name()='svg']/*[local-name()='text' and @class='highcharts-title']/*[local-name()='tspan']", + contextMenuItemByText: function (text) { + return '//div[@class="x-menu x-menu-floating x-layer x-menu-nosep"]//span[contains(text(), "' + text + '")]'; + }, + resizableWindowByTitle: function (title) { + return '//div[contains(@class, "x-window") and contains(@class, "x-resizable-pinned") and contains(@style, "visibility: visible")]//span[@class="x-window-header-text" and text()[contains(.,"' + title + '")]]'; + }, + rawDataEntryByIndex: function (index) { + var thisIndex = (index !== undefined) ? index : 1; + return "(//div[contains(@class, 'x-window') and contains(@style, 'visibility: visible')]//div[contains(@class, 'x-grid3-body')]//div[contains(@class, 'x-grid3-cell-inner') and contains(@class, 'x-grid3-col-local_job_id')])[" + thisIndex + ']'; + }, + startDate: '#metric_explorer input[id^=start_field_ext]', + endDate: '#metric_explorer input[id^=end_field_ext]', + container: '#metric_explorer', + load: { + button: function meLoadButtonId() { + return 'button=Load Chart'; + }, + firstSaved: '.x-menu-floating:not(.x-hide-offsets) .x-grid3-body .x-grid3-row-first', + // This will return the id for the chart number specified in a zero based manner. + // This does not take into account the selected item + chartNum: function meChartByIndex(number) { + var thisNumber = number + 1; + return '.x-menu-floating:not(.x-hide-offsets) .x-grid3-body > div:nth-child(' + thisNumber + ')'; + } + }, + addData: { + button: '.x-btn-text.add_data', + secondLevel: '.x-menu-floating:not(.x-hide-offsets):not(.x-menu-nosep)' + }, + data: { + button: 'button=Data', + container: '', + modal: { + updateButton: 'button=Update', + groupBy: { + input: 'input[name=dimension]' + } + } + }, + deleteChart: '', + undo: function meUndoButtonId() { + // eslint-disable-next-line no-undef + return '#' + $container('button.x-btn-text-icon') + .closest('table') + .attr('id'); + }, + options: { + aggregate: '#aggregate_cb', + button: '#metric_explorer button.chartoptions', + trendLine: '#me_trend_line', + swap: '#me_chart_swap_xy', + title: 'div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*="visibility: visible"] #me_chart_title' + }, + chart: { + svg: '#metric_explorer > div > .x-panel-body-noborder > .x-panel-noborder svg', + title: '#hc-panelmetric_explorer svg .undefinedtitle', + titleInput: 'div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*="visibility: visible"] input[type=text]', + titleOkButton: 'div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*="visibility: visible"] table.x-btn.x-btn-noicon.x-box-item:first-child button', + titleCancelButton: 'div.x-menu.x-menu-floating.x-layer.x-menu-nosep[style*="visibility: visible"] table.x-btn.x-btn-noicon.x-box-item:last-child button', + contextMenu: { + container: '#metric-explorer-chartoptions-context-menu', + legend: '#metric-explorer-chartoptions-legend', + addData: '#metric-explorer-chartoptions-add-data', + addFilter: '#metric-explorer-chartoptions-add-filter' - }, - axis: "#metric_explorer .highcharts-xaxis-labels" - }, - catalog: { - container: "#metric_explorer > div > .x-panel-body-noborder > .x-border-panel:not(.x-panel-noborder)", - tree: "#metric_explorer > div > .x-panel-body-noborder > .x-border-panel:not(.x-panel-noborder) .x-tree-root-ct" - }, - buttonMenu: { - firstLevel: ".x-menu-floating:not(.x-hide-offsets)" - } + }, + axis: '#metric_explorer .highcharts-xaxis-labels' + }, + catalog: { + container: '#metric_explorer > div > .x-panel-body-noborder > .x-border-panel:not(.x-panel-noborder)', + tree: '#metric_explorer > div > .x-panel-body-noborder > .x-border-panel:not(.x-panel-noborder) .x-tree-root-ct' + }, + buttonMenu: { + firstLevel: '.x-menu-floating:not(.x-hide-offsets)' + } }; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.js index c2a660d628..9010a5a7fd 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.js @@ -1,7 +1,7 @@ var logIn = require('./loginPage.page.js'); -var loginName = testHelpers.auth.roles.po.username; -var loginPassword = testHelpers.auth.roles.po.password; -var displayName = testHelpers.auth.roles.po.display; +var loginName = testHelpers.auth.roles.centerdirector.username; +var loginPassword = testHelpers.auth.roles.centerdirector.password; +var displayName = testHelpers.auth.roles.centerdirector.display; var Abt = require('./about.page.js'); describe('About', function about() { @@ -98,4 +98,3 @@ describe('About', function about() { logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); logIn.logout(); }); - diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.page.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.page.js index f5650a265b..6e351bab78 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.page.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/about.page.js @@ -13,12 +13,12 @@ class About { checkTab(name) { browser.waitForLoadedThenClick(this.navEntry(name), 50000); $(this.container).waitForText(50000); + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(name.replace(' ',''), this.center, "xdmod"); } checkRoadmap() { browser.waitForLoadedThenClick(this.navEntry('Roadmap')); - browser.pause(20000); browser.waitForExist('iframe#about_roadmap', 30000); browser.frame('about_roadmap', function (err, result) { expect(err).to.be.a('undefined'); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.js index 6c79d77c0a..d932a214c4 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/mainToolbar.js @@ -1,7 +1,7 @@ var logIn = require('./loginPage.page.js'); -var loginName = testHelpers.auth.roles.po.username; -var loginPassword = testHelpers.auth.roles.po.password; -var displayName = testHelpers.auth.roles.po.display; +var loginName = testHelpers.auth.roles.centerdirector.username; +var loginPassword = testHelpers.auth.roles.centerdirector.password; +var displayName = testHelpers.auth.roles.centerdirector.display; var mTb = require('./mainToolbar.page.js'); var mainTab; @@ -18,6 +18,8 @@ describe('Main Toolbar', function () { describe('Contact Us', function () { for (var type in mTb.contactTypes) { if (mTb.contactTypes.hasOwnProperty(type)) { + // TODO: Fix this with Page Objects? + // eslint-disable-next-line no-loop-func it(type, function () { mTb.contactFunc(type); }); @@ -27,6 +29,8 @@ describe('Main Toolbar', function () { describe('Help', function () { for (var type in mTb.helpTypes) { if (mTb.helpTypes.hasOwnProperty(type)) { + // TODO: Fix this with Page Objects? + // eslint-disable-next-line no-loop-func it(type, function () { mTb.helpFunc(type, mainTab); browser.pause(1500); diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.js index 0a1cf6c023..48d7a7fd0c 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.js @@ -59,9 +59,9 @@ describe('Metric Explorer', function metricExplorer() { } } }; - var loginName = testHelpers.auth.roles.po.username; - var loginPassword = testHelpers.auth.roles.po.password; - var displayName = testHelpers.auth.roles.po.display; + var loginName = testHelpers.auth.roles.centerdirector.username; + var loginPassword = testHelpers.auth.roles.centerdirector.password; + var displayName = testHelpers.auth.roles.centerdirector.display; logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); describe('Select Tab', function xdmod() { it('Selected', function meSelect() { @@ -76,6 +76,7 @@ describe('Metric Explorer', function metricExplorer() { }); it('Instructions look the same as previous run', function () { browser.waitForVisible(me.selectors.catalog.container, 10000); + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "instructions") }); it('Has three toolbars', function meConfirmToolbars() { @@ -104,8 +105,9 @@ describe('Metric Explorer', function metricExplorer() { }); it('Scratchpad looks the same as previous run', function () { browser.waitForChart(); + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.01.source") - browser.pause(5000); + // browser.pause(5000); }); it("'Add Data' again via toolbar", function meAddData2() { @@ -124,8 +126,9 @@ describe('Metric Explorer', function metricExplorer() { }); it('Chart looks the same as previous run', function () { browser.waitForChart(); + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.undo.02.aggregate") - browser.pause(3000); + // browser.pause(3000); }); it('Undo Scratch Pad second source', function meUndoScratchPad() { browser.waitAndClick(me.undo($container)); @@ -133,9 +136,10 @@ describe('Metric Explorer', function metricExplorer() { browser.waitAndClick('.xtb-text.logo93'); }); it('Chart looks the same as previous run', function () { - // browser.waitForChart(); + browser.waitForChart(); + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.undo.02.source") - browser.pause(3000); + // browser.pause(3000); }); /* it("Swap the X and Y axis", function(){ @@ -146,22 +150,25 @@ describe('Metric Explorer', function metricExplorer() { me.attemptDeleteScratchpad(cheerio); }); it('Chart looks the same as previous run', function () { + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.delete.confirm") - browser.pause(1000); + // browser.pause(1000); }); it('Delete Scratchpad Chart', function meValidateDeletedScratchPad() { browser.waitAndClick(me.selectors.deleteChart); }); it('Chart looks the same as previous run', function () { + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "scratchpad.delete.complete") - browser.pause(1000); + // browser.pause(1000); }); it('Open load chart dialog', function meLoadChart() { browser.click(me.selectors.load.button()); }); it('Load chart dialog looks the same as previous run', function () { + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "load.dialog") - browser.pause(1000); + // browser.pause(1000); }); it('Open chart from load dialog', function meOpenChart() { // TODO: Need to make sure to select the same chart every time, not just the first for screenshots @@ -169,15 +176,17 @@ describe('Metric Explorer', function metricExplorer() { browser.waitForChart(); }); it('Loaded chart looks the same as previous run', function () { + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "load.chart") - browser.pause(1000); + // browser.pause(1000); }); it('Open Chart Options', function meChartOptions() { browser.waitAndClick(me.selectors.options.button); }); it('Chart options looks the same as previous run', function () { + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "chart.options") - browser.pause(1000); + // browser.pause(1000); }); it('Show Trend Line via Chart Options', function meAddTrendLine() { browser.waitAndClick(me.selectors.options.trendLine); @@ -193,8 +202,9 @@ describe('Metric Explorer', function metricExplorer() { browser.waitForChart(); }); it('Undo Trend Line looks the same as previous run', function () { + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "saved.chart.undo.trendline") - browser.pause(2000); + // browser.pause(2000); }); }); describe('Context Menu', function contextMenu() { @@ -233,11 +243,9 @@ describe('Metric Explorer', function metricExplorer() { describe('Add Data Menu', function () { actions.chart.contextMenu.addData(); - actions.chart.contextMenu.addData(); }); describe('Add Filter Menu', function () { actions.chart.contextMenu.addFilter(); - actions.chart.contextMenu.addFilter(); }); describe('Legend Menus', function () { actions.chart.contextMenu.setLegendPosition('Top Left'); @@ -248,9 +256,8 @@ describe('Metric Explorer', function metricExplorer() { actions.chart.contextMenu.open(); actions.chart.contextMenu.legend(); it('legend Items set Properly', function () { - browser.waitForVisible('#metric-explorer-chartoptions-legend-options .x-menu-item-checked', 2000); + browser.waitForVisible('#metric-explorer-chartoptions-legend-options', 2000); var legendText = browser.getText('#metric-explorer-chartoptions-legend-options .x-menu-item-checked'); - // TODO: figure out why the line above was written and why it fails expect(legendText).to.equal('Bottom Center (Default)', 'Loaded chart has non default legend'); }); }); @@ -283,6 +290,7 @@ describe('Metric Explorer', function metricExplorer() { expect(execReturn).to.equal(false); }); it('Chart looks the same as previous run', function () { + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "pie.loaded"); }); it("Select the 'Data' toolbar button", function selectData() { @@ -333,6 +341,7 @@ describe('Metric Explorer', function metricExplorer() { expect(execReturn.value).to.equal(false); }); it('Chart looks the same as previous run', function () { + // TODO: Determine Pass case for this without using screenshot // browser.takeScreenshot(moduleName, me.selectors.container, "highcharts.loaded") }); }); // Should start with a dataset. diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.page.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.page.js index bc497e3afb..7ef9e6982e 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.page.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/metricExplorer.page.js @@ -73,7 +73,6 @@ class MetricExplorer { clear() { browser.refresh(); browser.waitForVisible('#logout_link', 3000); - // expect(browser.isVisible("#metric_explorer .x-grid-empty")).to.equal(false, "Empty chart not visible"); } generateTitle(size) { var result = ''; @@ -100,12 +99,10 @@ class MetricExplorer { browser.waitForLoadedThenClick(this.selectors.options.button); browser.waitForLoadedThenClick(this.selectors.options.title); var cursorPosition = browser.execute('return document.getElementById("me_chart_title").selectionStart;'); - // expect(cursorPosition.state).to.equal("success"); expect(cursorPosition._status).to.equal(0); expect(cursorPosition.value).to.equal(this.originalTitle.length, 'Cursor Position not at end'); browser.keys('Arrow_Up'); var newPosition = browser.execute('return document.getElementById("me_chart_title").selectionStart;'); - // expect(newPosition.state).to.equal("success"); expect(newPosition._status).to.equal(0); expect(newPosition.value).to.equal(0, 'Cursor Position not at begining'); browser.waitAndClick(this.selectors.options.button); @@ -176,6 +173,8 @@ class MetricExplorer { var res1 = browser.getValue(this.selectors.options.title); expect(res1).to.be.a('string'); var res2 = browser.execute(function (text) { + // TODO: Fix this withOut having to use EXT if Possible + // eslint-disable-next-line no-undef return Ext.util.Format.htmlDecode(text); }, res1); expect(res2.value).to.equal(this.newTitle); @@ -187,7 +186,6 @@ class MetricExplorer { // this gets the buttons, however, not able to get just the yes button // $$(".x-window-dlg .x-toolbar-cell:not(.x-hide-offsets) table"); browser.waitForVisible('.x-window-dlg .x-toolbar-cell:not(.x-hide-offsets) table'); - browser.getHTML('.x-window-dlg .x-toolbar-cell:not(.x-hide-offsets) table')[0]; var $yesButton = cheerio.load(browser.getHTML('.x-window-dlg .x-toolbar-cell:not(.x-hide-offsets) table')[0]); this.selectors.deleteChart = '#' + $yesButton('table').attr('id'); } @@ -263,4 +261,3 @@ class MetricExplorer { } module.exports = new MetricExplorer(); - diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.js index 2571c7bdb2..ca42a81200 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/reportGenerator.js @@ -2,9 +2,9 @@ var logIn = require('./loginPage.page.js'); var rg = require('./reportGenerator.page.js'); describe('Report Generator', function reportGenerator() { - var loginName = testHelpers.auth.roles.po.username; - var loginPassword = testHelpers.auth.roles.po.password; - var displayName = testHelpers.auth.roles.po.display; + var loginName = testHelpers.auth.roles.centerdirector.username; + var loginPassword = testHelpers.auth.roles.centerdirector.password; + var displayName = testHelpers.auth.roles.centerdirector.display; logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); var columnIndex = 1; var reportName = 'TAS Report 1'; diff --git a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.js b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.js index 4d17438ff1..86e2f3a295 100644 --- a/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.js +++ b/open_xdmod/modules/xdmod/automated_tests/test/specs/xdmod/usageTab.js @@ -2,9 +2,9 @@ var logIn = require('./loginPage.page.js'); var usg = require('./usageTab.page.js'); describe('Usage', function () { - var loginName = testHelpers.auth.roles.po.username; - var loginPassword = testHelpers.auth.roles.po.password; - var displayName = testHelpers.auth.roles.po.display; + var loginName = testHelpers.auth.roles.centerdirector.username; + var loginPassword = testHelpers.auth.roles.centerdirector.password; + var displayName = testHelpers.auth.roles.centerdirector.display; logIn.login('Open XDMoD', '/', loginName, loginPassword, displayName); var baselineDate = { start: '2016-12-25', diff --git a/open_xdmod/modules/xdmod/automated_tests/wdio-sauce.conf.js b/open_xdmod/modules/xdmod/automated_tests/wdio-sauce.conf.js index 8d4cae3c44..e8ff87154d 100644 --- a/open_xdmod/modules/xdmod/automated_tests/wdio-sauce.conf.js +++ b/open_xdmod/modules/xdmod/automated_tests/wdio-sauce.conf.js @@ -1,249 +1,218 @@ -var ie = {browserName: 'internet explorer'}; -ie['platform'] = 'Windows 10'; -ie['version'] = '11.103'; -ie['screenResolution'] = '1280x1024'; - -var ff = {browserName: 'firefox'}; -ff['platform'] = 'Windows 10'; -ff['version'] = '45.0'; -ff['screenResolution'] = '2560x1600'; - -var chr = {browserName: 'chrome'}; -chr['platform'] = 'Windows 10'; -chr['version'] = '48.0'; -chr['screenResolution'] = '2560x1600'; +// eslint-disable-next-line no-unused-vars +var InternetExplorer = { + browserName: 'internet explorer', + platform: 'Windows 10', + version: '11.103', + screenResolution: '1280x1024' +}; +// eslint-disable-next-line no-unused-vars +var FireFox = { + browserName: 'firefox', + platform: 'Windows 10', + version: '45.0', + screenResolution: '2560x1600' +}; -sf = {browserName: 'safari'}; -sf['platform'] = 'macOS 10.12'; -sf['version'] = '10.0'; -sf['screenResolution'] = '1024x768'; +var Chrome = { + browserName: 'chrome', + platform: 'Windows 10', + version: '48.0', + screenResolution: '2560x1600', + chromeOptions: { + args: [ + 'incognito', + 'disable-extensions', + 'start-maximized', + 'window-size=2560,1600' + ] + } +}; +// eslint-disable-next-line no-unused-vars +var Safari = { + browserName: 'safari', + platform: 'macOS 10.12', + version: '10', + screenResolution: '1024x768' +}; +// eslint-disable-next-line no-unused-vars +var PhantomJS = { + browserName: 'phantomjs', + 'phantomjs.cli.args': [ + '--ignore-ssl-errors=true', + '--web-security=false', + '--debug=false' + ] +}; exports.config = { // Sauce Labs Login, comment out user and key to run tests locally - user: "xdmod-sauce", - key: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", // enter key before running - // - // ================== - // Specify Test Files - // ================== - // Define which test specs should run. The pattern is relative to the directory - // from which `wdio` was called. Notice that, if you are calling `wdio` from an - // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working - // directory is where your package.json resides, so `wdio` will be called from there. - // - specs: ["./test/specs/**/*.js"], - - // Patterns to exclude. - exclude: [ - /* - "./test/specs/xdmod/about.js", - "./test/specs/xdmod/jobViewer.js", - "./test/specs/xdmod/mainToolbar.js", - "./test/specs/xdmod/metricExplorer.js", - "./test/specs/xdmod/reportGenerator.js", - "./test/specs/xdmod/usageTab.js", - */ + user: 'xdmod-sauce', + key: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', // enter key before running + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. Notice that, if you are calling `wdio` from an + // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working + // directory is where your package.json resides, so `wdio` will be called from there. + // + specs: [ + './test/specs/**/*.js' + ], + // Patterns to exclude. + exclude: [ // pageObject files should always be excluded - "./test/**/*.page.js" - ], - // - // ============ - // Capabilities - // ============ - // Define your capabilities here. WebdriverIO can run multiple capabilties at the same - // time. Depending on the number of capabilities, WebdriverIO launches several test - // sessions. Within your capabilities you can overwrite the spec and exclude option in - // order to group specific specs to a specific capability. - // - // If you have trouble getting all important capabilities together, check out the - // Sauce Labs platform configurator - a great tool to configure your capabilities: - // https://docs.saucelabs.com/reference/platforms-configurator - // - // **NOTE** if no browserName is specified webdriverio defaults to firefox - // Webdriver.io has the ability to run multiple browsers at once - // uncomment the different objects to enable each browser - // uncomment multiple objects to enable multiple at the same time - // Please bear in mind that if the tests are manipulating saved state on the server - // then running multiple logins concurrently could cause problems. - + './test/**/*.page.js' + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilties at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude option in + // order to group specific specs to a specific capability. + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + // **NOTE** if no browserName is specified webdriverio defaults to firefox + // Webdriver.io has the ability to run multiple browsers at once + // uncomment the different objects to enable each browser + // uncomment multiple objects to enable multiple at the same time + // Please bear in mind that if the tests are manipulating saved state on the server + // then running multiple logins concurrently could cause problems. // Define how many instances should be started at the same time. Let's // say you have 3 different capabilities (Chrome, Firefox, and Safari) - // and you have set maxInstances to 1, wdio will spawn 3 processes. - // Therefore, if you have 10 spec files and you set maxInstances to 10; - // all spec files will get tested at the same time and 30 processes will - // get spawned. The property handles how many capabilities from the same + // and you have set maxInstances to 1, wdio will spawn 3 processes. + // Therefore, if you have 10 spec files and you set maxInstances to 10; + // all spec files will get tested at the same time and 30 processes will + // get spawned. The property handles how many capabilities from the same // test should run tests. // The XDMoD SauceLabs account has a limit of 5 concurrent sessions. - maxInstances: 5, - //maxInstances: 1, - + maxInstances: 1, capabilities: [ - /* - { - browserName: "firefox" - }, - */ - /* - { - browserName: "phantomjs", - "phantomjs.cli.args": [ - "--ignore-ssl-errors=true", - "--web-security=false", - "--debug=false" - ] - }, - */ - /* - { - browserName: "chrome", - "chromeOptions": { - "args": [ - "incognito", - "disable-extensions", - "start-maximized", - - // For some reason start-maximized doesnt always work on mac - // so lets default its size - // for retina display the default is: window-size=2560,1600 but that is double what it should be... - - "window-size=1280,800" - ] - } - }, - */ - //ie, - //sf, - ff, - chr - - ], - // - // =================== - // Test Configurations - // =================== - // Define all options that are relevant for the WebdriverIO instance here - // + FireFox, + Chrome + ], + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // // By default WebdriverIO commands are executed in a synchronous way using // the wdio-sync package. If you still want to run your tests in an async way // e.g. using promises you can set the sync option to false. sync: true, - //sync: false, - // Level of logging verbosity. - logLevel: "silent", - // - // Enables colors for log output. - coloredLogs: true, - // - // Saves a screenshot to a given path if a command fails. + + // Level of logging verbosity. + logLevel: 'silent', + // + // Enables colors for log output. + coloredLogs: true, + // + // Saves a screenshot to a given path if a command fails. // Comment out to disable feature. - //screenshotPath: "./errorShots/", - // - // Set a base URL in order to shorten url command calls. If your url parameter starts - // with "/", the base url gets prepended. - //baseUrl: "https://xdmod-dev.ccr.buffalo.edu", - baseUrl: "https://tas-reference-dbs.ccr.xdmod.org", - // - // Default timeout for all waitForXXX commands. - waitforTimeout: 10000, - // - // Initialize the browser instance with a WebdriverIO plugin. The object should have the - // plugin name as key and the desired plugin options as property. Make sure you have - // the plugin installed before running any tests. The following plugins are currently - // available: - // WebdriverCSS: https://github.com/webdriverio/webdrivercss - // WebdriverRTC: https://github.com/webdriverio/webdriverrtc - // Browserevent: https://github.com/webdriverio/browserevent - // plugins: { - // webdrivercss: { - // screenshotRoot: "my-shots", - // failedComparisonsRoot: "diffs", - // misMatchTolerance: 0.05, - // screenWidth: [320,480,640,1024] - // }, - // webdriverrtc: {}, - // browserevent: {} - // }, - // - services: ['sauce'], - // Framework you want to run your specs with. - // The following are supported: mocha, jasmine and cucumber - // see also: http://webdriver.io/guide/testrunner/frameworks.html - // - // Make sure you have the node package for the specific framework installed before running - // any tests. If not please install the following package: - // Mocha: `$ npm install mocha` - // Jasmine: `$ npm install jasmine` - // Cucumber: `$ npm install cucumber` - framework: "mocha", - // - // Test reporter for stdout. - // The following are supported: dot (default), spec and xunit - // see also: http://webdriver.io/guide/testrunner/reporters.html - reporter: "spec", - // - // Options to be passed to Mocha. - // See the full list at http://mochajs.org/ - mochaOpts: { - ui: "bdd", + // screenshotPath: './errorShots/', + // + // Set a base URL in order to shorten url command calls. If your url parameter starts + // with '/', the base url gets prepended. + baseUrl: 'https://tas-reference-dbs.ccr.xdmod.org', + // + // Default timeout for all waitForXXX commands. + waitforTimeout: 10000, + // + // Initialize the browser instance with a WebdriverIO plugin. The object should have the + // plugin name as key and the desired plugin options as property. Make sure you have + // the plugin installed before running any tests. The following plugins are currently + // available: + // WebdriverCSS: https://github.com/webdriverio/webdrivercss + // WebdriverRTC: https://github.com/webdriverio/webdriverrtc + // Browserevent: https://github.com/webdriverio/browserevent + // plugins: { + // webdrivercss: { + // screenshotRoot: 'my-shots', + // failedComparisonsRoot: 'diffs', + // misMatchTolerance: 0.05, + // screenWidth: [320,480,640,1024] + // }, + // webdriverrtc: {}, + // browserevent: {} + // }, + // + services: [ + 'sauce' + ], + // Framework you want to run your specs with. + // The following are supported: mocha, jasmine and cucumber + // see also: http://webdriver.io/guide/testrunner/frameworks.html + // + // Make sure you have the node package for the specific framework installed before running + // any tests. If not please install the following package: + // Mocha: `$ npm install mocha` + // Jasmine: `$ npm install jasmine` + // Cucumber: `$ npm install cucumber` + framework: 'mocha', + // + // Test reporter for stdout. + // The following are supported: dot (default), spec and xunit + // see also: http://webdriver.io/guide/testrunner/reporters.html + reporter: 'spec', + // + // Options to be passed to Mocha. + // See the full list at http://mochajs.org/ + mochaOpts: { + ui: 'bdd', timeout: 100000 - }, - // - // ===== - // Hooks - // ===== - // Run functions before or after the test. If one of them returns with a promise, WebdriverIO - // will wait until that promise got resolved to continue. - // - // Gets executed before all workers get launched. - onPrepare: function onPrepare() { - // do something - }, - // - // Gets executed before test execution begins. At this point you will have access to all global - // variables like `browser`. It is the perfect place to define custom commands. - before: function before() { - global.testHelpers = require("./test/helpers"); - var webdriverHelpers = require("./webdriverHelpers"); - for(var extension in webdriverHelpers){ - if(webdriverHelpers.hasOwnProperty(extension) && typeof webdriverHelpers[extension] === "function"){ - browser.addCommand(extension, webdriverHelpers[extension].bind(browser)); - } - else { - console.warning("Not Adding: ", extension, typeof webdriverHelpers[extension]); - } - } - /* - require("webdrivercss") - .init(browser, { - screenshotRoot: "xdmod", - // this is used to upload screenshots to a shared repository - api: "https://screenshots.ben.dev/api/repositories/", - misMatchTolerance: 0.05 - });*/ - /* jshint ignore:start */ - var chai = require("chai"); - expect = chai.expect; - /* jshint ignore:end */ - //browser.sync(); - /* - * Comment this out to make the window not maximize. - */ - //browser.windowHandleMaximize(); - }, - // - // Gets executed after all tests are done. You still have access to all global variables from - // the test. - after: function after( /*failures, pid*/ ) { - // do something - }, - // - // Gets executed after all workers got shut down and the process is about to exit. It is not - // possible to defer the end of the process using a promise. - onComplete: function onComplete() { - // do something - } + }, + // + // ===== + // Hooks + // ===== + // Run functions before or after the test. If one of them returns with a promise, WebdriverIO + // will wait until that promise got resolved to continue. + // + // Gets executed before all workers get launched. + onPrepare: function onPrepare() { + // do something + }, + // + // Gets executed before test execution begins. At this point you will have access to all global + // variables like `browser`. It is the perfect place to define custom commands. + before: function before() { + // eslint-disable-next-line global-require + global.testHelpers = require('./test/helpers'); + // eslint-disable-next-line global-require + var webdriverHelpers = require('./webdriverHelpers'); + for (var extension in webdriverHelpers) { + if (webdriverHelpers.hasOwnProperty(extension) && typeof webdriverHelpers[extension] === 'function') { + browser.addCommand(extension, webdriverHelpers[extension].bind(browser)); + } else { + console.warning('Not Adding: ', extension, typeof webdriverHelpers[extension]); + } + } + // eslint-disable-next-line global-require + var chai = require('chai'); + // eslint-disable-next-line no-global-assign + expect = chai.expect; + }, + // + // Gets executed after all tests are done. You still have access to all global variables from + // the test. + after: function after(/* failures, pid */) { + // do something + }, + // + // Gets executed after all workers got shut down and the process is about to exit. It is not + // possible to defer the end of the process using a promise. + onComplete: function onComplete() { + // do something + } }; diff --git a/open_xdmod/modules/xdmod/automated_tests/wdio.conf.js b/open_xdmod/modules/xdmod/automated_tests/wdio.conf.js index 75ca464cb6..833ba3aab8 100644 --- a/open_xdmod/modules/xdmod/automated_tests/wdio.conf.js +++ b/open_xdmod/modules/xdmod/automated_tests/wdio.conf.js @@ -1,239 +1,211 @@ -var ie = {browserName: 'internet explorer'}; -ie['platform'] = 'Windows 10'; -ie['version'] = '11.103'; -ie['screenResolution'] = '1280x1024'; - -var ff = {browserName: 'firefox'}; -ff['platform'] = 'Windows 10'; -ff['version'] = '45.0'; -ff['screenResolution'] = '2560x1600'; - -var chr = {browserName: 'chrome'}; -chr['platform'] = 'Windows 10'; -chr['version'] = '48.0'; -chr['screenResolution'] = '2560x1600'; +// eslint-disable-next-line no-unused-vars +var InternetExplorer = { + browserName: 'internet explorer', + platform: 'Windows 10', + version: '11.103', + screenResolution: '1280x1024' +}; +// eslint-disable-next-line no-unused-vars +var FireFox = { + browserName: 'firefox', + platform: 'Windows 10', + version: '45.0', + screenResolution: '2560x1600' +}; -sf = {browserName: 'safari'}; -sf['platform'] = 'macOS 10.12'; -sf['version'] = '10.0'; -sf['screenResolution'] = '1024x768'; +var Chrome = { + browserName: 'chrome', + platform: 'Windows 10', + version: '48.0', + screenResolution: '2560x1600', + chromeOptions: { + args: [ + 'incognito', + 'disable-extensions', + 'start-maximized', + 'window-size=2560,1600' + ] + } +}; +// eslint-disable-next-line no-unused-vars +var Safari = { + browserName: 'safari', + platform: 'macOS 10.12', + version: '10', + screenResolution: '1024x768' +}; +// eslint-disable-next-line no-unused-vars +var PhantomJS = { + browserName: 'phantomjs', + 'phantomjs.cli.args': [ + '--ignore-ssl-errors=true', + '--web-security=false', + '--debug=false' + ] +}; exports.config = { - // ================== - // Specify Test Files - // ================== - // Define which test specs should run. The pattern is relative to the directory - // from which `wdio` was called. Notice that, if you are calling `wdio` from an - // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working - // directory is where your package.json resides, so `wdio` will be called from there. - // - specs: ["./test/specs/**/*.js"], - - // Patterns to exclude. - exclude: [ - /* - "./test/specs/xdmod/about.js", - "./test/specs/xdmod/jobViewer.js", - "./test/specs/xdmod/mainToolbar.js", - "./test/specs/xdmod/metricExplorer.js", - "./test/specs/xdmod/reportGenerator.js", - "./test/specs/xdmod/usageTab.js", - */ + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. Notice that, if you are calling `wdio` from an + // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working + // directory is where your package.json resides, so `wdio` will be called from there. + // + specs: [ + './test/specs/**/*.js' + ], + // Patterns to exclude. + exclude: [ // pageObject files should always be excluded - "./test/**/*.page.js" - ], - // - // ============ - // Capabilities - // ============ - // Define your capabilities here. WebdriverIO can run multiple capabilties at the same - // time. Depending on the number of capabilities, WebdriverIO launches several test - // sessions. Within your capabilities you can overwrite the spec and exclude option in - // order to group specific specs to a specific capability. - // - // If you have trouble getting all important capabilities together, check out the - // Sauce Labs platform configurator - a great tool to configure your capabilities: - // https://docs.saucelabs.com/reference/platforms-configurator - // - // **NOTE** if no browserName is specified webdriverio defaults to firefox - // Webdriver.io has the ability to run multiple browsers at once - // uncomment the different objects to enable each browser - // uncomment multiple objects to enable multiple at the same time - // Please bear in mind that if the tests are manipulating saved state on the server - // then running multiple logins concurrently could cause problems. - + './test/**/*.page.js' + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilties at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude option in + // order to group specific specs to a specific capability. + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + // **NOTE** if no browserName is specified webdriverio defaults to firefox + // Webdriver.io has the ability to run multiple browsers at once + // uncomment the different objects to enable each browser + // uncomment multiple objects to enable multiple at the same time + // Please bear in mind that if the tests are manipulating saved state on the server + // then running multiple logins concurrently could cause problems. // Define how many instances should be started at the same time. Let's // say you have 3 different capabilities (Chrome, Firefox, and Safari) - // and you have set maxInstances to 1, wdio will spawn 3 processes. - // Therefore, if you have 10 spec files and you set maxInstances to 10; - // all spec files will get tested at the same time and 30 processes will - // get spawned. The property handles how many capabilities from the same + // and you have set maxInstances to 1, wdio will spawn 3 processes. + // Therefore, if you have 10 spec files and you set maxInstances to 10; + // all spec files will get tested at the same time and 30 processes will + // get spawned. The property handles how many capabilities from the same // test should run tests. - maxInstances: 5, - //maxInstances: 1, - + maxInstances: 1, capabilities: [ - /* - { - browserName: "firefox" - }, - */ - /* - { - browserName: "phantomjs", - "phantomjs.cli.args": [ - "--ignore-ssl-errors=true", - "--web-security=false", - "--debug=false" - ] - }, - */ - ///* - { - browserName: "chrome", - "chromeOptions": { - "args": [ - "incognito", - "disable-extensions", - "start-maximized", - - // For some reason start-maximized doesnt always work on mac - // so lets default its size - // for retina display the default is: window-size=2560,1600 but that is double what it should be... - - "window-size=1280,800" - ] - } - }, - //*/ - ], - // - // =================== - // Test Configurations - // =================== - // Define all options that are relevant for the WebdriverIO instance here - // + Chrome + ], + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // // By default WebdriverIO commands are executed in a synchronous way using // the wdio-sync package. If you still want to run your tests in an async way // e.g. using promises you can set the sync option to false. sync: true, - //sync: false, - // Level of logging verbosity. - logLevel: "silent", - // - // Enables colors for log output. - coloredLogs: true, - // - // Saves a screenshot to a given path if a command fails. + // Level of logging verbosity. + logLevel: 'silent', + // + // Enables colors for log output. + coloredLogs: true, + // + // Saves a screenshot to a given path if a command fails. // Comment out to disable feature. - //screenshotPath: "./errorShots/", - // - // Set a base URL in order to shorten url command calls. If your url parameter starts - // with "/", the base url gets prepended. - //baseUrl: "https://xdmod-dev.ccr.buffalo.edu", - baseUrl: "https://tas-reference-dbs.ccr.xdmod.org", - // - // Default timeout for all waitForXXX commands. - waitforTimeout: 10000, - // - // Initialize the browser instance with a WebdriverIO plugin. The object should have the - // plugin name as key and the desired plugin options as property. Make sure you have - // the plugin installed before running any tests. The following plugins are currently - // available: - // WebdriverCSS: https://github.com/webdriverio/webdrivercss - // WebdriverRTC: https://github.com/webdriverio/webdriverrtc - // Browserevent: https://github.com/webdriverio/browserevent - // plugins: { - // webdrivercss: { - // screenshotRoot: "my-shots", - // failedComparisonsRoot: "diffs", - // misMatchTolerance: 0.05, - // screenWidth: [320,480,640,1024] - // }, - // webdriverrtc: {}, - // browserevent: {} - // }, - // - services: ['selenium-standalone'], - // Framework you want to run your specs with. - // The following are supported: mocha, jasmine and cucumber - // see also: http://webdriver.io/guide/testrunner/frameworks.html - // - // Make sure you have the node package for the specific framework installed before running - // any tests. If not please install the following package: - // Mocha: `$ npm install mocha` - // Jasmine: `$ npm install jasmine` - // Cucumber: `$ npm install cucumber` - framework: "mocha", - // - // Test reporter for stdout. - // The following are supported: dot (default), spec and xunit - // see also: http://webdriver.io/guide/testrunner/reporters.html - reporter: "spec", - // - // Options to be passed to Mocha. - // See the full list at http://mochajs.org/ - mochaOpts: { - ui: "bdd", + // screenshotPath: './errorShots/', + // + // Set a base URL in order to shorten url command calls. If your url parameter starts + // with '/', the base url gets prepended. + baseUrl: 'https://tas-reference-dbs.ccr.xdmod.org', + // + // Default timeout for all waitForXXX commands. + waitforTimeout: 10000, + // + // Initialize the browser instance with a WebdriverIO plugin. The object should have the + // plugin name as key and the desired plugin options as property. Make sure you have + // the plugin installed before running any tests. The following plugins are currently + // available: + // WebdriverCSS: https://github.com/webdriverio/webdrivercss + // WebdriverRTC: https://github.com/webdriverio/webdriverrtc + // Browserevent: https://github.com/webdriverio/browserevent + // plugins: { + // webdrivercss: { + // screenshotRoot: 'my-shots', + // failedComparisonsRoot: 'diffs', + // misMatchTolerance: 0.05, + // screenWidth: [320,480,640,1024] + // }, + // webdriverrtc: {}, + // browserevent: {} + // }, + // + services: [ + 'selenium-standalone' + ], + // Framework you want to run your specs with. + // The following are supported: mocha, jasmine and cucumber + // see also: http://webdriver.io/guide/testrunner/frameworks.html + // + // Make sure you have the node package for the specific framework installed before running + // any tests. If not please install the following package: + // Mocha: `$ npm install mocha` + // Jasmine: `$ npm install jasmine` + // Cucumber: `$ npm install cucumber` + framework: 'mocha', + // + // Test reporter for stdout. + // The following are supported: dot (default), spec and xunit + // see also: http://webdriver.io/guide/testrunner/reporters.html + reporter: 'spec', + // + // Options to be passed to Mocha. + // See the full list at http://mochajs.org/ + mochaOpts: { + ui: 'bdd', timeout: 100000 - }, - // - // ===== - // Hooks - // ===== - // Run functions before or after the test. If one of them returns with a promise, WebdriverIO - // will wait until that promise got resolved to continue. - // - // Gets executed before all workers get launched. - onPrepare: function onPrepare() { - // do something - }, - // - // Gets executed before test execution begins. At this point you will have access to all global - // variables like `browser`. It is the perfect place to define custom commands. - before: function before() { - global.testHelpers = require("./test/helpers"); - var webdriverHelpers = require("./webdriverHelpers"); - for(var extension in webdriverHelpers){ - if(webdriverHelpers.hasOwnProperty(extension) && typeof webdriverHelpers[extension] === "function"){ - browser.addCommand(extension, webdriverHelpers[extension].bind(browser)); - } - else { - console.warning("Not Adding: ", extension, typeof webdriverHelpers[extension]); - } - } - /* - require("webdrivercss") - .init(browser, { - screenshotRoot: "xdmod", - // this is used to upload screenshots to a shared repository - api: "https://screenshots.ben.dev/api/repositories/", - misMatchTolerance: 0.05 - });*/ - /* jshint ignore:start */ - var chai = require("chai"); - expect = chai.expect; - /* jshint ignore:end */ - //browser.sync(); - /* - * Comment this out to make the window not maximize. - */ - //browser.windowHandleMaximize(); - }, - // - // Gets executed after all tests are done. You still have access to all global variables from - // the test. - after: function after( /*failures, pid*/ ) { - // do something - }, - // - // Gets executed after all workers got shut down and the process is about to exit. It is not - // possible to defer the end of the process using a promise. - onComplete: function onComplete() { - // do something - } + }, + // + // ===== + // Hooks + // ===== + // Run functions before or after the test. If one of them returns with a promise, WebdriverIO + // will wait until that promise got resolved to continue. + // + // Gets executed before all workers get launched. + onPrepare: function onPrepare() { + // do something + }, + // + // Gets executed before test execution begins. At this point you will have access to all global + // variables like `browser`. It is the perfect place to define custom commands. + before: function before() { + // eslint-disable-next-line global-require + global.testHelpers = require('./test/helpers'); + // eslint-disable-next-line global-require + var webdriverHelpers = require('./webdriverHelpers'); + for (var extension in webdriverHelpers) { + if (webdriverHelpers.hasOwnProperty(extension) && typeof webdriverHelpers[extension] === 'function') { + browser.addCommand(extension, webdriverHelpers[extension].bind(browser)); + } else { + console.warning('Not Adding: ', extension, typeof webdriverHelpers[extension]); + } + } + // eslint-disable-next-line global-require + var chai = require('chai'); + // eslint-disable-next-line no-global-assign + expect = chai.expect; + }, + // + // Gets executed after all tests are done. You still have access to all global variables from + // the test. + after: function after(/* failures, pid */) { + // do something + }, + // + // Gets executed after all workers got shut down and the process is about to exit. It is not + // possible to defer the end of the process using a promise. + onComplete: function onComplete() { + // do something + } }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/getChartSeriesPointLocation.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/getChartSeriesPointLocation.js index f23ea5bdb2..9af80b4c21 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/getChartSeriesPointLocation.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/getChartSeriesPointLocation.js @@ -16,26 +16,24 @@ * left: * } **/ -module.exports = function getChartSeriesPointLocation( - containerId, - seriesIndex, - pointIndex) { - seriesIndex = seriesIndex !== undefined ? seriesIndex : 0; - pointIndex = pointIndex !== undefined ? pointIndex : 0; - return this.execute(function(containerId, seriesIndex, pointIndex) { +module.exports = function getChartSeriesPointLocation(containerId, seriesIndex, pointIndex) { + var thisSeriesIndex = (seriesIndex !== undefined) ? seriesIndex : 0; + var thisPointIndex = (pointIndex !== undefined) ? pointIndex : 0; + return this.execute(function (innerContainerId, innerSeriesIndex, innerPointIndex) { + // TODO: Fix this withOut having to use EXT if Possible + // eslint-disable-next-line no-undef + var cmp = Ext.getCmp(innerContainerId); + var axes = cmp.chart.axes; + var xAxis = axes[0]; + var yAxis = axes[1]; + var series = cmp.chart.series[innerSeriesIndex]; + var point = series.data[innerPointIndex]; + var top = yAxis.toPixels(point.options.y); + var left = xAxis.toPixels(point.options.x); - var cmp = Ext.getCmp(containerId); - var axes = cmp.chart.axes; - var xAxis = axes[0]; - var yAxis = axes[1]; - var series = cmp.chart.series[seriesIndex]; - var point = series.data[pointIndex]; - var top = yAxis.toPixels(point.options.y); - var left = xAxis.toPixels(point.options.x); - - return { - top: Number(top.toFixed(0)), - left: Number(left.toFixed(0)) - }; - }, containerId, seriesIndex, pointIndex); + return { + top: Number(top.toFixed(0)), + left: Number(left.toFixed(0)) + }; + }, containerId, thisSeriesIndex, thisPointIndex); }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndClick.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndClick.js index 8e0b353fd9..978e5b2af0 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndClick.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndClick.js @@ -1,14 +1,14 @@ /* * Wait for selector to be visible then click on it * - * @param {string} selector - element to click on - * @param {Number} [ms=5000] - Milliseconds to wait for element to be visible + * @param {string} selector - element to click on + * @param {Number} [ms=5000] - Milliseconds to wait for element to be visible * - * @uses commands/waitForVisible, commands/click + * @uses commands/waitForVisible, commands/click */ module.exports = function waitAndClick(selector, ms) { - ms = ms || 5000; + var thisMs = ms || 5000; - this.waitForVisible(selector, ms); - return this.click(selector); + this.waitForVisible(selector, thisMs); + return this.click(selector); }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndSet.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndSet.js index 92db9245b5..e111730a36 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndSet.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitAndSet.js @@ -1,16 +1,3 @@ -/** - * The default validation function that is to be used if one is not provided by - * the user. - * - * @param {*} expected - the right hand side of the simple equality statement. - * ie. the value that the selector was set to. - * @param {*} actual - the left hand side of the simple equality statement. - * ie. the value that was retrieved from the selector. - **/ -var DEFAULT_VALIDATE_FUNCTION = function(expected, actual) { - expect(actual).to.equal(expected); -}; - /** * Wait for the element identified by the provided selector to be visible and * then set it's value to the provided value. To more accurately simulate a user @@ -39,27 +26,27 @@ var DEFAULT_VALIDATE_FUNCTION = function(expected, actual) { * ] - The function that will be used to validate the value retrieved * from the selector if the validate argument is true. **/ -module.exports = function waitAndSet(selector, value, ms, click, validate, validateFunc) { - ms = ms || 5000; - click = click !== undefined ? click : true; - validate = validate !== undefined ? validate : true; - validateFunc = typeof validateFunc === 'function' ? validateFunc : DEFAULT_VALIDATE_FUNCTION; +// eslint-disable-next-line consistent-return +module.exports = function waitAndSet(selector, value, ms, click, validate) { + var timeOut = ms || 5000; + var thisClick = click !== undefined ? click : true; + var thisValidate = validate !== undefined ? validate : true; - if (click === true && validate === true) { - this.waitForVisible(selector, ms); + if (thisClick === true && thisValidate === true) { + this.waitForVisible(selector, timeOut); this.click(selector); this.setValue(selector, value); - return this.getValue(selector) - } else if (click === true && validate === false) { - this.waitForVisible(selector, ms); + return this.getValue(selector); + } else if (thisClick === true && thisValidate === false) { + this.waitForVisible(selector, timeOut); this.click(selector); return this.setValue(selector, value); - } else if (click === false && validate === true) { - this.waitForVisible(selector, ms); + } else if (thisClick === false && thisValidate === true) { + this.waitForVisible(selector, timeOut); this.setValue(selector, value); return this.getValue(selector); - } else if (click === false && validate === false) { - this.waitForVisible(selector, ms); + } else if (thisClick === false && thisValidate === false) { + this.waitForVisible(selector, timeOut); return this.setValue(selector, value); - } + } }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForChart.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForChart.js index a6053aad9a..ea911858eb 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForChart.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForChart.js @@ -1,14 +1,14 @@ /* * Wait for chart to load - * TODO: Find a better way to determine if chart is rendered + * TODO: Find a better way to determine if chart is rendered * - * @param {Number} [ms=3000] - Milliseconds to wait for chat to be visible + * @param {Number} [ms=9000] - Milliseconds to wait for chat to be visible * - * @uses commands/waitForVisible, protocol/pause + * @uses commands/waitForVisible, protocol/pause */ module.exports = function waitForChart(ms) { - ms = ms || 3000; + var timeOut = ms || 9000; - return this.waitForVisible(".ext-el-mask-msg", 9000, true) + return this.waitForVisible('.ext-el-mask-msg', timeOut, true); }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForInvisible.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForInvisible.js index eb8bc8360a..ac41338edb 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForInvisible.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForInvisible.js @@ -1,13 +1,13 @@ /* * Wait for selector to be invisible * - * @param {string} selector - element to check - * @param {Number} [ms=500] - Milliseconds to wait for element to be invisible + * @param {string} selector - element to check + * @param {Number} [ms=1000] - Milliseconds to wait for element to be invisible * - * @uses commands/waitForVisible + * @uses commands/waitForVisible */ module.exports = function waitForInvisible(selector, ms) { - ms = ms || 1000; - return this.waitForVisible(selector, ms, true); + var timeOut = ms || 1000; + return this.waitForVisible(selector, timeOut, true); }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForLoadedThenClick.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForLoadedThenClick.js index 630fba885d..117b8f7779 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForLoadedThenClick.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitForLoadedThenClick.js @@ -1,15 +1,13 @@ /* * Wait for loadingMask to not exist and selector to exist then click on selector * - * @param {string} selector - element to click on - * @param {Number} [maskMs=500] - Milliseconds to wait for mask to not exist - * @param {Number} [clickMs=500] - Milliseconds to wait for selector to be visible + * @param {string} selector - element to click on + * @param {Number} [maskMs=500] - Milliseconds to wait for mask to not exist * - * @uses commands/waitForVisible, helpers/waitAndClick + * @uses commands/waitForVisible, helpers/waitAndClick */ -module.exports = function waitForLoadedThenClick(selector, maskMs, clickMs){ - maskMs = maskMs || 9000; - clickMs = clickMs || 5000; - browser.waitForVisible(".ext-el-mask-msg", maskMs, true); - return browser.click(selector); +module.exports = function waitForLoadedThenClick(selector, maskMs) { + var maskTimeOut = maskMs || 9000; + browser.waitForVisible('.ext-el-mask-msg', maskTimeOut, true); + return browser.click(selector); }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEnd.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEnd.js index 1575c9f173..4603d65646 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEnd.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEnd.js @@ -2,31 +2,28 @@ * Wait for selector to stop animating, where animation is defined * as moving in the view. * - * @param {string} selector - element to click on - * @param {Number} [ms=9000] - Milliseconds to wait for element to be visible - * @param {Number} [interval=250] - interval between element location checks + * @param {string} selector - element to click on + * @param {Number} [ms=9000] - Milliseconds to wait for element to be visible + * @param {Number} [interval=250] - interval between element location checks * - * @uses commands/waitUntil commands/getLocationInView + * @uses commands/waitUntil commands/getLocationInView */ module.exports = function waitUntilAnimEnd(selector, ms, interval) { - ms = ms || 9000; - interval = interval || 250; + var timeOut = ms || 9000; + var checkInterval = interval || 250; - var initialLoc = {x: -1, y:-1}; + var initialLoc = { x: -1, y: -1 }; - this.waitForVisible(selector, ms) - return this.waitUntil(function() { - - var loc = this.getLocationInView(selector) - if(loc.x === initialLoc.x && loc.y === initialLoc.y) { + this.waitForVisible(selector, timeOut); + return this.waitUntil(function () { + var loc = this.getLocationInView(selector); + if (loc.x === initialLoc.x && loc.y === initialLoc.y) { return true; } - else { - initialLoc = loc; - } - return false; - }, ms, interval); + initialLoc = loc; + return false; + }, timeOut, checkInterval); }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEndAndClick.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEndAndClick.js index 530faab615..0e38270a39 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEndAndClick.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilAnimEndAndClick.js @@ -1,19 +1,19 @@ /* * Wait for selector to stop animating then click on it * - * @param {string} selector - element to click on - * @param {string} [button=left] which mouse key to use ["left", "middle", "right"] - * @param {Number} [ms=9000] - Milliseconds to wait for element to stop moving - * @param {Number} [interval=250] - interval between element location checks + * @param {string} selector - element to click on + * @param {string} [button=left] which mouse key to use ["left", "middle", "right"] + * @param {Number} [ms=9000] - Milliseconds to wait for element to stop moving + * @param {Number} [interval=250] - interval between element location checks * - * @uses waitUntilAnimEnd commands/buttonPress + * @uses waitUntilAnimEnd commands/buttonPress */ module.exports = function waitUntilAnimEndAndClick(selector, button, ms, interval) { - button = button || 'left'; - ms = ms || 9000; - interval = interval || 250; - this.waitUntilAnimEnd(selector, ms,interval); + var clickButton = button || 'left'; + var timeOut = ms || 9000; + var checkInterval = interval || 250; + this.waitUntilAnimEnd(selector, timeOut, checkInterval); this.moveToObject(selector); - return this.buttonPress(button); + return this.buttonPress(clickButton); }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilChartLoadsBySeries.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilChartLoadsBySeries.js index c4a8c860f4..1b151b2ae3 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilChartLoadsBySeries.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilChartLoadsBySeries.js @@ -6,9 +6,9 @@ * @param {Number} [ms=9000] - Milliseconds to wait for the element to **/ module.exports = function waitUntilChartLoadsBySeries(series, ms) { - ms = ms || 9000; - return this.waitForVisible( + var timeOut = ms || 9000; + return this.waitForVisible( "//*[local-name() = 'svg']//*[local-name() = 'g' and contains(@class, 'highcharts-axis')]//*[local-name() = 'tspan' and text()[contains(., '" + series + "')]]", - ms + timeOut ); }; diff --git a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilNotExist.js b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilNotExist.js index d859c6c345..1ecb98629c 100644 --- a/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilNotExist.js +++ b/open_xdmod/modules/xdmod/automated_tests/webdriverHelpers/waitUntilNotExist.js @@ -1,13 +1,13 @@ /* * Wait for selector to be visible then click on it * - * @param {string} selector - element to click on - * @param {Number} [ms=9000] - Milliseconds to wait for element to be visible + * @param {string} selector - element to click on + * @param {Number} [ms=9000] - Milliseconds to wait for element to be visible * - * @uses commands/waitForExist + * @uses commands/waitForExist */ module.exports = function waitUntilNotExist(selector, ms) { - ms = ms || 9000; - return this.waitForExist(selector, ms, true); + var timeOut = ms || 9000; + return this.waitForExist(selector, timeOut, true); };