diff --git a/.gitignore b/.gitignore index caf619d..09661b9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,9 @@ node_modules/ secrets.json tests/spec/ vendor/ +/MapView.js +MapView.js.map +/extentRouter.js +extentRouter.js.map +resources/MapView.css +resources/MapView.css.map diff --git a/ExtentRouter.js b/ExtentRouter.js deleted file mode 100644 index 884120b..0000000 --- a/ExtentRouter.js +++ /dev/null @@ -1,44 +0,0 @@ -// TODO: -// initRouter: function () { -// // summary: -// // sets up the url router for persisting the map extent -// console.log('agrc.widgets.map.BaseMap::initRouter', arguments); -// -// var that = this; -// var urlObj = ioQuery.queryToObject(hash()); -// var options = { -// scale: parseInt(urlObj.scale, 10), -// center: new Point({ -// x: parseInt(urlObj.x, 10), -// y: parseInt(urlObj.y, 10), -// spatialReference: {wkid: 3857} -// }) -// }; -// this.on('load', function () { -// if (urlObj.x && urlObj.y && urlObj.scale) { -// that.setScale(options.scale); -// that.centerAt(options.center); -// } -// that.on('extent-change', lang.hitch(that, 'updateExtentHash')); -// }); -// -// return (options.scale && options.center.x && options.center.y) ? options : {}; -// }, -// updateExtentHash: function () { -// // summary: -// // sets the extent props in the url hash -// console.log('agrc.widgets.map.BaseMap::updateExtentHash', arguments); -// -// var center = this.extent.getCenter(); -// if (center.x && center.y) { -// // mixin any existing url props to allow for other routers -// var newProps = lang.mixin(ioQuery.queryToObject(hash()), { -// x: Math.round(center.x), -// y: Math.round(center.y), -// scale: Math.round(this.getScale()) -// }); -// -// return hash(ioQuery.objectToQuery(newProps), true); -// } -// } -//# sourceMappingURL=ExtentRouter.js.map diff --git a/ExtentRouter.js.map b/ExtentRouter.js.map deleted file mode 100644 index fe51e8c..0000000 --- a/ExtentRouter.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["_src/ExtentRouter.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"ExtentRouter.js","sourcesContent":["// TODO:\n// initRouter: function () {\n// // summary:\n// // sets up the url router for persisting the map extent\n// console.log('agrc.widgets.map.BaseMap::initRouter', arguments);\n//\n// var that = this;\n// var urlObj = ioQuery.queryToObject(hash());\n// var options = {\n// scale: parseInt(urlObj.scale, 10),\n// center: new Point({\n// x: parseInt(urlObj.x, 10),\n// y: parseInt(urlObj.y, 10),\n// spatialReference: {wkid: 3857}\n// })\n// };\n// this.on('load', function () {\n// if (urlObj.x && urlObj.y && urlObj.scale) {\n// that.setScale(options.scale);\n// that.centerAt(options.center);\n// }\n// that.on('extent-change', lang.hitch(that, 'updateExtentHash'));\n// });\n//\n// return (options.scale && options.center.x && options.center.y) ? options : {};\n// },\n// updateExtentHash: function () {\n// // summary:\n// // sets the extent props in the url hash\n// console.log('agrc.widgets.map.BaseMap::updateExtentHash', arguments);\n//\n// var center = this.extent.getCenter();\n// if (center.x && center.y) {\n// // mixin any existing url props to allow for other routers\n// var newProps = lang.mixin(ioQuery.queryToObject(hash()), {\n// x: Math.round(center.x),\n// y: Math.round(center.y),\n// scale: Math.round(this.getScale())\n// });\n//\n// return hash(ioQuery.objectToQuery(newProps), true);\n// }\n// }\n"]} \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js index 89f9bf3..9b6e915 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -49,6 +49,14 @@ module.exports = function (grunt) { ] } }, + exec: { + main: { + cmd: 'node node_modules/jasmine/bin/jasmine.js --config=tests/e2e/jasmine.json' + }, + debug: { + cmd: 'DEBUG=true node node_modules/jasmine/bin/jasmine.js --config=tests/e2e/jasmine.json' + } + }, jasmine: { main: { options: { @@ -112,6 +120,17 @@ module.exports = function (grunt) { 'eslint', 'connect', 'babel', - 'jasmine' + 'jasmine', + 'exec:main' + ]); + + grunt.registerTask('e2e', [ + 'connect', + 'exec:main' + ]); + + grunt.registerTask('e2edebug', [ + 'connect', + 'exec:debug' ]); }; diff --git a/MapView.js b/MapView.js deleted file mode 100644 index 5fffa3f..0000000 --- a/MapView.js +++ /dev/null @@ -1,55 +0,0 @@ -define(['dijit/_TemplatedMixin', 'dijit/_WidgetBase', 'dojo/dom-class', 'dojo/dom-construct', 'dojo/query', 'dojo/text!./resources/templates/loader.html', 'dojo/_base/declare'], function (_TemplatedMixin, _WidgetBase, domClass, domConstruct, query, loaderTemplate, declare) { - return declare(null, { - // loader: DomNode - // the widget containing the loader animation - loader: null, - - constructor: function constructor(mapView) { - var _this = this; - - // summary: - // Customizes the esri map view in the following ways: - // - sets the extent to be the state of utah - // - "Powered by ESRI" -> "Powered by AGRC" - // - adds a loader - // mapView: esri/views/MapView - console.log('map-tools/MapView:constructor', arguments); - - mapView.extent = { - xmax: -11762120.612131765, - xmin: -13074391.513731329, - ymax: 5225035.106177688, - ymin: 4373832.359194187, - spatialReference: 3857 - - // wait until dom has been built - };mapView.when(function () { - // AGRC attribution - var poweredByDiv = query('.esri-attribution__powered-by', mapView.container)[0]; - domConstruct.empty(poweredByDiv); - poweredByDiv.innerHTML = 'Built by '; - domConstruct.create('a', { - href: 'https://gis.utah.gov', - innerHTML: 'AGRC', - target: '_blank', - 'class': 'esri-attribution__link' - }, poweredByDiv); - - // loader - required to be a widget so as to retain a reference to the dom node for use in toggleLoader - _this.loader = new (declare([_WidgetBase, _TemplatedMixin], { - templateString: loaderTemplate, - baseClass: 'hidden sk-double-bounce' - }))(); - mapView.ui.add(_this.loader, 'bottom-left'); - }); - }, - toggleLoader: function toggleLoader(show) { - // summary: - // toggles the visibility of the loader on the map - console.log('map-tools/Mapview:toggleLoader', arguments); - - domClass.toggle(this.loader.domNode, 'hidden', !show); - } - }); -}); -//# sourceMappingURL=MapView.js.map diff --git a/MapView.js.map b/MapView.js.map deleted file mode 100644 index 8cffba6..0000000 --- a/MapView.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["_src/MapView.js"],"names":["define","_TemplatedMixin","_WidgetBase","domClass","domConstruct","query","loaderTemplate","declare","loader","constructor","mapView","console","log","arguments","extent","xmax","xmin","ymax","ymin","spatialReference","when","poweredByDiv","container","empty","innerHTML","create","href","target","templateString","baseClass","ui","add","toggleLoader","show","toggle","domNode"],"mappings":"AAAAA,OAAO,CACH,uBADG,EAEH,mBAFG,EAIH,gBAJG,EAKH,oBALG,EAMH,YANG,EAOH,6CAPG,EAQH,oBARG,CAAP,EASG,UACCC,eADD,EAECC,WAFD,EAICC,QAJD,EAKCC,YALD,EAMCC,KAND,EAOCC,cAPD,EAQCC,OARD,EASD;AACE,WAAOA,QAAQ,IAAR,EAAc;AACjB;AACA;AACAC,gBAAQ,IAHS;;AAKjBC,mBALiB,uBAKLC,OALK,EAKI;AAAA;;AACjB;AACA;AACA;AACA;AACA;AACA;AACAC,oBAAQC,GAAR,CAAY,+BAAZ,EAA6CC,SAA7C;;AAEAH,oBAAQI,MAAR,GAAiB;AACbC,sBAAM,CAAC,kBADM;AAEbC,sBAAM,CAAC,kBAFM;AAGbC,sBAAM,iBAHO;AAIbC,sBAAM,iBAJO;AAKbC,kCAAkB;;AAGtB;AARiB,aAAjB,CASAT,QAAQU,IAAR,CAAa,YAAM;AACf;AACA,oBAAIC,eAAehB,MAAM,+BAAN,EAAuCK,QAAQY,SAA/C,EAA0D,CAA1D,CAAnB;AACAlB,6BAAamB,KAAb,CAAmBF,YAAnB;AACAA,6BAAaG,SAAb,GAAyB,WAAzB;AACApB,6BAAaqB,MAAb,CAAoB,GAApB,EAAyB;AACrBC,0BAAM,sBADe;AAErBF,+BAAW,MAFU;AAGrBG,4BAAQ,QAHa;AAIrB,6BAAS;AAJY,iBAAzB,EAKGN,YALH;;AAOA;AACA,sBAAKb,MAAL,GAAc,KAAKD,QAAQ,CAACL,WAAD,EAAcD,eAAd,CAAR,EAAwC;AACvD2B,oCAAgBtB,cADuC;AAEvDuB,+BAAW;AAF4C,iBAAxC,CAAL,GAAd;AAIAnB,wBAAQoB,EAAR,CAAWC,GAAX,CAAe,MAAKvB,MAApB,EAA4B,aAA5B;AACH,aAlBD;AAmBH,SA1CgB;AA2CjBwB,oBA3CiB,wBA2CJC,IA3CI,EA2CE;AACf;AACA;AACAtB,oBAAQC,GAAR,CAAY,gCAAZ,EAA8CC,SAA9C;;AAEAV,qBAAS+B,MAAT,CAAgB,KAAK1B,MAAL,CAAY2B,OAA5B,EAAqC,QAArC,EAA+C,CAACF,IAAhD;AACH;AAjDgB,KAAd,CAAP;AAmDH,CAtED","file":"MapView.js","sourcesContent":["define([\n 'dijit/_TemplatedMixin',\n 'dijit/_WidgetBase',\n\n 'dojo/dom-class',\n 'dojo/dom-construct',\n 'dojo/query',\n 'dojo/text!./resources/templates/loader.html',\n 'dojo/_base/declare'\n], function (\n _TemplatedMixin,\n _WidgetBase,\n\n domClass,\n domConstruct,\n query,\n loaderTemplate,\n declare\n) {\n return declare(null, {\n // loader: DomNode\n // the widget containing the loader animation\n loader: null,\n\n constructor(mapView) {\n // summary:\n // Customizes the esri map view in the following ways:\n // - sets the extent to be the state of utah\n // - \"Powered by ESRI\" -> \"Powered by AGRC\"\n // - adds a loader\n // mapView: esri/views/MapView\n console.log('map-tools/MapView:constructor', arguments);\n\n mapView.extent = {\n xmax: -11762120.612131765,\n xmin: -13074391.513731329,\n ymax: 5225035.106177688,\n ymin: 4373832.359194187,\n spatialReference: 3857\n }\n\n // wait until dom has been built\n mapView.when(() => {\n // AGRC attribution\n let poweredByDiv = query('.esri-attribution__powered-by', mapView.container)[0]\n domConstruct.empty(poweredByDiv);\n poweredByDiv.innerHTML = 'Built by ';\n domConstruct.create('a', {\n href: 'https://gis.utah.gov',\n innerHTML: 'AGRC',\n target: '_blank',\n 'class': 'esri-attribution__link'\n }, poweredByDiv);\n\n // loader - required to be a widget so as to retain a reference to the dom node for use in toggleLoader\n this.loader = new (declare([_WidgetBase, _TemplatedMixin], {\n templateString: loaderTemplate,\n baseClass: 'hidden sk-double-bounce'\n }))();\n mapView.ui.add(this.loader, 'bottom-left');\n });\n },\n toggleLoader(show) {\n // summary:\n // toggles the visibility of the loader on the map\n console.log('map-tools/Mapview:toggleLoader', arguments);\n\n domClass.toggle(this.loader.domNode, 'hidden', !show);\n }\n });\n});\n"]} \ No newline at end of file diff --git a/_SpecRunner.html b/_SpecRunner.html index 181f818..0ec198c 100644 --- a/_SpecRunner.html +++ b/_SpecRunner.html @@ -30,8 +30,6 @@ - - diff --git a/_src/ExtentRouter.js b/_src/ExtentRouter.js deleted file mode 100644 index adca4eb..0000000 --- a/_src/ExtentRouter.js +++ /dev/null @@ -1,43 +0,0 @@ -// TODO: -// initRouter: function () { -// // summary: -// // sets up the url router for persisting the map extent -// console.log('agrc.widgets.map.BaseMap::initRouter', arguments); -// -// var that = this; -// var urlObj = ioQuery.queryToObject(hash()); -// var options = { -// scale: parseInt(urlObj.scale, 10), -// center: new Point({ -// x: parseInt(urlObj.x, 10), -// y: parseInt(urlObj.y, 10), -// spatialReference: {wkid: 3857} -// }) -// }; -// this.on('load', function () { -// if (urlObj.x && urlObj.y && urlObj.scale) { -// that.setScale(options.scale); -// that.centerAt(options.center); -// } -// that.on('extent-change', lang.hitch(that, 'updateExtentHash')); -// }); -// -// return (options.scale && options.center.x && options.center.y) ? options : {}; -// }, -// updateExtentHash: function () { -// // summary: -// // sets the extent props in the url hash -// console.log('agrc.widgets.map.BaseMap::updateExtentHash', arguments); -// -// var center = this.extent.getCenter(); -// if (center.x && center.y) { -// // mixin any existing url props to allow for other routers -// var newProps = lang.mixin(ioQuery.queryToObject(hash()), { -// x: Math.round(center.x), -// y: Math.round(center.y), -// scale: Math.round(this.getScale()) -// }); -// -// return hash(ioQuery.objectToQuery(newProps), true); -// } -// } diff --git a/_src/MapView.js b/_src/MapView.js index 0073fcc..e30b72f 100644 --- a/_src/MapView.js +++ b/_src/MapView.js @@ -7,7 +7,7 @@ define([ 'dojo/query', 'dojo/text!./resources/templates/loader.html', 'dojo/_base/declare' -], function ( +], ( _TemplatedMixin, _WidgetBase, @@ -16,7 +16,7 @@ define([ query, loaderTemplate, declare -) { +) => { return declare(null, { // loader: DomNode // the widget containing the loader animation diff --git a/_src/extentRouter.js b/_src/extentRouter.js new file mode 100644 index 0000000..9de037d --- /dev/null +++ b/_src/extentRouter.js @@ -0,0 +1,72 @@ +define([ + 'dojo/hash', + 'dojo/io-query', + + 'esri/core/watchUtils', + 'esri/geometry/Point' +], ( + hash, + ioQuery, + + watchUtils, + Point +) => { + const updateExtentHash = (mapView) => { + // summary: + // sets the extent props in the url hash + // mapView: esri/views/mapView + console.log('map-tools/ExtentRouter:updateExtentHash', arguments); + + if ((!mapView.scale && !mapView.zoom) || !mapView.center) { + return; + } + + const center = mapView.center; + // mixin any existing url props to allow for other routers + const newProps = Object.assign(ioQuery.queryToObject(hash()), { + x: Math.round(center.x), + y: Math.round(center.y) + }); + + if (mapView.zoom) { + newProps.zoom = mapView.zoom; + } else { + newProps.scale = Math.rount(mapView.scale); + } + + return hash(ioQuery.objectToQuery(newProps), true); + }; + + return (mapView) => { + // summary: + // sets up the url router for persisting the map extent + // mapView: esri/views/mapView + console.log('map-tools/ExtentRouter:constructor', arguments); + + const urlObj = ioQuery.queryToObject(hash()); + const options = { + scale: parseInt(urlObj.scale, 10), + center: new Point({ + x: parseInt(urlObj.x, 10), + y: parseInt(urlObj.y, 10), + spatialReference: {wkid: 3857} + }), + zoom: parseInt(urlObj.zoom, 10) + }; + mapView.when(() => { + if (options.center.x && options.center.y && (options.scale || options.zoom)) { + if (options.zoom) { + mapView.zoom = options.zoom; + } else { + mapView.scale = options.scale; + } + + mapView.center = options.center; + } + watchUtils.whenTrue(mapView, 'stationary', updateExtentHash.bind(null, mapView)); + }); + + // return for unit tests assertion + return options; + }; +}); diff --git a/package-lock.json b/package-lock.json index d14bf3e..8960f12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,9 +54,9 @@ } }, "acorn": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.6.1.tgz", - "integrity": "sha512-XH4o5BK5jmw9PzSGK7mNf+/xV+mPxQxGZoeC36OVsJZYV77JAG9NnI7T90hoUpI/C1TOfXWTvugRdZ9ZR3iE2Q==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", + "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", "dev": true }, "acorn-jsx": { @@ -1087,9 +1087,9 @@ } }, "caniuse-lite": { - "version": "1.0.30000848", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000848.tgz", - "integrity": "sha512-9Hu5LvDZ+vTqHNDQXJpceg3YJZI2YFx+OuNDwLauoswT6dycZcSZ9NZIO3MJSLswRpR3HL1Pqitz0r6H6IdoCA==", + "version": "1.0.30000856", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000856.tgz", + "integrity": "sha512-x3mYcApHMQemyaHuH/RyqtKCGIYTgEA63fdi+VBvDz8xUSmRiVWTLeyKcoGQCGG6UPR9/+4qG4OKrTa6aSQRKg==", "dev": true }, "caseless": { @@ -1201,18 +1201,18 @@ "dev": true }, "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", "dev": true, "requires": { - "color-name": "^1.1.1" + "color-name": "1.1.1" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", "dev": true }, "colors": { @@ -1634,9 +1634,9 @@ } }, "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { "is-arrayish": "^0.2.1" @@ -2413,12 +2413,43 @@ "sprintf-js": "~1.0.3" }, "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, "lodash": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", "dev": true }, + "mime": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "dev": true + }, + "puppeteer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.4.0.tgz", + "integrity": "sha512-WDnC1FSHTedvRSS8BZB73tPAx2svUCWFdcxVjrybw8pbKOAB1v5S/pW0EamkqQoL1mXiBc+v8lyYjhhzMHIk1Q==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "extract-zip": "^1.6.5", + "https-proxy-agent": "^2.1.0", + "mime": "^2.0.3", + "progress": "^2.0.0", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^3.0.0" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -2491,6 +2522,12 @@ } } }, + "grunt-exec": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-3.0.0.tgz", + "integrity": "sha512-cgAlreXf3muSYS5LzW0Cc4xHK03BjFOYk0MqCQ/MZ3k1Xz2GU7D+IAJg4UKicxpO+XdONJdx/NJ6kpy2wI+uHg==", + "dev": true + }, "grunt-if-missing": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/grunt-if-missing/-/grunt-if-missing-1.0.1.tgz", @@ -3051,6 +3088,22 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "jasmine": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.1.0.tgz", + "integrity": "sha1-K9Wf1+xuwOistk4J9Fpo7SrRlSo=", + "dev": true, + "requires": { + "glob": "^7.0.6", + "jasmine-core": "~3.1.0" + } + }, + "jasmine-core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.1.0.tgz", + "integrity": "sha1-pHheE11d9lAk38kiSVPfWFvSdmw=", + "dev": true + }, "jasmine-favicon-reporter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/jasmine-favicon-reporter/-/jasmine-favicon-reporter-1.0.0.tgz", @@ -3523,20 +3576,19 @@ } }, "node-gyp": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", - "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.7.0.tgz", + "integrity": "sha512-qDQE/Ft9xXP6zphwx4sD0t+VhwV7yFaloMpfbL2QnnDZcyaiakWlLdtFGGQfTAwpFHdpbRhRxVhIHN1OKAjgbg==", "dev": true, "requires": { "fstream": "^1.0.0", "glob": "^7.0.3", "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", "mkdirp": "^0.5.0", "nopt": "2 || 3", "npmlog": "0 || 1 || 2 || 3 || 4", "osenv": "0", - "request": "2", + "request": ">=2.9.0 <2.82.0", "rimraf": "2", "semver": "~5.3.0", "tar": "^2.0.0", @@ -3779,9 +3831,9 @@ } }, "p-limit": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", - "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { "p-try": "^1.0.0" @@ -4077,19 +4129,19 @@ "dev": true }, "puppeteer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.4.0.tgz", - "integrity": "sha512-WDnC1FSHTedvRSS8BZB73tPAx2svUCWFdcxVjrybw8pbKOAB1v5S/pW0EamkqQoL1mXiBc+v8lyYjhhzMHIk1Q==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.5.0.tgz", + "integrity": "sha512-eELwFtFxL+uhmg4jPZOZXzSrPEYy4CaYQNbcchBbfxY+KjMpnv6XGf/aYWaQG49OTpfi2/DMziXtDM8XuJgoUA==", "dev": true, "requires": { "debug": "^3.1.0", - "extract-zip": "^1.6.5", - "https-proxy-agent": "^2.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^2.2.1", "mime": "^2.0.3", "progress": "^2.0.0", "proxy-from-env": "^1.0.0", "rimraf": "^2.6.1", - "ws": "^3.0.0" + "ws": "^5.1.1" }, "dependencies": { "debug": { @@ -4106,6 +4158,15 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", "dev": true + }, + "ws": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.0.tgz", + "integrity": "sha512-c18dMeW+PEQdDFzkhDsnBAlS4Z8KGStBQQUcQ5mf7Nf689jyGk0594L+i9RaQuf4gog6SvWLJorz2NfSaqxZ7w==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } } } }, @@ -4655,9 +4716,9 @@ "dev": true }, "sshpk": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", - "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", "dev": true, "requires": { "asn1": "~0.2.3", @@ -4667,6 +4728,7 @@ "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, "dependencies": { diff --git a/package.json b/package.json index 1e3d2d5..beb133b 100644 --- a/package.json +++ b/package.json @@ -24,14 +24,18 @@ "grunt-contrib-jasmine": "2.0.1", "grunt-contrib-watch": "^1.0.0", "grunt-eslint": "20.1.0", + "grunt-exec": "3.0.0", "grunt-if-missing": "^1", "grunt-sass": "2.1.0", + "jasmine": "3.1.0", "jasmine-favicon-reporter": "1.0.0", - "load-grunt-tasks": "4.0.0" + "load-grunt-tasks": "4.0.0", + "puppeteer": "1.5.0" }, "dojoBuild": "map-tools.profile.js", "scripts": { - "test": "grunt travis --verbose" + "test": "grunt travis --verbose", + "prepublish": "grunt sass && grunt babel" }, "dependencies": { "arcgis-js-api": "^4.7.x", diff --git a/resources/MapView.css b/resources/MapView.css deleted file mode 100644 index 7dc0a6e..0000000 --- a/resources/MapView.css +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Usage: - * -
-
-
-
- * - */ -.sk-double-bounce { - width: 40px; - height: 40px; - position: relative; - margin: 40px auto; } - .sk-double-bounce .sk-child { - width: 100%; - height: 100%; - border-radius: 50%; - background-color: #333; - opacity: 0.6; - position: absolute; - top: 0; - left: 0; - animation: sk-doubleBounce 2.0s infinite ease-in-out; } - .sk-double-bounce .sk-double-bounce2 { - animation-delay: -1.0s; } - -@keyframes sk-doubleBounce { - 0%, 100% { - transform: scale(0); } - 50% { - transform: scale(1); } } - -.sk-double-bounce { - margin: 0; - width: 30px; - height: 30px; } - .sk-double-bounce.hidden { - visibility: hidden; - display: none; } - .sk-double-bounce .sk-child { - opacity: 0.2; } - -/*# sourceMappingURL=MapView.css.map */ \ No newline at end of file diff --git a/resources/MapView.css.map b/resources/MapView.css.map deleted file mode 100644 index 39d7d5c..0000000 --- a/resources/MapView.css.map +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 3, - "file": "MapView.css", - "sources": [ - "MapView.scss", - "../node_modules/spinkit/scss/spinners/2-double-bounce.scss", - "../node_modules/spinkit/scss/_variables.scss" - ], - "names": [], - "mappings": "ACAA;;;;;;;;GAQG;AAGH,AAAA,iBAAiB,CAAC;EAChB,KAAK,ECXQ,IAAI;EDYjB,MAAM,ECZO,IAAI;EDajB,QAAQ,EAAE,QAAQ;EAClB,MAAM,ECfiB,IAAI,CAAC,IAAI,GDgCjC;EArBD,AAME,iBANe,CAMf,SAAS,CAAC;IACR,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,aAAa,EAAE,GAAG;IAClB,gBAAgB,ECnBI,IAAI;IDoBxB,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,SAAS,EAAE,yCAAyC,GACrD;EAhBH,AAkBE,iBAlBe,CAkBf,kBAAkB,CAAC;IACjB,eAAe,EAAE,KAAK,GACvB;;AAGH,UAAU,CAAV,eAAU;EACR,EAAE,EAAE,IAAI;IAAG,SAAS,EAAE,QAAQ;EAC9B,GAAG;IAAG,SAAS,EAAE,QAAU;;ADjC7B,AAAA,iBAAiB,CAAC;EACd,MAAM,EAAE,CAAC;EACT,KAAK,EAHD,IAAI;EAIR,MAAM,EAJF,IAAI,GAYX;EAXD,AAII,iBAJa,AAIZ,OAAO,CAAC;IACL,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,IAAI,GAChB;EAPL,AAQI,iBARa,CAQb,SAAS,CAAC;IACN,OAAO,EAAE,GAAG,GACf" -} \ No newline at end of file diff --git a/secrets.json.sample b/secrets.json.sample deleted file mode 100644 index f316f36..0000000 --- a/secrets.json.sample +++ /dev/null @@ -1,3 +0,0 @@ -{ - "quad_word": "" -} diff --git a/tests/ExtentRouterTests.html b/tests/ExtentRouterTests.html index 9eed572..d8de2ae 100644 --- a/tests/ExtentRouterTests.html +++ b/tests/ExtentRouterTests.html @@ -1,3 +1,88 @@ + + + ExtentRouter Tests + + + + + + + +
+ diff --git a/tests/e2e/Spec_extentRouter.js b/tests/e2e/Spec_extentRouter.js new file mode 100644 index 0000000..025f894 --- /dev/null +++ b/tests/e2e/Spec_extentRouter.js @@ -0,0 +1,98 @@ +const puppeteer = require('puppeteer'); +jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; + +describe('map-tools/ExtentRouter', function () { + let browser; + let page; + const testPage = 'http://localhost:8000/tests/ExtentRouterTests.html'; + + beforeAll(async () => { + browser = await puppeteer.launch({ + headless: !process.env.DEBUG, + slowMo: 200 + }); + page = await browser.newPage(); + }); + + afterAll(async () => { + if (!process.env.DEBUG) { + await browser.close(); + } + }); + + const waitForMapLoad = () => { + return page.waitForSelector('body.loaded'); + }; + + it('sets the initial map extent - zoom', async () => { + const x = -12447906; + const y = 4976212; + const zoom = 14; + await page.goto(`${testPage}#x=${x}&y=${y}&zoom=${zoom}`); + await waitForMapLoad(); + + const props = await page.evaluate(() => window.getMapViewProps()); + + expect(props.zoom).toBe(zoom); + expect(props.center.x).toBeCloseTo(x, 0); + expect(props.center.y).toBeCloseTo(y, 0); + }); + + it('sets the initial map extent - scale', async () => { + const x = -12447906; + const y = 4976212; + const scale = 36111; + await page.goto(`${testPage}#x=${x}&y=${y}&scale=${scale}`); + await waitForMapLoad(); + + const props = await page.evaluate(() => window.getMapViewProps()); + + expect(props.scale).toBeCloseTo(scale, -1); + expect(props.center.x).toBeCloseTo(x, 0); + expect(props.center.y).toBeCloseTo(y, 0); + }); + + it('updates the URL hash on map extent change', async () => { + const target = { + x: -12512327, + y: 4798937, + spatialReference: { wkid: 3857 } + }; + const zoom = 15; + + await page.goto(testPage); + + await waitForMapLoad(); + + await page.evaluate((param1, param2) => window.zoomTo(param1, param2), target, zoom); + + await page.waitFor(200); + + const url = page.url(); + + expect(url).toMatch(new RegExp(`zoom=${zoom}`)); + expect(url).toMatch(new RegExp(`x=${target.x}`)); + expect(url).toMatch(new RegExp(`y=${target.y}`)); + }); + + it('preserves other url parameters', async () => { + const target = { + x: -12512327, + y: 4798937, + spatialReference: { wkid: 3857 } + }; + const zoom = 15; + + await page.goto(`${testPage}?test=1`); + + await waitForMapLoad(); + + await page.evaluate((param1, param2) => window.zoomTo(param1, param2), target, zoom); + + await page.waitFor(200); + + const url = page.url(); + + expect(url).toMatch(/test=1/); + }); +}); diff --git a/tests/e2e/jasmine.json b/tests/e2e/jasmine.json new file mode 100644 index 0000000..f14ebaf --- /dev/null +++ b/tests/e2e/jasmine.json @@ -0,0 +1,8 @@ +{ + "spec_dir": "tests/e2e", + "spec_files": [ + "[sS]pec*.js" + ], + "stopSpecOnExpectationFailure": false, + "random": false +}