From ad482600de30cefe19a7bbc273e23eaeca1539b4 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 30 Jul 2015 15:32:17 -0700 Subject: [PATCH 01/40] [Documentation] Begin adding doc generator Begin adding Markdown->HTML documentation generation with nomnoml embedded diagram support. MissionControl/vista#21 --- docsrc/gendocs.js | 109 ++++++++++++++++++++++++++++++++++++++++++ docsrc/guide/index.md | 3 ++ docsrc/index.html | 33 +++++++++++++ package.json | 10 +++- 4 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 docsrc/gendocs.js create mode 100644 docsrc/guide/index.md create mode 100644 docsrc/index.html diff --git a/docsrc/gendocs.js b/docsrc/gendocs.js new file mode 100644 index 0000000000..03309cd65e --- /dev/null +++ b/docsrc/gendocs.js @@ -0,0 +1,109 @@ +/*global require,process,GLOBAL*/ +/*jslint nomen: true*/ + + +var CONSTANTS = { + DIAGRAM_WIDTH: 800, + DIAGRAM_HEIGHT: 500 + }; + +GLOBAL.window = GLOBAL.window || {}; // nomnoml expects window to be defined +(function () { + "use strict"; + + var fs = require("fs"), + mkdirp = require("mkdirp"), + path = require("path"), + glob = require("glob"), + showdown = require("github-flavored-markdown"), + split = require("split"), + stream = require("stream"), + nomnoml = require('nomnoml'), + Canvas = require('canvas'), + options = require("minimist")(process.argv.slice(2)); + + function renderNomnoml(source, target) { + var canvas = + new Canvas(CONSTANTS.DIAGRAM_WIDTH, CONSTANTS.DIAGRAM_HEIGHT); + nomnoml.draw(canvas, source, 1.0); + canvas.pngStream().pipe(fs.createWriteStream(target)); + } + + function nomnomlifier(outputDirectory, prefix) { + var transform = new stream.Transform({ objectMode: true }), + isBuilding = false, + counter = 1, + outputPath, + source = ""; + + transform._transform = function (chunk, encoding, done) { + if (isBuilding) { + if (chunk.trim().indexOf("```nomnoml") === 0) { + var outputFilename = prefix + '-' + counter + '.png'; + outputPath = path.join(outputDirectory, outputFilename); + this.push([ + "\n![Diagram ", + counter, + "](", + outputFilename, + ")\n\n" + ].join("")); + isBuilding = true; + source = ""; + } else { + // Otherwise, pass through + this.push(chunk); + } + } else { + if (chunk.trim() === "```") { + // End nomnoml + renderNomnoml(source, outputPath); + isBuilding = false; + } else { + source += chunk; + } + } + }; + + return transform; + } + + function concat() { + + } + + function gfmifier() { + var transform = new stream.Transform({ objectMode: true }), + markdown = ""; + transform._transform = function (chunk, encoding, done) { + markdown += chunk; + }; + transform._flush = function () { + this.push(markdown); + }; + return transform; + } + + options['in'] = options['in'] || options.i; + options.out = options.out || options.o; + + glob(options['in'] + "/**/*.md", {}, function (err, files) { + files.forEach(function (file) { + var destination = file.replace(options['in'], options.out) + .replace(/md$/, "html"), + destPath = path.dirname(destination), + prefix = path.basename(destination).replace(/\.html$/, ""); + + mkdirp(destPath, function (err) { + fs.createReadStream(file, { encoding: 'utf8' }) + .pipe(split()) + .pipe(nomnomlifier(destPath, prefix)) + .pipe(gfmifier()) + .pipe(fs.createWriteStream(destination, { + encoding: 'utf8' + })); + }); + }); + }); + +}()); diff --git a/docsrc/guide/index.md b/docsrc/guide/index.md new file mode 100644 index 0000000000..0f72139a24 --- /dev/null +++ b/docsrc/guide/index.md @@ -0,0 +1,3 @@ +# Hello, world! + +This is a placeholder for the developer guide. diff --git a/docsrc/index.html b/docsrc/index.html new file mode 100644 index 0000000000..23e92c21cb --- /dev/null +++ b/docsrc/index.html @@ -0,0 +1,33 @@ + + + + + + Open MCT Web Documentation + + + API + Developer Guide + Architecture Overview + + diff --git a/package.json b/package.json index 1216935f21..350bc7faa3 100644 --- a/package.json +++ b/package.json @@ -16,13 +16,19 @@ "karma-jasmine": "^0.1.5", "karma-phantomjs-launcher": "^0.1.4", "karma-requirejs": "^0.2.2", - "requirejs": "^2.1.17" + "requirejs": "^2.1.17", + "github-flavored-markdown": ">= 1.0.0", + "glob": ">= 3.0.0", + "split": "^1.0.0", + "mkdirp": "^0.5.1", + "nomnoml": "^0.0.3", + "canvas": "^1.2.7" }, "scripts": { "start": "node app.js", "test": "karma start --single-run", "jshint": "jshint platform example || exit 0", - "jsdoc": "jsdoc -c jsdoc.json -r -d docs" + "jsdoc": "jsdoc -c jsdoc.json -r -d docs/api" }, "repository": { "type": "git", From ee64ef5fc1829ce93b7c041f09dcdfaa262afeea Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 30 Jul 2015 16:16:33 -0700 Subject: [PATCH 02/40] [Documentation] Generate docs with diagram Convert Markdown+nomnoml -> HTML+PNG for MissionControl/vista#21 --- docsrc/gendocs.js | 22 ++++++++++++---------- docsrc/guide/index.md | 9 +++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/docsrc/gendocs.js b/docsrc/gendocs.js index 03309cd65e..c738c7ddb2 100644 --- a/docsrc/gendocs.js +++ b/docsrc/gendocs.js @@ -7,7 +7,7 @@ var CONSTANTS = { DIAGRAM_HEIGHT: 500 }; -GLOBAL.window = GLOBAL.window || {}; // nomnoml expects window to be defined +GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be defined (function () { "use strict"; @@ -37,7 +37,7 @@ GLOBAL.window = GLOBAL.window || {}; // nomnoml expects window to be defined source = ""; transform._transform = function (chunk, encoding, done) { - if (isBuilding) { + if (!isBuilding) { if (chunk.trim().indexOf("```nomnoml") === 0) { var outputFilename = prefix + '-' + counter + '.png'; outputPath = path.join(outputDirectory, outputFilename); @@ -50,9 +50,10 @@ GLOBAL.window = GLOBAL.window || {}; // nomnoml expects window to be defined ].join("")); isBuilding = true; source = ""; + counter += 1; } else { // Otherwise, pass through - this.push(chunk); + this.push(chunk + '\n'); } } else { if (chunk.trim() === "```") { @@ -60,26 +61,27 @@ GLOBAL.window = GLOBAL.window || {}; // nomnoml expects window to be defined renderNomnoml(source, outputPath); isBuilding = false; } else { - source += chunk; + source += chunk + '\n'; } } + done(); }; return transform; } - function concat() { - - } - function gfmifier() { var transform = new stream.Transform({ objectMode: true }), markdown = ""; transform._transform = function (chunk, encoding, done) { markdown += chunk; + done(); }; - transform._flush = function () { - this.push(markdown); + transform._flush = function (done) { + this.push("\n"); + this.push(showdown.parse(markdown)); + this.push("\n\n"); + done(); }; return transform; } diff --git a/docsrc/guide/index.md b/docsrc/guide/index.md index 0f72139a24..c826f4926b 100644 --- a/docsrc/guide/index.md +++ b/docsrc/guide/index.md @@ -1,3 +1,12 @@ # Hello, world! This is a placeholder for the developer guide. + +```nomnoml +[ Start]->[ Load bundles.json] +[Load bundles.json]->[ Load bundle.json files] +[Load bundle.json files]->[ Resolve implementations] +[Resolve implementations]->[ Register with Angular] +[Register with Angular]->[ Bootstrap application] +[Bootstrap application]->[ End] +``` From 64e2de7aa6712391f5783176301247aa07c10978 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 30 Jul 2015 16:36:17 -0700 Subject: [PATCH 03/40] [Documentation] Add a build step Support generation of non-API docs using npm run docs. Supports MissionControl/vista#21 --- docsrc/architecture/index.md | 12 ++++++++++++ docsrc/gendocs.js | 15 +++++++++++++++ docsrc/guide/index.md | 9 --------- package.json | 4 +++- 4 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 docsrc/architecture/index.md diff --git a/docsrc/architecture/index.md b/docsrc/architecture/index.md new file mode 100644 index 0000000000..cbda4c46c5 --- /dev/null +++ b/docsrc/architecture/index.md @@ -0,0 +1,12 @@ +# Introduction + +This is a placeholder for an architectural description of Open MCT Web. + +```nomnoml +[ Start]->[ Load bundles.json] +[Load bundles.json]->[ Load bundle.json files] +[Load bundle.json files]->[ Resolve implementations] +[Resolve implementations]->[ Register with Angular] +[Register with Angular]->[ Bootstrap application] +[Bootstrap application]->[ End] +``` diff --git a/docsrc/gendocs.js b/docsrc/gendocs.js index c738c7ddb2..9f8954fc18 100644 --- a/docsrc/gendocs.js +++ b/docsrc/gendocs.js @@ -108,4 +108,19 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define }); }); + // Also copy over all HTML files + glob(options['in'] + "/**/*.html", {}, function (err, files) { + files.forEach(function (file) { + var destination = file.replace(options['in'], options.out), + destPath = path.dirname(destination); + + mkdirp(destPath, function (err) { + fs.createReadStream(file, { encoding: 'utf8' }) + .pipe(fs.createWriteStream(destination, { + encoding: 'utf8' + })); + }); + }); + }); + }()); diff --git a/docsrc/guide/index.md b/docsrc/guide/index.md index c826f4926b..0f72139a24 100644 --- a/docsrc/guide/index.md +++ b/docsrc/guide/index.md @@ -1,12 +1,3 @@ # Hello, world! This is a placeholder for the developer guide. - -```nomnoml -[ Start]->[ Load bundles.json] -[Load bundles.json]->[ Load bundle.json files] -[Load bundle.json files]->[ Resolve implementations] -[Resolve implementations]->[ Register with Angular] -[Register with Angular]->[ Bootstrap application] -[Bootstrap application]->[ End] -``` diff --git a/package.json b/package.json index 350bc7faa3..d594817ed2 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,9 @@ "start": "node app.js", "test": "karma start --single-run", "jshint": "jshint platform example || exit 0", - "jsdoc": "jsdoc -c jsdoc.json -r -d docs/api" + "jsdoc": "jsdoc -c jsdoc.json -r -d docs/api", + "otherdoc": "node docsrc/gendocs.js --in docsrc --out docs", + "docs": "npm run jsdoc ; npm run otherdoc" }, "repository": { "type": "git", From a4c704a5a2cea4bc0573bccaf4f559707aaabd09 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 3 Aug 2015 12:18:49 -0700 Subject: [PATCH 04/40] [Layout] Ensure minimum frame size Ensure default frame size in a layout is not small, even if the grid size for the layout is very small. WTD-1424. --- .../features/layout/src/LayoutController.js | 30 +++++++++++++++++-- .../layout/test/LayoutControllerSpec.js | 17 +++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/platform/features/layout/src/LayoutController.js b/platform/features/layout/src/LayoutController.js index 1c58f92988..622508f939 100644 --- a/platform/features/layout/src/LayoutController.js +++ b/platform/features/layout/src/LayoutController.js @@ -27,7 +27,8 @@ define( "use strict"; var DEFAULT_DIMENSIONS = [ 12, 8 ], - DEFAULT_GRID_SIZE = [32, 32]; + DEFAULT_GRID_SIZE = [32, 32], + MINIMUM_FRAME_SIZE = [ 320, 180 ]; /** * The LayoutController is responsible for supporting the @@ -67,12 +68,22 @@ define( }; } + // Generate default positions for a new panel + function defaultDimensions() { + return MINIMUM_FRAME_SIZE.map(function (min, i) { + return Math.max( + Math.ceil(min / gridSize[i]), + DEFAULT_DIMENSIONS[i] + ); + }); + } + // Generate a default position (in its raw format) for a frame. // Use an index to ensure that default positions are unique. function defaultPosition(index) { return { position: [index, index], - dimensions: DEFAULT_DIMENSIONS + dimensions: defaultDimensions() }; } @@ -107,6 +118,18 @@ define( ids.forEach(populatePosition); } + // Update grid size when it changed + function updateGridSize(layoutGrid) { + var oldSize = gridSize; + + gridSize = layoutGrid || DEFAULT_GRID_SIZE; + + // Only update panel positions if this actually changed things + if (gridSize[0] !== oldSize[0] || gridSize[1] !== oldSize[1]) { + lookupPanels(Object.keys(positions)); + } + } + // Position a panel after a drop event function handleDrop(e, id, position) { if (e.defaultPrevented) { @@ -138,6 +161,9 @@ define( e.preventDefault(); } + // Watch for changes to the grid size in the model + $scope.$watch("model.layoutGrid", updateGridSize); + // Position panes when the model field changes $scope.$watch("model.composition", lookupPanels); diff --git a/platform/features/layout/test/LayoutControllerSpec.js b/platform/features/layout/test/LayoutControllerSpec.js index 5ec80755f4..b0ab7a13fb 100644 --- a/platform/features/layout/test/LayoutControllerSpec.js +++ b/platform/features/layout/test/LayoutControllerSpec.js @@ -175,6 +175,23 @@ define( ); expect(testConfiguration.panels.d).not.toBeDefined(); }); + + it("ensures a minimum frame size", function () { + var styleB, styleC; + + // Start with a very small frame size + testModel.layoutGrid = [ 1, 1 ]; + + // White-boxy; we know which watch is which + mockScope.$watch.calls[0].args[1](testModel.layoutGrid); + mockScope.$watch.calls[1].args[1](testModel.composition); + + styleB = controller.getFrameStyle("b"); + + // Resulting size should still be reasonably large pixel-size + expect(parseInt(styleB.width, 10)).toBeGreaterThan(63); + expect(parseInt(styleB.width, 10)).toBeGreaterThan(31); + }); }); } ); From 867b5f726ace018dfca9b2563f4999bb22f233e5 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 3 Aug 2015 12:33:20 -0700 Subject: [PATCH 05/40] [Documentation] Changes doc output directory MissionControl/vista#21 --- {docsrc => docs}/architecture/index.md | 0 {docsrc => docs}/gendocs.js | 0 {docsrc => docs}/guide/index.md | 0 {docsrc => docs}/index.html | 0 package.json | 4 ++-- 5 files changed, 2 insertions(+), 2 deletions(-) rename {docsrc => docs}/architecture/index.md (100%) rename {docsrc => docs}/gendocs.js (100%) rename {docsrc => docs}/guide/index.md (100%) rename {docsrc => docs}/index.html (100%) diff --git a/docsrc/architecture/index.md b/docs/architecture/index.md similarity index 100% rename from docsrc/architecture/index.md rename to docs/architecture/index.md diff --git a/docsrc/gendocs.js b/docs/gendocs.js similarity index 100% rename from docsrc/gendocs.js rename to docs/gendocs.js diff --git a/docsrc/guide/index.md b/docs/guide/index.md similarity index 100% rename from docsrc/guide/index.md rename to docs/guide/index.md diff --git a/docsrc/index.html b/docs/index.html similarity index 100% rename from docsrc/index.html rename to docs/index.html diff --git a/package.json b/package.json index d594817ed2..dae336c88b 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,8 @@ "start": "node app.js", "test": "karma start --single-run", "jshint": "jshint platform example || exit 0", - "jsdoc": "jsdoc -c jsdoc.json -r -d docs/api", - "otherdoc": "node docsrc/gendocs.js --in docsrc --out docs", + "jsdoc": "jsdoc -c jsdoc.json -r -d target/docs/api", + "otherdoc": "node docs/gendocs.js --in docs --out target/docs", "docs": "npm run jsdoc ; npm run otherdoc" }, "repository": { From ff5e7486bc1578007daa220455b2c02fe23462bb Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 3 Aug 2015 12:46:47 -0700 Subject: [PATCH 06/40] [Documentation] Move doc sources Move doc sources to docs/src MissionControl/vista#21 --- docs/{ => src}/architecture/index.md | 0 docs/{ => src}/guide/index.md | 0 docs/{ => src}/index.html | 0 package.json | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) rename docs/{ => src}/architecture/index.md (100%) rename docs/{ => src}/guide/index.md (100%) rename docs/{ => src}/index.html (100%) diff --git a/docs/architecture/index.md b/docs/src/architecture/index.md similarity index 100% rename from docs/architecture/index.md rename to docs/src/architecture/index.md diff --git a/docs/guide/index.md b/docs/src/guide/index.md similarity index 100% rename from docs/guide/index.md rename to docs/src/guide/index.md diff --git a/docs/index.html b/docs/src/index.html similarity index 100% rename from docs/index.html rename to docs/src/index.html diff --git a/package.json b/package.json index dae336c88b..df7a7f9529 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "test": "karma start --single-run", "jshint": "jshint platform example || exit 0", "jsdoc": "jsdoc -c jsdoc.json -r -d target/docs/api", - "otherdoc": "node docs/gendocs.js --in docs --out target/docs", + "otherdoc": "node docs/gendocs.js --in docs/src --out target/docs", "docs": "npm run jsdoc ; npm run otherdoc" }, "repository": { From ae7fc27c9ebac889218d33777d71d09b8ae862e2 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 3 Aug 2015 12:49:35 -0700 Subject: [PATCH 07/40] [Documentation] Copy over css, png files ...in addition to .html files. MissionControl/vista#21 --- docs/gendocs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/gendocs.js b/docs/gendocs.js index 9f8954fc18..6fe71f1347 100644 --- a/docs/gendocs.js +++ b/docs/gendocs.js @@ -108,8 +108,8 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define }); }); - // Also copy over all HTML files - glob(options['in'] + "/**/*.html", {}, function (err, files) { + // Also copy over all HTML, CSS, or PNG files + glob(options['in'] + "/**/*.@(html|css|png)", {}, function (err, files) { files.forEach(function (file) { var destination = file.replace(options['in'], options.out), destPath = path.dirname(destination); From 4240e8843ba93ec1892f19941a707393a0c88762 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 09:52:09 -0700 Subject: [PATCH 08/40] [Documentation] Begin adding arch diagrams MissionControl/vista#21 --- docs/src/architecture/index.md | 76 ++++++++++++++++++++++++++++++---- docs/src/index.html | 8 ++-- 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/docs/src/architecture/index.md b/docs/src/architecture/index.md index cbda4c46c5..62d58262ab 100644 --- a/docs/src/architecture/index.md +++ b/docs/src/architecture/index.md @@ -1,12 +1,74 @@ # Introduction -This is a placeholder for an architectural description of Open MCT Web. +The purpose of this document is to familiarize developers with the +overall architecture of Open MCT Web. + +The target audience includes: + +* _Platform maintainers_: Individuals involved in developing, + extending, and maintaing capabilities of the platform. +* _Integration developers_: Individuals tasked with integrated + Open MCT Web into a larger system, who need to understand + its inner workings sufficiently to complete this integration. + +# Overview + +Open MCT Web is client software: It runs in a web browser and +provides a user interface, while communicating with various +server-side resources through browser APIs. ```nomnoml -[ Start]->[ Load bundles.json] -[Load bundles.json]->[ Load bundle.json files] -[Load bundle.json files]->[ Resolve implementations] -[Resolve implementations]->[ Register with Angular] -[Register with Angular]->[ Bootstrap application] -[Bootstrap application]->[ End] +#direction: right +[Client|[Browser|[Open MCT Web]->[Browser APIs]]] +[Server|[Web services]] +[Client]<->[Server] ``` + +While Open MCT Web can be configured to run as a standalone client, +this is rarely very useful. Instead, it is intended to be used as a +display and interaction layer for information obtained from a +variety of back-end services. Doing so requires authoring or utilizing +adapter plugins which allow Open MCT Web to interact with these services. + +Typically, the pattern here is to provide a known interface that +Open MCT Web can utilize, and implement it such that it interacts with +whatever back-end provides the relevant information. +Examples of back-ends that can be utilized in this fashion include +databases for the persistence of user-created objects, or sources of +telemetry data. + +## Software Architecture + +The simplest overview of Open MCT Web is to look at it as a "layered" +architecture, where each layer more clearly specifies the behavior +of the software. + +```nomnoml +#direction: down +[Open MCT Web| + [Platform]<->[Application] + [Framework]->[Application] + [Framework]->[Platform] +] +``` + +These layers are: + +* [_Framework_](Framework.html): The framework layer is responsible for + managing the interactions between application components. It has no + application-specific knowledge; at this layer, we have only + established an abstraction by which different software components + may communicate and/or interact. +* _Platform_: The platform layer defines the general look, feel, and + behavior of Open MCT Web. This includes user-facing components like + Browse mode and Edit mode, as well as underlying elements of the + information model and the general service infrastructure. +* _Application_: The application layer defines specific features of + an application built on Open MCT Web. This includes adapters to + specific back-ends, new types of things for users to create, and + new ways of visualizing objects within the system. This layer + typically consists of a mix of custom plug-ins to Open MCT Web, + as well as optional features (such as Plot view) included alongside + the platform. + + diff --git a/docs/src/index.html b/docs/src/index.html index 23e92c21cb..fce129f9ce 100644 --- a/docs/src/index.html +++ b/docs/src/index.html @@ -26,8 +26,10 @@ Open MCT Web Documentation - API - Developer Guide - Architecture Overview + From 4803eef90768a31cfe8f0ec8507bfae4446dfcb7 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 09:55:15 -0700 Subject: [PATCH 09/40] [Documentation] Add initial arch. docs Add initial architecture docs; remove docs folder from gitignore, as the generated docs (which should be ignored) have been moved to target/docs. MissionControl/vista#21. --- .gitignore | 3 -- docs/src/architecture/Framework.md | 73 ++++++++++++++++++++++++++++++ docs/src/architecture/Platform.md | 0 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 docs/src/architecture/Framework.md create mode 100644 docs/src/architecture/Platform.md diff --git a/.gitignore b/.gitignore index 2863ec0cb7..d815ed2081 100644 --- a/.gitignore +++ b/.gitignore @@ -20,9 +20,6 @@ closed-lib # Node dependencies node_modules -# Build documentation -docs - # Protractor logs protractor/logs diff --git a/docs/src/architecture/Framework.md b/docs/src/architecture/Framework.md new file mode 100644 index 0000000000..76ea473789 --- /dev/null +++ b/docs/src/architecture/Framework.md @@ -0,0 +1,73 @@ +#Overview + +The framework layer's most basic responsibility is allowing individual +software components to communicate. The software components it recognizes +are: + +* _Extensions_: Individual units of functionality that can be added to + or removed from Open MCT Web. _Extension categories_ distinguish what + type of functionality is being added/removed. +* _Bundles_: A grouping of related extensions + (named after an analogous concept from [OSGi](http://www.osgi.org/)) + that may be added or removed as a group. + +The framework layer operates by taking a set of active bundles, and +exposing extensions to one another as-needed, using +[dependency injection](https://en.wikipedia.org/wiki/Dependency_injection). +Extensions are responsible for declaring their dependencies in a +manner which the framework layer can understand. + +```nomnoml +#direction: down +[Open MCT Web| + [Dependency injection framework]-->[Platform bundle #1] + [Dependency injection framework]-->[Platform bundle #2] + [Dependency injection framework]-->[Plugin bundle #1] + [Dependency injection framework]-->[Plugin bundle #2] + [Platform bundle #1|[Extensions]] + [Platform bundle #2|[Extensions]] + [Plugin bundle #1|[Extensions]] + [Plugin bundle #2|[Extensions]] + [Platform bundle #1]<->[Platform bundle #2] + [Plugin bundle #1]<->[Platform bundle #2] + [Plugin bundle #1]<->[Plugin bundle #2] +] +``` + +The "dependency injection framework" in this case is +[AngularJS](https://angularjs.org/). Open MCT Web's framework layer +is really just a thin wrapper over Angular that recognizes the +concepts of bundles and extensions (as declared in JSON files) and +registering extensions with Angular. It additionally acts as a +mediator between Angular and [RequireJS](http://requirejs.org/), +which is used to load JavaScript sources which implement +extensions. + +```nomnoml +[Framework layer| + [AngularJS]<-[Framework Component] + [RequireJS]<-[Framework Component] + [Framework Component]1o-*[Bundles] +] +``` + +It is worth noting that _no other components_ are "aware" of the +framework component directly; Angular and Require are _used by_ the +framework components, and extensions in various bundles will have +their dependencies satisfied by Angular as a consequence of registration +activities which were performed by the framework component. + + +## Application Initialization + +The framework component initializes an Open MCT Web application following +a simple sequence of steps. + +```nomnoml +[ Start]->[ Load bundles.json] +[Load bundles.json]->[ Load bundle.json files] +[Load bundle.json files]->[ Resolve implementations] +[Resolve implementations]->[ Register with Angular] +[Register with Angular]->[ Bootstrap application] +[Bootstrap application]->[ End] +``` diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md new file mode 100644 index 0000000000..e69de29bb2 From 2ca3c6ea93b41013b6f3ea8fa4a72dfa5fd4e5b8 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 10:00:44 -0700 Subject: [PATCH 10/40] [Layout] Use consistent whitespace Use consistent whitespace in array literals, WTD-1424. --- platform/features/layout/src/LayoutController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/features/layout/src/LayoutController.js b/platform/features/layout/src/LayoutController.js index 622508f939..643ed952a3 100644 --- a/platform/features/layout/src/LayoutController.js +++ b/platform/features/layout/src/LayoutController.js @@ -27,7 +27,7 @@ define( "use strict"; var DEFAULT_DIMENSIONS = [ 12, 8 ], - DEFAULT_GRID_SIZE = [32, 32], + DEFAULT_GRID_SIZE = [ 32, 32 ], MINIMUM_FRAME_SIZE = [ 320, 180 ]; /** From 503bae661cb5ffd9f99f211267911feeb13ab08e Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 13:15:19 -0700 Subject: [PATCH 11/40] [Documentation] Add more description to framework MissionControl/vista#21 --- docs/src/architecture/Framework.md | 39 +++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/src/architecture/Framework.md b/docs/src/architecture/Framework.md index 76ea473789..c0a3e4990b 100644 --- a/docs/src/architecture/Framework.md +++ b/docs/src/architecture/Framework.md @@ -1,4 +1,6 @@ -#Overview +# Framework Architecture + +## Overview The framework layer's most basic responsibility is allowing individual software components to communicate. The software components it recognizes @@ -71,3 +73,38 @@ a simple sequence of steps. [Register with Angular]->[ Bootstrap application] [Bootstrap application]->[ End] ``` + +## Architectural Paradigm + +Open MCT Web's architecture relies on a simple premise: Individual units +(extensions) only have access to the dependencies they declare that they +need, and they acquire references to these dependencies via dependency +injection. This has several desirable traits: + +* Programming to an interface is enforced. Any given dependency can be + swapped out for something which exposes an equivalent interface. This + improves flexibility against refactoring, simplifies testing, and + provides a common mechanism for extension and reconfiguration. +* The dependencies of a unit must be explicitly defined. This means that + it can be easily determined what a given unit's role is within the + larger system, in terms of what other components it will interact with. + It also helps to enforce good separation of concerns: When a set of + declared dependencies becomes long it is obvious, and this is usually + a sign that a given unit is involved in too many concerns and should + be refactored into smaller pieces. +* Individual units do not need to be aware of the framework; they need + only be aware of the interfaces to the components they specifically + use. This avoids introducing a ubiquitous dependency upon the framework + layer itself; it is plausible to modify or replace the framework + without making changes to individual software components which run upon + the framework. + +A drawback to this approach is that it makes it difficult to define +"the architecture" of Open MCT Web, in terms of describing the specific +units that interact at run-time. The run-time architecture is determined +by the framework as the consequence of wiring together dependencies. +As such, the specific architecture of any given application built on +Open MCT Web can look very different. + +The specific service infrastructure provided by the platform is described +in the [Platform Architecture](Platform.html). \ No newline at end of file From 55d52d060a3681a67b83caf5728203c33135e665 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 13:20:19 -0700 Subject: [PATCH 12/40] [Documentation] Switch to marked Switch markdown generator to something more up-to-date, MissionControl/vista#21. --- docs/gendocs.js | 15 +++++++++++++-- package.json | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/gendocs.js b/docs/gendocs.js index 6fe71f1347..26816ba703 100644 --- a/docs/gendocs.js +++ b/docs/gendocs.js @@ -15,7 +15,7 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define mkdirp = require("mkdirp"), path = require("path"), glob = require("glob"), - showdown = require("github-flavored-markdown"), + marked = require("marked"), split = require("split"), stream = require("stream"), nomnoml = require('nomnoml'), @@ -79,7 +79,7 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define }; transform._flush = function (done) { this.push("\n"); - this.push(showdown.parse(markdown)); + this.push(marked(markdown)); this.push("\n\n"); done(); }; @@ -89,6 +89,17 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define options['in'] = options['in'] || options.i; options.out = options.out || options.o; + marked.setOptions({ + renderer: new marked.Renderer(), + gfm: true, + tables: true, + breaks: false, + pedantic: false, + sanitize: true, + smartLists: true, + smartypants: false + }); + glob(options['in'] + "/**/*.md", {}, function (err, files) { files.forEach(function (file) { var destination = file.replace(options['in'], options.out) diff --git a/package.json b/package.json index df7a7f9529..d1d675df19 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "karma-phantomjs-launcher": "^0.1.4", "karma-requirejs": "^0.2.2", "requirejs": "^2.1.17", - "github-flavored-markdown": ">= 1.0.0", + "marked": "^0.3.5", "glob": ">= 3.0.0", "split": "^1.0.0", "mkdirp": "^0.5.1", From aea286779ea56b049c9acc6659c389ec97c707da Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 13:37:45 -0700 Subject: [PATCH 13/40] [Documentation] Add custom renderer MissionControl/vista#21 --- docs/gendocs.js | 21 ++++++++++++++++++++- docs/src/architecture/Framework.md | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/gendocs.js b/docs/gendocs.js index 26816ba703..371e02957a 100644 --- a/docs/gendocs.js +++ b/docs/gendocs.js @@ -86,11 +86,30 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define return transform; } + function CustomRenderer() { + var renderer = new marked.Renderer(), + customRenderer = Object.create(renderer); + customRenderer.heading = function (text, level) { + var escapedText = (text || "").trim().toLowerCase().replace(/\W/g, "-"), + aOpen = "", + aClose = ""; + return aOpen + renderer.heading.apply(renderer, arguments) + aClose; + }; + // Change links to .md files to .html + customRenderer.link = function (href, title, text) { + // ...but only if they look like relative paths + return (href || "").indexOf(":") === -1 && href[0] !== "/" ? + renderer.link(href.replace(/md$/, "html"), title, text) : + renderer.link.apply(renderer, arguments); + }; + return customRenderer; + } + options['in'] = options['in'] || options.i; options.out = options.out || options.o; marked.setOptions({ - renderer: new marked.Renderer(), + renderer: new CustomRenderer(), gfm: true, tables: true, breaks: false, diff --git a/docs/src/architecture/Framework.md b/docs/src/architecture/Framework.md index c0a3e4990b..519a4eb7b3 100644 --- a/docs/src/architecture/Framework.md +++ b/docs/src/architecture/Framework.md @@ -107,4 +107,4 @@ As such, the specific architecture of any given application built on Open MCT Web can look very different. The specific service infrastructure provided by the platform is described -in the [Platform Architecture](Platform.html). \ No newline at end of file +in the [Platform Architecture](Platform.md). From 926ee1454690ecbead14ef9325679c44d81b0301 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 14:23:23 -0700 Subject: [PATCH 14/40] [Documentation] Add composite services notes MissionControl/vista#21 --- docs/src/architecture/Framework.md | 94 ++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/docs/src/architecture/Framework.md b/docs/src/architecture/Framework.md index 519a4eb7b3..3272ffaac1 100644 --- a/docs/src/architecture/Framework.md +++ b/docs/src/architecture/Framework.md @@ -74,8 +74,31 @@ a simple sequence of steps. [Bootstrap application]->[ End] ``` +1. __Loading bundles.json.__ A file named `bundles.json` is loaded to determine + which bundles to load. Bundles are given in this file as relative paths + which point to bundle directories. +2. __Load bundle.json files.__ Individual bundle definitions are loaded; a + `bundle.json` file is expected in each bundle directory. +2. __Resolving implementations.__ Any scripts which provide implementations for + extensions exposed by bundles are loaded, using RequireJS. +3. __Register with Angular.__ Resolved extensions are registered with Angular, + such that they can be used by the application at run-time. This stage + includes both registration of Angular built-ins (directives, controllers, + routes, constants, and services) as well as registration of non-Angular + extensions. +4. __Bootstrap application.__ Once all extensions have been registered, + the Angular application + [is bootstrapped](https://docs.angularjs.org/guide/bootstrap). + ## Architectural Paradigm +```nomnoml +[Extension] +[Extension]o->[Dependency #1] +[Extension]o->[Dependency #2] +[Extension]o->[Dependency #3] +``` + Open MCT Web's architecture relies on a simple premise: Individual units (extensions) only have access to the dependencies they declare that they need, and they acquire references to these dependencies via dependency @@ -106,5 +129,76 @@ by the framework as the consequence of wiring together dependencies. As such, the specific architecture of any given application built on Open MCT Web can look very different. +Keeping that in mind, there are a few useful patterns supported by the +framework that are useful to keep in mind. + The specific service infrastructure provided by the platform is described in the [Platform Architecture](Platform.md). + +### Extension Categories + +### Composite Services + +Composite services (registered via extension category `components`) are +a pattern supported by the framework. These allow service instances to +be built from multiple components at run-time; support for this pattern +allows additional bundles to introduce or modify behavior associated +with these services without modifying or replacing original service +instances. + +```nomnoml +#direction: down +[ FooService] +[FooDecorator #1]--:>[FooService] +[FooDecorator #n]--:>[FooService] +[FooAggregator]--:>[FooService] +[FooProvider #1]--:>[FooService] +[FooProvider #n]--:>[FooService] + +[FooDecorator #1]o->[ ...decorators...] +[...decorators...]o->[FooDecorator #n] +[FooDecorator #n]o->[FooAggregator] +[FooAggregator]o->[FooProvider #1] +[FooAggregator]o->[ ...providers...] +[FooAggregator]o->[FooProvider #n] + +[FooDecorator #1]--[ Exposed as fooService] +``` + +In this pattern, components all implement an interface which is +standardized for that service. Components additionally declare +that they belong to one of three types: + +* __Providers.__ A provider actually implements the behavior + (satisfies the contract) for that kind of service. For instance, + if a service is responsible for looking up documents by an identifier, + one provider may do so by querying a database, while another may + do so by reading a static JSON document. From the outside, either + provider would look the same (they expose the same interface) and + they could be swapped out easily. +* __Aggregator.__ An aggregator takes many providers and makes them + behave as one. Again, this implements the same interface as an + individual provider, so users of the service do not need to be + concerned about the difference between consulting many providers + and consulting one. Continuing with the example of a service that + looks up documents by identifiers, an aggregator here might consult + all providers, and return any document is found (perhaps picking one + over the other or merging documents if there are multiple matches.) +* __Decorators.__ A decorator exposes the same interface as other + components, but instead of fully implementing the behavior associated + with that kind of service, it only acts as an intermediary, delegating + the actual behavior to a different component. Decorators may transform + inputs or outputs, or initiate some side effects associated with a + service. This is useful if certain common behavior associated with a + service (caching, for instance) may be useful across many different + implementations of that same service. + +The framework will register extensions in this category such that an +aggregator will depend on all of its providers, and decorators will +depend upon on one another in a chain. The result of this compositing step +(the last decorator, if any; otherwise the aggregator, if any; +otherwise a single provider) will be exposed as a single service that +other extensions can acquire through dependency injection. Because all +components of the same type of service expose the same interface, users +of that service do not need to be aware that they are talking to an +aggregator or a provider, for instance. \ No newline at end of file From f8dd69bbfae68ebe778f1e360e71ba61d3fa72c6 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 14:55:52 -0700 Subject: [PATCH 15/40] [Documentation] Complete framework arch MissionControl/vista#21 --- docs/src/architecture/Framework.md | 30 ++++++++++++++++++++++++++++++ docs/src/architecture/index.md | 4 ++++ 2 files changed, 34 insertions(+) diff --git a/docs/src/architecture/Framework.md b/docs/src/architecture/Framework.md index 3272ffaac1..da036f3c04 100644 --- a/docs/src/architecture/Framework.md +++ b/docs/src/architecture/Framework.md @@ -137,6 +137,36 @@ in the [Platform Architecture](Platform.md). ### Extension Categories +One of the capabilities that the framework component layers on top of +AngularJS is support for many-to-one dependencies. That is, a specific +extension may declare a dependency to _all extensions of a specific +category_, instead of being limited to declaring specific dependencies. + +```nomnoml +#direction: right +[Specific Extension] 1 o-> * [Extension of Some Category] +``` + +This is useful for introducing specific extension points to an application. +Some unit of software will depend upon all extensions of a given category +and integrate their behavior into the system in some fashion; plugin authors +can then add new extensions of that category to augment existing behaviors. + +Some developers may be familiar with the use of registries to achieve +similar characteristics. This approach is similar, except that the registry +is effectively implicit whenever a new extension category is used or +depended-upon. This has some advantages over a more straightforward +registry-based approach: + +* These many-to-one relationships are expressed as dependencies; an + extension category is registered as having dependencies on all individual + extensions of this category. This avoids ordering issues that may occur + with more conventional registries, which may be observed before all + dependencies are resolved. +* The need for service registries of specific types is removed, reducing + the number of interfaces to manage within the system. Groups of + extensions are provided as arrays. + ### Composite Services Composite services (registered via extension category `components`) are diff --git a/docs/src/architecture/index.md b/docs/src/architecture/index.md index 62d58262ab..19953efe9e 100644 --- a/docs/src/architecture/index.md +++ b/docs/src/architecture/index.md @@ -11,6 +11,10 @@ The target audience includes: Open MCT Web into a larger system, who need to understand its inner workings sufficiently to complete this integration. +As the focus of this document is on architecture, whenever possible +implementation details (such as relevant API or JSON syntax) have been +omitted. These details may be found in the developer guide. + # Overview Open MCT Web is client software: It runs in a web browser and From fc0c902886ae5809a66ec823604ba5cd0ecb9b04 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 16:11:13 -0700 Subject: [PATCH 16/40] [Documentation] More service infrastructure MissionControl/vista#21 --- docs/gendocs.js | 2 +- docs/src/architecture/Framework.md | 8 +- docs/src/architecture/Platform.md | 205 +++++++++++++++++++++++++++++ docs/src/architecture/index.md | 4 +- 4 files changed, 211 insertions(+), 8 deletions(-) diff --git a/docs/gendocs.js b/docs/gendocs.js index 371e02957a..d0cb008c02 100644 --- a/docs/gendocs.js +++ b/docs/gendocs.js @@ -99,7 +99,7 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define customRenderer.link = function (href, title, text) { // ...but only if they look like relative paths return (href || "").indexOf(":") === -1 && href[0] !== "/" ? - renderer.link(href.replace(/md$/, "html"), title, text) : + renderer.link(href.replace(/\.md/, ".html"), title, text) : renderer.link.apply(renderer, arguments); }; return customRenderer; diff --git a/docs/src/architecture/Framework.md b/docs/src/architecture/Framework.md index da036f3c04..229bee39c4 100644 --- a/docs/src/architecture/Framework.md +++ b/docs/src/architecture/Framework.md @@ -1,6 +1,4 @@ -# Framework Architecture - -## Overview +# Overview The framework layer's most basic responsibility is allowing individual software components to communicate. The software components it recognizes @@ -135,7 +133,7 @@ framework that are useful to keep in mind. The specific service infrastructure provided by the platform is described in the [Platform Architecture](Platform.md). -### Extension Categories +## Extension Categories One of the capabilities that the framework component layers on top of AngularJS is support for many-to-one dependencies. That is, a specific @@ -167,7 +165,7 @@ registry-based approach: the number of interfaces to manage within the system. Groups of extensions are provided as arrays. -### Composite Services +## Composite Services Composite services (registered via extension category `components`) are a pattern supported by the framework. These allow service instances to diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md index e69de29bb2..023ba61aca 100644 --- a/docs/src/architecture/Platform.md +++ b/docs/src/architecture/Platform.md @@ -0,0 +1,205 @@ +# Overview + +The Open MCT Web platform utilizes the [framework layer](Framework.md) +to provide an extensible baseline for applications which includes: + +* A common user interface (and user interface paradigm) for dealing with + domain objects of various sorts. +* A variety of extension points for introducing new functionality + of various kinds within the context of the common user interface. +* A service infrastructure to support building additional components. + +# Information Model + +```nomnoml +#direction: right +[DomainObject| + getId() : string + getModel() : object + getCapability(key : string) : Capability + hasCapability(key : string) : boolean + useCapability(key : string, args...) : * +] +[DomainObject] 1 +- 1 [Model] +[DomainObject] 1 o- * [Capability] +``` + +Domain objects are the most fundamental component of Open MCT Web's +information model. A domain object is some distinct thing relevant to a +user's work flow, such as a telemetry channel, display, or similar. +Open MCT Web is a tool for viewing, browsing, manipulating, and otherwise +interacting with a graph of domain objects. + +A domain object should be conceived of as the union of the following: + +* _Identifier_: A machine-readable string that uniquely identifies the + domain object within this application instance. +* _Model_: The persistent state of the domain object. A domain object's + model is a JavaScript object that can be losslessly converted to JSON. +* _Capabilities_: Dynamic behavior associated with the domain object. + Capabilities are JavaScript objects which provide additional methods + for interacting with the domain objects which expose those capabilities. + Not all domain objects expose all capabilities. The interface exposed + by any given capability will depend on its type (as identified + by the `key` argument.) For instance, a `persistence` capability + has a different interface from a `telemetry` capability. Using + capabilities requires some prior knowledge of their interface. + +# Service Infrastructure + +Most services exposed by the Open MCT Web platform follow the +[composite services](Framework.md#composite-services) to permit +a higher degree of flexibility in how a service can be modified +or customized for specific applications. + +To simplify usage for plugin developers, the platform also usually +includes a provider implementation for these service type that consumes +some extension category. For instance, an `ActionService` provider is +included which depends upon extension category `actions`, and exposes +all actions declared as such to the system. As such, plugin developers +can simply implement the new actions they wish to be made available without +worrying about the details of composite services or implementing a new +`ActionService` provider; however, the ability to implement a new provider +remains useful when the expressive power of individual extensions is +insufficient. + +## Object Service + +```nomnoml +#direction: right +[ ObjectService| + getObjects(ids : Array.) : Promise.> +] +[DomainObjectProvider]--:>[ObjectService] +[DomainObjectProvider]o-[ModelService] +[DomainObjectProvider]o-[CapabilityService] +``` + +As domain objects are central to Open MCT Web's information model, +acquiring domain objects is equally important. + +```nomnoml +#direction: right +[ Start]->[ Look up models] +[ Look up models]->[ Look up capabilities] +[ Look up capabilities]->[ Instantiate DomainObject] +[ Instantiate DomainObject]->[ End] +``` + +Open MCT Web includes an implementation of an `ObjectService` which +satisfies this capability by: + +* Consulting the [Model Service](#model-service) to acquire domain object + models by identifier. +* Passing these models to a [Capability Service](#capability-service) to + determine which capabilities are applicable. +* Combining these results together as [DomainObject](#information-model) + instances. + +## Model Service + +```nomnoml +#direction: down +[ ModelService| + getModels(ids : Array.) : Promise.> +] +[StaticModelProvider]--:>[ModelService] +[RootModelProvider]--:>[ModelService] +[PersistedModelProvider]--:>[ModelService] +[ModelAggregator]--:>[ModelService] +[CachingModelDecorator]--:>[ModelService] +[MissingModelDecorator]--:>[ModelService] + +[MissingModelDecorator]o-[CachingModelDecorator] +[CachingModelDecorator]o-[ModelAggregator] +[ModelAggregator]o-[StaticModelProvider] +[ModelAggregator]o-[RootModelProvider] +[ModelAggregator]o-[PersistedModelProvider] + +[PersistedModelProvider]o-[PersistenceService] +[RootModelProvider]o-[roots] +[StaticModelProvider]o-[models] +``` + +The platform's model service is responsible for providing domain object +models (effectively, JSON documents describing the persistent state +associated with domain objects.) These are retrieved by identifier. + +The platform includes multiple components of this variety: + +* `PersistedModelProvider` looks up domain object models from + a persistence store; this is how user-created and user-modified + domain object models are retrieved. +* `RootModelProvider` provides domain object models that have been + declared via the `roots` extension category. These will appear at the + top level of the tree hierarchy in the user interface. +* `StaticModelProvider` provides domain object models that have been + declared via the `models` extension category. This is useful for + allowing plugins to expose new domain objects declaratively. +* `ModelAggregator` merges together the results from multiple providers. + If multiple providers return models for the same domain object, + the most recently modified version (as determined by the `modified` + property of the model) is chosen. +* `CachingModelDecorator` caches model instances in memory. This + ensures that only a single instance of a domain object model is + present at any given time within the application, and prevent + redundant retrievals. +* `MissingModelDecorator` adds in placeholders when no providers + have returned domain object models for a specific identifier. This + allows the user to easily see that something was expected to be + present, but wasn't. + +## Capability Service + +```nomnoml +#direction: down +[ CapabilityService| + getCapabilities(model : object) : object. +] +[CoreCapabilityProvider]--:>[CapabilityService] +[QueuingPersistenceCapabilityDecorator]--:>[CapabilityService] + +[CoreCapabilityProvider]o-[capabilities] +[QueuingPersistenceCapabilityDecorator]o-[CoreCapabilityProvider] +``` + +The capability service is responsible for determining which capabilities +are applicable for a given domain object, based on its model. Primarily, +this is handled by the `CoreCapabilityProvider`, which examines +capabilities exposed via the `capabilities` extension category. + +Additionally, `platform/persistence/queue` decorates the persistence +capability specifically to batch persistence attempts among multiple +objects (this allows failures to be recognized and handled in groups.) + +## Persistence Service + +```nomnoml +#direction: right +[ PersistenceService| + listSpaces() : Promise.> + listObjects() : Promise.> + createObject(space : string, key : string, document : object) : Promise. + readObject(space : string, key : string, document : object) : Promise. + updateObject(space : string, key : string, document : object) : Promise. + deleteObject(space : string, key : string, document : object) : Promise. +] + +[ElasticPersistenceProvider]--:>[PersistenceService] +[ElasticPersistenceProvider]->[ ElasticSearch] + +[CouchPersistenceProvider]--:>[PersistenceService] +[CouchPersistenceProvider]->[ CouchDB] +``` + +Closely related to the notion of domain objects models is their +persistence. The `PersistenceService` allows these to be saved +and loaded. (Currently, this capability is only used for domain +object models, but the interface has been designed without this idea +in mind; other kinds of documents could be saved and loaded in the +same manner.) + +There is no single definitive implementation of a `PersistenceService` in +the platform. Optional adapters are provided to store and load documents +from CouchDB and ElasticSearch, respectively; plugin authors may also +write additional adapters to utilize different back end technologies. \ No newline at end of file diff --git a/docs/src/architecture/index.md b/docs/src/architecture/index.md index 19953efe9e..fd9e0961e1 100644 --- a/docs/src/architecture/index.md +++ b/docs/src/architecture/index.md @@ -58,12 +58,12 @@ of the software. These layers are: -* [_Framework_](Framework.html): The framework layer is responsible for +* [_Framework_](Framework.md): The framework layer is responsible for managing the interactions between application components. It has no application-specific knowledge; at this layer, we have only established an abstraction by which different software components may communicate and/or interact. -* _Platform_: The platform layer defines the general look, feel, and +* [_Platform_](Platform.md): The platform layer defines the general look, feel, and behavior of Open MCT Web. This includes user-facing components like Browse mode and Edit mode, as well as underlying elements of the information model and the general service infrastructure. From 0bf510ca088d380e7092b4593463272c9f22784d Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 16:31:01 -0700 Subject: [PATCH 17/40] [Documentation] Add more useful patterns MissionControl/vista#21 --- docs/src/architecture/Platform.md | 70 ++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md index 023ba61aca..25c9943626 100644 --- a/docs/src/architecture/Platform.md +++ b/docs/src/architecture/Platform.md @@ -45,6 +45,48 @@ A domain object should be conceived of as the union of the following: has a different interface from a `telemetry` capability. Using capabilities requires some prior knowledge of their interface. +## Capabilities and Services + +```nomnoml +#direction: right +[DomainObject]o-[FooCapability] +[FooCapability]o-[FooService] +[FooService]o-[foos] +``` + +At run-time, the user is primarily concerned with interacting with +domain objects. These interactions are ultimately supported via back-end +services, but to allow customization per-object, these are often mediated +by capabilities. + +A common pattern that emerges in the Open MCT Platform is as follows: + +* A `DomainObject` has some particular behavior that will be supported + by a service. +* A `Capability` of that domain object will define that behavior, + _for that domain object_, supported by a service. +* A `Service` utilized by that capability will perform the actual behavior. +* An extension category will be utilized by that capability to determine + the set of possible behaviors. + +Concrete examples of capabilities which follow this pattern +(or a subset of this pattern) include: + +```nomnoml +#direction: right +[DomainObject]1 o- *[Capability] +[Capability]<:--[TypeCapability] +[Capability]<:--[ActionCapability] +[Capability]<:--[PersistenceCapability] +[Capability]<:--[TelemetryCapability] +[TypeCapability]o-[TypeService] +[TypeService]o-[types] +[ActionCapability]o-[ActionService] +[ActionService]o-[actions] +[PersistenceCapability]o-[PersistenceService] +[TelemetryCapability]o-[TelemetryService] +``` + # Service Infrastructure Most services exposed by the Open MCT Web platform follow the @@ -128,7 +170,8 @@ associated with domain objects.) These are retrieved by identifier. The platform includes multiple components of this variety: * `PersistedModelProvider` looks up domain object models from - a persistence store; this is how user-created and user-modified + a persistence store (the [`PersistenceService`](#persistence-service)); + this is how user-created and user-modified domain object models are retrieved. * `RootModelProvider` provides domain object models that have been declared via the `roots` extension category. These will appear at the @@ -202,4 +245,27 @@ same manner.) There is no single definitive implementation of a `PersistenceService` in the platform. Optional adapters are provided to store and load documents from CouchDB and ElasticSearch, respectively; plugin authors may also -write additional adapters to utilize different back end technologies. \ No newline at end of file +write additional adapters to utilize different back end technologies. + +## Action Service + +```nomnoml +[ActionService| + getActions(context : ActionContext) : Array. +] +[ActionProvider]--:>[ActionService] +[CreateActionProvider]--:>[ActionService] +[ActionAggregator]--:>[ActionService] +[LoggingActionDecorator]--:>[ActionService] + +[LoggingActionDecorator]o-[ActionAggregator] +[ActionAggregator]o-[ActionProvider] +[ActionAggregator]o-[CreateActionProvider] + +[ActionProvider]o-[actions] +[CreateActionProvider]o-[TypeService] +``` + +Actions are discrete tasks or behaviors that can be initiated by a user +upon or using a domain object. Actions may appear as menu items or +buttons in the user interface, or may be triggered by certain gestures. \ No newline at end of file From 3c325b8870a9f0eaead7fa2714f1348f24687fe9 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 16:55:29 -0700 Subject: [PATCH 18/40] [Documentation] Add more high-level platform information MissionControl/vista#21 --- docs/src/architecture/Platform.md | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md index 25c9943626..ef1e65b91e 100644 --- a/docs/src/architecture/Platform.md +++ b/docs/src/architecture/Platform.md @@ -9,6 +9,38 @@ to provide an extensible baseline for applications which includes: of various kinds within the context of the common user interface. * A service infrastructure to support building additional components. +## Platform Architecture + +While the framework provides a more general architectural paradigm for +building application, the platform adds more specificity by defining +additional extension types and allowing for integration with back end +components. + +The run-time architecture of an Open MCT Web application can be categorized +into certain high-level tiers: + +```nomnoml +[Templates]->[ AngularJS] +[AngularJS]->[Presentation Layer] +[Presentation Layer]->[Information Model] +[Presentation Layer]->[Service Infrastructure] +[Information Model]->[Service Infrastructure] +[Service Infrastructure]->[ Browser APIs] +[Browser APIs]->[Back-end] +``` + +Applications built using Open MCT Web may add or configure functionality +in any of these tiers. + +# Presentation Layer + +The presentation layer of Open MCT Web is responsible for providing +information to display within templates, and for handling interactions +which are initiated from templated DOM elements. AngularJS acts as +an intermediary between the web page as the user sees it, and the +presentation layer implemented as Open MCT Web extensions. + + # Information Model ```nomnoml From 96f738b6b63df50a2bcff6b9823935074a7a04ce Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 4 Aug 2015 17:10:04 -0700 Subject: [PATCH 19/40] [Documentation] Diagram service infrastructure MissionControl/vista#21 --- docs/src/architecture/Platform.md | 56 ++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md index ef1e65b91e..263683e4cd 100644 --- a/docs/src/architecture/Platform.md +++ b/docs/src/architecture/Platform.md @@ -40,20 +40,38 @@ which are initiated from templated DOM elements. AngularJS acts as an intermediary between the web page as the user sees it, and the presentation layer implemented as Open MCT Web extensions. +```nomnoml +[Presentation Layer| + [Angular built-ins| + [routes] + [controllers] + [directives] + ] + [Domain object representation| + [views] + [representations] + [representers] + [gestures] + ] +] +``` + # Information Model ```nomnoml #direction: right -[DomainObject| - getId() : string - getModel() : object - getCapability(key : string) : Capability - hasCapability(key : string) : boolean - useCapability(key : string, args...) : * +[Information Model| + [DomainObject| + getId() : string + getModel() : object + getCapability(key : string) : Capability + hasCapability(key : string) : boolean + useCapability(key : string, args...) : * + ] + [DomainObject] 1 +- 1 [Model] + [DomainObject] 1 o- * [Capability] ] -[DomainObject] 1 +- 1 [Model] -[DomainObject] 1 o- * [Capability] ``` Domain objects are the most fundamental component of Open MCT Web's @@ -137,6 +155,28 @@ worrying about the details of composite services or implementing a new remains useful when the expressive power of individual extensions is insufficient. +```nomnoml +[ Service Infrastructure | + [ObjectService]->[ModelService] + [ModelService]->[PersistenceService] + [ObjectService]->[CapabilityService] + [CapabilityService]->[capabilities] + [capabilities]->[TelemetryService] + [capabilities]->[PersistenceService] + [capabilities]->[TypeService] + [capabilities]->[ActionService] + [capabilities]->[ViewService] + [PersistenceService]->[ Document store] + [TelemetryService]->[ Data source] + [ActionService]->[actions] + [ActionService]->[PolicyService] + [ViewService]->[PolicyService] + [ViewService]->[views] + [PolicyService]->[policies] + [TypeService]->[types] +] +``` + ## Object Service ```nomnoml From 096dce1fe007bc7aebf1bb72180c8de07ca6e1fc Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 5 Aug 2015 16:35:58 -0700 Subject: [PATCH 20/40] [Documentation] Clarify terminology MissionControl/vista#21 --- docs/src/architecture/Platform.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md index 263683e4cd..e15afed8a3 100644 --- a/docs/src/architecture/Platform.md +++ b/docs/src/architecture/Platform.md @@ -167,7 +167,7 @@ insufficient. [capabilities]->[ActionService] [capabilities]->[ViewService] [PersistenceService]->[ Document store] - [TelemetryService]->[ Data source] + [TelemetryService]->[ Telemetry source] [ActionService]->[actions] [ActionService]->[PolicyService] [ViewService]->[PolicyService] From 37cd73c6e850283c1f5c904007aebb6554b64eba Mon Sep 17 00:00:00 2001 From: Pete Richards Date: Wed, 5 Aug 2015 17:11:30 -0700 Subject: [PATCH 21/40] [Template] Move ng-click to parent node Move the ng-click directive to the li element to match the element that receives hover styles. Fixes nasa/openmctweb#60. --- .../commonUI/browse/res/templates/create/create-menu.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/platform/commonUI/browse/res/templates/create/create-menu.html b/platform/commonUI/browse/res/templates/create/create-menu.html index 3386d2d266..24314a17c7 100644 --- a/platform/commonUI/browse/res/templates/create/create-menu.html +++ b/platform/commonUI/browse/res/templates/create/create-menu.html @@ -23,9 +23,8 @@ - \ No newline at end of file + From 4c8d07bba8d69aea0d412b6563bfb81351814cea Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 5 Aug 2015 17:24:36 -0700 Subject: [PATCH 22/40] [Documentation] Telemetry service architecture MissionControl/vista#21 --- docs/src/architecture/Platform.md | 143 +++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 1 deletion(-) diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md index e15afed8a3..bac6de3799 100644 --- a/docs/src/architecture/Platform.md +++ b/docs/src/architecture/Platform.md @@ -167,7 +167,7 @@ insufficient. [capabilities]->[ActionService] [capabilities]->[ViewService] [PersistenceService]->[ Document store] - [TelemetryService]->[ Telemetry source] + [TelemetryService]->[ Telemetry source] [ActionService]->[actions] [ActionService]->[PolicyService] [ViewService]->[PolicyService] @@ -177,6 +177,29 @@ insufficient. ] ``` +A short summary of the roles of these services: + +* _[ObjectService](#object-service)_: Allows retrieval of domain objects by + their identifiers; in practice, often the main point of entry into the + [information model](#information-model). +* _[ModelService](#model-service)_: Provides domain object models, retrieved + by their identifier. +* _[CapabilityService](#capability-service)_: Provides capabilities, as they + apply to specific domain objects (as judged from their model.) +* _[TelemetryService](#telemetry-service)_: Provides access to historical + and real-time telemetry data. +* _[PersistenceService](#persistence-service)_: Provides the ability to + store and retrieve documents (such as domain object models.) +* _[ActionService](#action-service)_: Provides distinct user actions that + can take place within the system (typically, upon or using domain objects.) +* _[ViewService](#view-service)_: Provides views for domain objects. A view + is a user-selectable representation of a domain object (in practice, an + HTML template.) +* _[PolicyService](#policy-service)_: Handles decisions about which + behavior are allowed within certain specific contexts. +* _[TypeService](#type-service)_: Provides information to distinguish + different types of domain objects from one another within the system. + ## Object Service ```nomnoml @@ -287,6 +310,124 @@ Additionally, `platform/persistence/queue` decorates the persistence capability specifically to batch persistence attempts among multiple objects (this allows failures to be recognized and handled in groups.) +## Telemetry Service + +```nomnoml +[ TelemetryService| + requestData(requests : Array.) : Promise. + subscribe(requests : Array.) : Function +]<--:[TelemetryAggregator] +``` + +The telemetry service is responsible for acquiring telemetry data. + +Notably, the platform does not include any providers for +`TelemetryService`; applications built on Open MCT Web will need to +implement a provider for this service if they wish to expose telemetry +data. This is usually the most important step for integrating Open MCT Web +into an existing telemetry system. + +Requests for telemetry data are usually initiated in the +[presentation layer](#presentation-layer) by some `Controller` referenced +from a view. The `telemetryHandler` service is most commonly used (although +one could also use an object's `telemetry` capability directly) as this +handles capability delegation, by which a domain object such as a Telemetry +Panel can declare that its `telemetry` capability should be handled by the +objects it contains. Ultimately, the request for historical data and the +new subscriptions will reach the `TelemetryService`, and, by way of the +provider(s) which are present for that `TelemetryService`, will pass the +same requests to the back-end. + +```nomnoml +[ Start]->[Controller] +[Controller]->[ declares object of interest] +[declares object of interest]->[TelemetryHandler] +[TelemetryHandler]->[ requests telemetry from capabilities] +[TelemetryHandler]->[ subscribes to telemetry using capabilities] +[requests telemetry from capabilities]->[TelemetryCapability] +[subscribes to telemetry using capabilities]->[TelemetryCapability] +[TelemetryCapability]->[ requests telemetry] +[TelemetryCapability]->[ subscribes to telemetry] +[requests telemetry]->[TelemetryService] +[subscribes to telemetry]->[TelemetryService] +[TelemetryService]->[ issues request] +[TelemetryService]->[ updates subscriptions] +[TelemetryService]->[ listens for real-time data] +[issues request]->[ Telemetry Back-end] +[updates subscriptions]->[Telemetry Back-end] +[listens for real-time data]->[Telemetry Back-end] +[Telemetry Back-end]->[ End] +``` + +The back-end, in turn, is expected to provide whatever historical +telemetry is available to satisfy the request that has been issue. + +```nomnoml +[ Start]->[ Telemetry Back-end] +[Telemetry Back-end]->[ transmits historical telemetry] +[transmits historical telemetry]->[TelemetryService] +[TelemetryService]->[ packages telemetry, fulfills requests] +[packages telemetry, fulfills requests]->[TelemetryCapability] +[TelemetryCapability]->[ unpacks telemetry per-object, fulfills request] +[unpacks telemetry per-object, fulfills request]->[TelemetryHandler] +[TelemetryHandler]->[ exposes data] +[TelemetryHandler]->[ notifies controller] +[exposes data]->[Controller] +[notifies controller]->[Controller] +[Controller]->[ prepares data for template] +[prepares data for template]->[Template] +[Template]->[ displays data] +[displays data]->[ End] +``` + +One peculiarity of this approach is that we package many responses +together at once in the `TelemetryService`, then unpack these in the +`TelemetryCapability`, then repackage these in the `TelemetryHandler`. +The rationale for this is as follows: + +* In the `TelemetryService`, we want to have the ability to combine + multiple requests into one call to the back-end, as many back-ends + will support this. It follows that we give the response as a single + object, packages in a manner that allows responses to individual + requests to be easily identified. +* In the `TelemetryCapability`, we want to provide telemetry for a + _single object_, so the telemetry data gets unpacked. This allows + for the unpacking of data to be handled in a single place, and + also permits a flexible substitution method; domain objects may have + implementations of the `telemetry` capability that do not use the + `TelemetryService` at all, while still maintaining compatibility + with any presentation layer code written to utilize this capability. + (This is true of capabilities generally.) +* In the `TelemetryHandler`, we want to group multiple responses back + together again to make it easy for the presentation layer to consume. + In this case, the grouping is different from what may have occurred + in the `TelemetryService`; this grouping is based on what is expected + to be useful _in a specific view_. The `TelemetryService` + may be receiving requests from multiple views. + +```nomnoml +[ Start]->[ Telemetry Back-end] +[Telemetry Back-end]->[ notifies client of new data] +[notifies client of new data]->[TelemetryService] +[TelemetryService]->[ relevant subscribers?] +[relevant subscribers?] yes ->[ notify subscribers] +[relevant subscribers?] no ->[ ignore] +[ignore]->[ Ignored] +[notify subscribers]->[TelemetryCapability] +[TelemetryCapability]->[ notify listener] +[notify listener]->[TelemetryHandler] +[TelemetryHandler]->[ exposes data] +[TelemetryHandler]->[ notifies controller] +[exposes data]->[Controller] +[notifies controller]->[Controller] +[Controller]->[ prepares data for template] +[prepares data for template]->[Template] +[Template]->[ displays data] +[displays data]->[ End] +``` + + + ## Persistence Service ```nomnoml From 935360e2eb8fec154b41aea3761c6be074cd0ada Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 6 Aug 2015 11:02:12 -0700 Subject: [PATCH 23/40] [Documentation] Document remaining services MissionControl/vista#21 --- docs/src/architecture/Platform.md | 133 +++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 3 deletions(-) diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md index bac6de3799..542c3357ae 100644 --- a/docs/src/architecture/Platform.md +++ b/docs/src/architecture/Platform.md @@ -426,7 +426,13 @@ The rationale for this is as follows: [displays data]->[ End] ``` - +The flow of real-time data is similar, and is handled by a sequence +of callbacks between the presentation layer component which is +interested in data and the telemetry service. Providers in the +telemetry service listen to the back-end for new data (via whatever +mechanism their specific back-end supports), package this data in +the same manner as historical data, and pass that to the callbacks +which are associated with relevant requests. ## Persistence Service @@ -470,15 +476,136 @@ write additional adapters to utilize different back end technologies. [CreateActionProvider]--:>[ActionService] [ActionAggregator]--:>[ActionService] [LoggingActionDecorator]--:>[ActionService] +[PolicyActionDecorator]--:>[ActionService] -[LoggingActionDecorator]o-[ActionAggregator] +[LoggingActionDecorator]o-[PolicyActionDecorator] +[PolicyActionDecorator]o-[ActionAggregator] [ActionAggregator]o-[ActionProvider] [ActionAggregator]o-[CreateActionProvider] [ActionProvider]o-[actions] [CreateActionProvider]o-[TypeService] +[PolicyActionDecorator]o-[PolicyService] ``` Actions are discrete tasks or behaviors that can be initiated by a user upon or using a domain object. Actions may appear as menu items or -buttons in the user interface, or may be triggered by certain gestures. \ No newline at end of file +buttons in the user interface, or may be triggered by certain gestures. + +Responsibilities of platform components of the action service are as +follows: + +* `ActionProvider` exposes actions registered via extension category + `actions`, supporting simple addition of new actions. Actions are + filtered down to match action contexts based on criteria defined as + part of an action's extension definition. +* `CreateActionProvider` provides the various Create actions which + populate the Create menu. These are driven by the available types, + so do not map easily ot extension category `actions`; instead, these + are generated after looking up which actions are available from the + [`TypeService`](#type-service). +* `ActionAggregator` merges together actions from multiple providers. +* `PolicyActionDecorator` enforces the `action` policy category by + filtering out actions which violate this policy, as determined by + consulting the [`PolicyService`](#policy-service). +* `LoggingActionDecorator` wraps exposed actions and writes to the + console when they are performed. + +## View Service + +```nomnoml +[ViewService| + getViews(domainObject : DomainObject) : Array. +] +[ViewProvider]--:>[ViewService] +[PolicyViewDecorator]--:>[ViewService] + +[ViewProvider]o-[views] +[PolicyViewDecorator]o-[ViewProvider] +``` + +The view service provides views that are relevant to a specified domain +object. A "view" is a user-selectable visualization of a domain object. + +The responsibilities of components of the view service are as follows: + +* `ViewProvider` exposes views registered via extension category + `views`, supporting simple addition of new views. Views are + filtered down to match domain objects based on criteria defined as + part of a view's extension definition. +* `PolicyViewDecorator` enforces the `view` policy category by + filtering out views which violate this policy, as determined by + consulting the [`PolicyService`](#policy-service). + +## Policy Service + +```nomnoml +[PolicyService| + allow(category : string, candidate : object, context : object, callback? : Function) : boolean +] +[PolicyProvider]--:>[PolicyService] +[PolicyProvider]o-[policies] +``` + +The policy service provides a general-purpose extensible decision-making +mechanism; plugins can add new extensions of category `policies` to +modify decisions of a known category. + +Often, the policy service is referenced from a decorator for another +service, to filter down the results of using that service based on some +appropriate policy category. + +The policy provider works by looking up all registered policy extensions +which are relevant to a particular _category_, then consulting each in +order to see if they allow a particular _candidate_ in a particular +_context_; the types for the `candidate` and `context` arguments will +vary depending on the `category`. Any one policy may disallow the +decision as a whole. + + +```nomnoml +[ Start]->[ is something allowed?] +[is something allowed?]->[PolicyService] +[PolicyService]->[ look up relevant policies by category] +[look up relevant policies by category]->[ consult policy #1] +[consult policy #1]->[Policy #1] +[Policy #1]->[ policy #1 allows?] +[policy #1 allows?] no ->[ decision disallowed] +[policy #1 allows?] yes ->[ consult policy #2] +[consult policy #2]->[Policy #2] +[Policy #2]->[ policy #2 allows?] +[policy #2 allows?] no ->[ decision disallowed] +[policy #2 allows?] yes ->[ consult policy #3] +[consult policy #3]->[ ...] +[...]->[ consult policy #n] +[consult policy #n]->[Policy #n] +[Policy #n]->[ policy #n allows?] +[policy #n allows?] no ->[ decision disallowed] +[policy #n allows?] yes ->[ decision allowed] +[decision disallowed]->[ Disallowed] +[decision allowed]->[ Allowed] +``` + +The policy decision is effectively an "and" operation over the individual +policy decisions: That is, all policies must agree to allow a particular +policy decision, and the first policy to disallow a decision will cause +the entire decision to be disallowed. As a consequence of this, policies +should generally be written with a default behavior of "allow", and +should only disallow the specific circumstances they are intended to +disallow. + +## Type Service + +```nomnoml +[TypeService| + listTypes() : Array. + getType(key : string) : Type +] +[TypeProvider]--:>[TypeService] +[TypeProvider]o-[types] +``` + +The type service provides metadata about the different types of domain +objects that exist within an Open MCT Web application. The platform +implementation reads these types in from extension category `types` +and wraps them in a JavaScript interface. \ No newline at end of file From 19db1c9c2b113b9da2f148a9e969c5244dfdfb43 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 6 Aug 2015 11:12:02 -0700 Subject: [PATCH 24/40] [Documentation] Add narrative about tiers MissionControl/vista#21 --- docs/src/architecture/Platform.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md index 542c3357ae..471feb159d 100644 --- a/docs/src/architecture/Platform.md +++ b/docs/src/architecture/Platform.md @@ -20,7 +20,7 @@ The run-time architecture of an Open MCT Web application can be categorized into certain high-level tiers: ```nomnoml -[Templates]->[ AngularJS] +[DOM]->[ AngularJS] [AngularJS]->[Presentation Layer] [Presentation Layer]->[Information Model] [Presentation Layer]->[Service Infrastructure] @@ -30,7 +30,29 @@ into certain high-level tiers: ``` Applications built using Open MCT Web may add or configure functionality -in any of these tiers. +in __any of these tiers__. + +* _DOM_: The rendered HTML document, composed from HTML templates which + have been processed by AngularJS and will be updated by AngularJS + to reflect changes from the presentation layer. +* [_Presentation layer_](#presentation-layer): The presentation layer + is responsible for updating (and providing information to update) + the displayed state of the application. The presentation layer consists + primarily of _controllers_ and _directives_. The presentation layer is + concerned with inspecting the information model and preparing it for + display. +* [_Information model_](#information-model): The information model + describes the state and behavior of the objects with which the user + interacts. +* [_Service infrastructure_](#service-infrastructure): The service + infrastructure is responsible for providing the underlying general + functionality needed to support the information model. This includes + exposing underlying sets of extensions and mediating with the + back-end. +* _Back-end_: The back-end is out of the scope of Open MCT Web, except + for the interfaces which are utilized by adapters participating in the + service infrastructure. + # Presentation Layer From 3dace28eb3e5dcaa4f42734adb0c3fd3b12d3a65 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 6 Aug 2015 11:39:01 -0700 Subject: [PATCH 25/40] [Documentation] Finish platform architecture MissionControl/vista#21 --- docs/src/architecture/Platform.md | 83 ++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/docs/src/architecture/Platform.md b/docs/src/architecture/Platform.md index 471feb159d..80f9e487f5 100644 --- a/docs/src/architecture/Platform.md +++ b/docs/src/architecture/Platform.md @@ -34,7 +34,8 @@ in __any of these tiers__. * _DOM_: The rendered HTML document, composed from HTML templates which have been processed by AngularJS and will be updated by AngularJS - to reflect changes from the presentation layer. + to reflect changes from the presentation layer. User interactions + are initiated from here and invoke behavior in the presentation layer. * [_Presentation layer_](#presentation-layer): The presentation layer is responsible for updating (and providing information to update) the displayed state of the application. The presentation layer consists @@ -53,6 +54,44 @@ in __any of these tiers__. for the interfaces which are utilized by adapters participating in the service infrastructure. +## Application Start-up + +Once the +[application has been initialized](Framework.md#application-initialization) +Open MCT Web primarily operates in an event-driven paradigm; various +events (mouse clicks, timers firing, receiving responses to XHRs) trigger +the invocation of functions, typically in the presentation layer for +user actions or in the service infrastructure for server responses. + +The "main point of entry" into an initialized Open MCT Web application +is effectively the +[route](https://docs.angularjs.org/api/ngRoute/service/$route#example) +which is associated with the URL used to access Open MCT Web (or a +default route.) This route will be associated with a template which +will be displayed; this template will include references to directives +and controllers which will be interpreted by Angular and used to +initialize the state of the display in a manner which is backed by +both the information model and the service infrastructure. + +```nomnoml +[ Start]->[ page load] +[page load]->[ route selection] +[route selection]->[ compile, display template] +[compile, display template]->[Template] +[Template]->[ use Controllers] +[Template]->[ use Directives] +[use Controllers]->[Controllers] +[use Directives]->[Directives] +[Controllers]->[ consult information model] +[consult information model]->[ expose data] +[expose data]->[Angular] +[Angular]->[ update display] +[Directives]->[ add event listeners] +[Directives]->[ update display] +[add event listeners]->[ End] +[update display]->[ End] +``` + # Presentation Layer @@ -68,6 +107,7 @@ presentation layer implemented as Open MCT Web extensions. [routes] [controllers] [directives] + [templates] ] [Domain object representation| [views] @@ -78,6 +118,47 @@ presentation layer implemented as Open MCT Web extensions. ] ``` +## Angular built-ins + +Several extension categories in the presentation layer map directly +to primitives from AngularJS: + +* [_Controllers_](https://docs.angularjs.org/guide/controller) provide + data to templates, and expose functionality that can be called from + templates. +* [_Directives_](https://docs.angularjs.org/guide/directive) effectively + extend HTML to provide custom behavior associated with specific + attributes and tags. +* [_Routes_](https://docs.angularjs.org/api/ngRoute/service/$route#example) + are used to associate specific URLs (including the fragment identifier) + with specific application states. (In Open MCT Web, these are used to + describe the mode of usage - e.g. browse or edit - as well as to + identify the object being used.) +* [_Templates_](https://docs.angularjs.org/guide/templates) are partial + HTML documents that will be rendered and kept up-to-date by AngularJS. + Open MCT Web introduces a custom `mct-include` directive which acts + as a wrapper around `ng-include` to allow templates to be referred + to by symbolic names. + +## Domain object representation + +The remaining extension categories in the presentation layer are specific +to displaying domain objects. + +* _Representations_ are templates that will be used to display + domain objects in specific ways (e.g. "as a tree node.") +* _Views_ are representations which are exposed to the user as options + for displaying domain objects. +* _Representers_ are extensions which modify or augment the process + of representing domain objects generally (e.g. by attaching + gestures to them.) +* _Gestures_ provide associations between specific user actions + (expressed as DOM events) and resulting behavior upon domain objects + (typically expressed as members of the `actions` extension category) + that can be reused across domain objects. For instance, `drag` and + `drop` are both gestures associated with using drag-and-drop to + modify the composition of domain objects by interacting with their + representations. # Information Model From 320be34798a0e57d6b2e511414115791a647d532 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 6 Aug 2015 11:44:28 -0700 Subject: [PATCH 26/40] [Documentation] Add clarifying comments Add clarifying comments to doc generator, MissionControl/vista#21. --- docs/gendocs.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/docs/gendocs.js b/docs/gendocs.js index d0cb008c02..90f6a2eef9 100644 --- a/docs/gendocs.js +++ b/docs/gendocs.js @@ -1,7 +1,32 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + /*global require,process,GLOBAL*/ /*jslint nomen: true*/ +// Usage: +// node gendocs.js --in --out + var CONSTANTS = { DIAGRAM_WIDTH: 800, DIAGRAM_HEIGHT: 500 @@ -22,6 +47,7 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define Canvas = require('canvas'), options = require("minimist")(process.argv.slice(2)); + // Convert from nomnoml source to a target PNG file. function renderNomnoml(source, target) { var canvas = new Canvas(CONSTANTS.DIAGRAM_WIDTH, CONSTANTS.DIAGRAM_HEIGHT); @@ -29,6 +55,11 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define canvas.pngStream().pipe(fs.createWriteStream(target)); } + // Stream transform. + // Pulls out nomnoml diagrams from fenced code blocks and renders them + // as PNG files in the output directory, prefixed with a provided name. + // The fenced code blocks will be replaced with Markdown in the + // output of this stream. function nomnomlifier(outputDirectory, prefix) { var transform = new stream.Transform({ objectMode: true }), isBuilding = false, @@ -70,6 +101,7 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define return transform; } + // Convert from Github-flavored Markdown to HTML function gfmifier() { var transform = new stream.Transform({ objectMode: true }), markdown = ""; @@ -86,6 +118,8 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define return transform; } + // Custom renderer for marked; converts relative links from md to html, + // and makes headings linkable. function CustomRenderer() { var renderer = new marked.Renderer(), customRenderer = Object.create(renderer); @@ -119,6 +153,9 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define smartypants: false }); + // Convert all markdown files. + // First, pull out nomnoml diagrams. + // Then, convert remaining Markdown to HTML. glob(options['in'] + "/**/*.md", {}, function (err, files) { files.forEach(function (file) { var destination = file.replace(options['in'], options.out) From be5253b9d3ed5c1e6d0f2425b2a6e48bdd6cbdba Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 6 Aug 2015 11:46:50 -0700 Subject: [PATCH 27/40] [Documentation] Update doc build/deployer MissionControl/vista#21 --- build-docs.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-docs.sh b/build-docs.sh index dd62c5ec41..c318a0dbda 100755 --- a/build-docs.sh +++ b/build-docs.sh @@ -24,7 +24,7 @@ # Script to build and deploy docs to github pages. -OUTPUT_DIRECTORY="docs" +OUTPUT_DIRECTORY="target/docs" REPOSITORY_URL="git@github.com:nasa/openmctweb.git" BUILD_SHA=`git rev-parse head` @@ -39,7 +39,7 @@ if [ -d $OUTPUT_DIRECTORY ]; then rm -rf $OUTPUT_DIRECTORY || exit 1 fi -npm run-script jsdoc +npm run docs cd $OUTPUT_DIRECTORY || exit 1 echo "git init" From 633c00f1614735633edc42dc00707f259aafbe9b Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 6 Aug 2015 11:53:04 -0700 Subject: [PATCH 28/40] [Documentation] Minor cleanup Minor cleanup around placeholder sections of documentation, MissionControl/vista#21 --- docs/src/guide/index.md | 2 +- docs/src/index.html | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/guide/index.md b/docs/src/guide/index.md index 0f72139a24..c575439d48 100644 --- a/docs/src/guide/index.md +++ b/docs/src/guide/index.md @@ -1,3 +1,3 @@ -# Hello, world! +# Developer Guide This is a placeholder for the developer guide. diff --git a/docs/src/index.html b/docs/src/index.html index fce129f9ce..e84b405234 100644 --- a/docs/src/index.html +++ b/docs/src/index.html @@ -26,6 +26,7 @@ Open MCT Web Documentation + Sections:
  • API
  • Developer Guide
  • From ddae7823f961e034f45e5d0cf0835a245174a00d Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 6 Aug 2015 11:57:57 -0700 Subject: [PATCH 29/40] [Documentation] Satisfy JSLint MissionControl/vista#21 --- docs/gendocs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gendocs.js b/docs/gendocs.js index 90f6a2eef9..2fcda7214e 100644 --- a/docs/gendocs.js +++ b/docs/gendocs.js @@ -21,7 +21,7 @@ *****************************************************************************/ /*global require,process,GLOBAL*/ -/*jslint nomen: true*/ +/*jslint nomen: false */ // Usage: From afddca510cba2460b7bcdeb3044b9ac328c9cebf Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 7 Aug 2015 13:47:32 -0700 Subject: [PATCH 30/40] [Documentation] Fix markdown Fix markdown typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c36cbea653..cb65eef811 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ To run: * Install protractor following the instructions above. * `webdriver-manager start` -* `node app.js -p 1984 -x platform/persistence/elastic -i example/persistence +* `node app.js -p 1984 -x platform/persistence/elastic -i example/persistence` * `protractor protractor/conf.js` ## Build From ef7c1bd0256db72f9fcdb57360d7da079940b7dc Mon Sep 17 00:00:00 2001 From: Jesse Date: Fri, 7 Aug 2015 11:28:18 -0700 Subject: [PATCH 31/40] Added Fix for Protractor Test --- protractor/README | 60 +++++++++++++++++++++++++++ protractor/StressTest.js | 27 ++++++------ protractor/StressTestBubble.js | 59 +++++++++++++++++++++++++++ protractor/StressTestCreateButton.js | 56 +++++++++++++++++++++++++ protractor/StressTestMenu.js | 55 +++++++++++++++++++++++++ protractor/StressTestNewPage.js | 61 ++++++++++++++++++++++++++++ protractor/StressTestRightClick.js | 59 +++++++++++++++++++++++++++ protractor/common/Launch.js | 4 +- protractor/common/RightMenu.js | 23 +++++++---- protractor/conf.js | 38 ++++++++--------- protractor/create/CreateTimer.js | 6 ++- 11 files changed, 405 insertions(+), 43 deletions(-) create mode 100644 protractor/README create mode 100644 protractor/StressTestBubble.js create mode 100644 protractor/StressTestCreateButton.js create mode 100644 protractor/StressTestMenu.js create mode 100644 protractor/StressTestNewPage.js create mode 100644 protractor/StressTestRightClick.js diff --git a/protractor/README b/protractor/README new file mode 100644 index 0000000000..d416d7092a --- /dev/null +++ b/protractor/README @@ -0,0 +1,60 @@ +E2e Protractor Tests. + +1. Instructions: + + 1. ctrl.sh: contains start up, stop, and run scripts. + * May need to modify DIRECTORY variable to reflect location of MMAP. * + -start: This will start 3 processes: MMAP, webdriver, and elastic search, all 3 are needed. + -run: run will run the protractor tests. (protractor conf.js) + -stop: stop will kill the 3 process started by the start command. + + 2. example: + cd protractor + ./ctrl.sh start + ./ctrl.sh run + *Note: multiple test can be run at this point. + ./ctrl.sh stop + +2. Directory Hierachy: + + -protractor: base directory + -common: contains prototype javascript functions that all other tests use. + -Buttons: common prototype functions related to enter fullscreen + -CreateItem: common prototype functions related to creating an item + -drag: common functions to test drag and drop. + -editItem: common functions used to test edit functionality. + -RightMenu: common functions for right click menu(remove). + -create + -e2e tests that creates the specified object. + -delete + -e2e tests that removes the specified object + -logs + -ctrl.sh redirects console output of MMAP, webdriver and elastic search and pipes them to log files. + -UI + -Contains tests that test the UI(drag drop, fullscreen, info bubble) + -conf.js: + -protractor config file. Explained below + + +3. Conf.js + Conf.js is used by protractor to setup and execute the tests. + -allScriptsTimeout: gives more time for protractor to synchronize with the page. + -jasmineNodeOpts: Protractor uses jasmine for the tests and jasmine has a default time out 30 seconds + per "it" test. Changed to maximume allowed time 360000 ms + -seleniumAddress: Protractor uses a Selenium server as a "proxy" between the test scripts and the browser + driver. A stand a lone version comes with protractor and to run use "webdriver-manager" + default address is: http://localhost:4444/wd/hub. + -specs[]: Is an array of files. Each File should have a "describe, it" test to be executed by protractor. + -capabilities: Tells protractor what browser to use and any browser arguments. + +4. StressTest: + Tests that are used to test for memory leaks. You can use the new tab option on WARP and then open the + timeline in the new tab during the browser.sleep(). Once the test is do the browser will pause and you can + look a the timeline results in the new tab. + NOTE: Cannot open chrome dev tools on same tab as the test are run on. Protractor uses the dev tools to + exectute the tests. + + -StressTest will create and delete folders. + -StressTestBubble.js: creates manny bubbles. + (Delay variable in InfoGesture.js was changed to 0) + \ No newline at end of file diff --git a/protractor/StressTest.js b/protractor/StressTest.js index 5e4a8b1507..789736a9e3 100644 --- a/protractor/StressTest.js +++ b/protractor/StressTest.js @@ -19,7 +19,6 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -//TODO Add filter for duplications/ var itemCreate = require("./common/CreateItem"); var itemEdit = require("./common/EditItem"); var right_click = require("./common/RightMenu.js"); @@ -41,31 +40,35 @@ describe('Create Folder', function() { }); it('should Create new Folder', function(){ browser.sleep(5000); - for(var i=0; i < 50; i++){ + for(var i=0; i < 25; i++){ browser.wait(function() { createClass.createButton().click(); return true; }).then(function (){ var folder = createClass.selectNewItem(ITEM_TYPE); expect(folder.getText()).toEqual([ ITEM_MENU_GLYPH ]); - browser.sleep(1000); + browser.sleep(500); folder.click() }).then(function() { browser.wait(function () { return element.all(by.model('ngModel[field]')).isDisplayed(); }) createClass.fillFolderForum(ITEM_NAME, ITEM_TYPE).click(); - browser.sleep(1000); + browser.sleep(500); }).then(function (){ - browser.sleep(1000); - // if(i === 1){ - clickClass.delete(ITEM_SIDE_SELECT, true); - element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); - // }else{ - browser.sleep(1000); - + browser.sleep(500); + clickClass.delete(ITEM_SIDE_SELECT, true); + //element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); + + + var MyItem = ">\nF\nMy Items" + element.all(by.repeater('child in composition')).filter(function (ele){ + return ele.getText().then(function(text) { + //expect(text).toEqual(MyItem); + return text === MyItem; + }); + }).all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); // clickClass.delete(ITEM_SIDE_SELECT, false); - // } }); } browser.pause(); diff --git a/protractor/StressTestBubble.js b/protractor/StressTestBubble.js new file mode 100644 index 0000000000..7cd4358bf1 --- /dev/null +++ b/protractor/StressTestBubble.js @@ -0,0 +1,59 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/StressTestBubble.jsStressTestBubble.js +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(10000); + for(var i=0; i < 1000; i++){ + var object = element.all(by.repeater('child in composition')).filter(function (ele){ + return ele.getText().then(function(text) { + return text === ">\nF\nMy Items"; + }); + }); + //browser.sleep(1000) + browser.actions().mouseMove(object.get(0)).perform(); + //browser.actions().click(protractor.Button.RIGHT).perform(); + + element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); + } + browser.pause(); + + }); + +}); diff --git a/protractor/StressTestCreateButton.js b/protractor/StressTestCreateButton.js new file mode 100644 index 0000000000..6fc2944df1 --- /dev/null +++ b/protractor/StressTestCreateButton.js @@ -0,0 +1,56 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(10000); + for(var i=0; i < 1000; i++){ + createClass.createButton().click(); + + //browser.sleep(1000) + //browser.actions().mouseMove(object.get(0)).perform(); + //browser.actions().click(protractor.Button.RIGHT).perform(); + + element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); + } + browser.pause(); + + }); + +}); diff --git a/protractor/StressTestMenu.js b/protractor/StressTestMenu.js new file mode 100644 index 0000000000..cc26e87d27 --- /dev/null +++ b/protractor/StressTestMenu.js @@ -0,0 +1,55 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(10000); + for(var i=0; i < 1000; i++){ + browser.wait(function() { + createClass.createButton().click(); + return true; + }).then(function (){ + element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); + }) + } + browser.pause(); + + }); + +}); diff --git a/protractor/StressTestNewPage.js b/protractor/StressTestNewPage.js new file mode 100644 index 0000000000..17f71607a9 --- /dev/null +++ b/protractor/StressTestNewPage.js @@ -0,0 +1,61 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); +var fullScreenFile = require("./common/FullScreen"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var fullScreenClass = new fullScreenFile(); + + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(15000); + for(var i=0; i < 1000; i++){ + fullScreenClass.newWidnow().click(); + + browser.getAllWindowHandles().then(function (handles) { + //browser.driver.switchTo().window(handles[1]); + browser.sleep(1000); + browser.driver.close(); + browser.sleep(1000); + // browser.driver.switchTo().window(handles[0]); + }); + } + browser.pause(); + + }); + +}); diff --git a/protractor/StressTestRightClick.js b/protractor/StressTestRightClick.js new file mode 100644 index 0000000000..35adb4a2b3 --- /dev/null +++ b/protractor/StressTestRightClick.js @@ -0,0 +1,59 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(8000); + for(var i=0; i < 1000; i++){ + var object = element.all(by.repeater('child in composition')).filter(function (ele){ + return ele.getText().then(function(text) { + return text === ">\nF\nMy Items"; + }); + }); + //browser.sleep(1000) + browser.actions().mouseMove(object.get(0)).perform(); + browser.actions().click(protractor.Button.RIGHT).perform(); + + element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); + } + browser.pause(); + + }); + +}); diff --git a/protractor/common/Launch.js b/protractor/common/Launch.js index 2b700672cc..0bc6e5f7f6 100644 --- a/protractor/common/Launch.js +++ b/protractor/common/Launch.js @@ -24,6 +24,6 @@ module.exports = function launch() { 'use strict'; browser.ignoreSynchronization = true; - browser.get('http://localhost:1984/'); - browser.sleep(2000); // 20 seconds + browser.get('http://localhost:1984/warp'); + browser.sleep(2000); // 2 seconds }; diff --git a/protractor/common/RightMenu.js b/protractor/common/RightMenu.js index 490d876d87..d1375d0533 100644 --- a/protractor/common/RightMenu.js +++ b/protractor/common/RightMenu.js @@ -24,18 +24,25 @@ var RightMenu = (function () { function RightMenu() { } + function carrotMyItem(){ + var MyItem = ">\nF\nMy Items" + element.all(by.repeater('child in composition')).filter(function (ele){ + return ele.getText().then(function(text) { + return text === MyItem; + }); + }).all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); + } //RightMenu Click on Object RightMenu.prototype.delete = function (name, flag) { if(typeof flag === 'undefined'){ flag = true; } if(flag === true){ - var carrot = element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).get(0).click(); + carrotMyItem(); } browser.sleep(1000) var object = element.all(by.repeater('child in composition')).filter(function (ele){ return ele.getText().then(function(text) { - //expect(text).toEqual("3"); return text === name; }); }); @@ -43,7 +50,7 @@ var RightMenu = (function () { browser.actions().mouseMove(object.get(0)).perform(); browser.actions().click(protractor.Button.RIGHT).perform(); browser.sleep(1000) - var remove = element.all(by.css('.ng-binding')).filter(function (ele){ + element.all(by.css('.ng-binding')).filter(function (ele){ return ele.getText().then(function (text) { return text == "Z\nRemove"; }) @@ -58,11 +65,10 @@ var RightMenu = (function () { }); }; RightMenu.prototype.reset = function (name) { - var carrot = element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); + carrotMyItem(); browser.sleep(1000) var object = element.all(by.repeater('child in composition')).filter(function (ele){ return ele.getText().then(function(text) { - //expect(text).toEqual("3"); return text === name; }); }).click(); @@ -75,19 +81,19 @@ var RightMenu = (function () { return text == "r\nRestart at 0"; }) }).click(); + browser.sleep(1000) }; + //click '<', true==yes false==no RightMenu.prototype.select = function(name, flag){ if(typeof flag == "undefined"){ flag = true; } - //click '<', true==yes false==no if(flag == true){ - var carrot = element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); + carrotMyItem(); } browser.sleep(1000) return element.all(by.repeater('child in composition')).filter(function (ele){ return ele.getText().then(function(text) { - // expect(text).toEqual("3"); return text === name; }); }); @@ -96,7 +102,6 @@ var RightMenu = (function () { RightMenu.prototype.dragDrop = function(name){ var object = element.all(by.repeater('child in composition')).filter(function (ele){ return ele.getText().then(function(text) { - //expect(text).toEqual("3"); return text === name; }); }); diff --git a/protractor/conf.js b/protractor/conf.js index c33e196157..183e514add 100644 --- a/protractor/conf.js +++ b/protractor/conf.js @@ -24,33 +24,33 @@ // conf.js exports.config = { allScriptsTimeout: 500000, - defaultTimeoutInterval: 60000, + jasmineNodeOpts: {defaultTimeoutInterval: 360000}, seleniumAddress: 'http://localhost:4444/wd/hub', - //specs: ['StressTest.js'], + //specs: ['StressTestCarrot.js'], specs: [ - //'create/CreateActivity.js', - //'delete/DeleteActivity.js', - //'create/CreateActivityMode.js', - //'delete/DeleteActivityMode.js', - //'create/CreateActivityMode.js', - //'create/CreateClock.js', - //'delete/DeleteClock.js', + 'create/CreateActivity.js', + 'delete/DeleteActivity.js', + 'create/CreateActivityMode.js', + 'delete/DeleteActivityMode.js', + 'create/CreateActivityMode.js', + 'create/CreateClock.js', + 'delete/DeleteClock.js', 'create/CreateDisplay.js', - //'delete/DeleteDisplay.js', + 'delete/DeleteDisplay.js', 'create/CreateFolder.js', - //'delete/DeleteFolder.js', + 'delete/DeleteFolder.js', 'create/CreateTelemetry.js', - //'delete/DeleteTelemetry.js', - //'create/CreateTimeline.js', - //'delete/DeleteTimeline.js', - //'create/CreateTimer.js', - //'delete/DeleteTimer.js', + 'delete/DeleteTelemetry.js', + 'create/CreateTimeline.js', + 'delete/DeleteTimeline.js', + 'create/CreateTimer.js', + 'delete/DeleteTimer.js', 'create/CreateWebPage.js', - //'delete/DeleteWebPage.js', + 'delete/DeleteWebPage.js', 'UI/Fullscreen.js', 'create/CreateButton.js', - //"UI/DragDrop.js", - //"UI/NewWindow.js", + "UI/DragDrop.js", + "UI/NewWindow.js", 'UI/InfoBubble.js' ], capabilities: { diff --git a/protractor/create/CreateTimer.js b/protractor/create/CreateTimer.js index d8059c1f59..e83fedfedf 100644 --- a/protractor/create/CreateTimer.js +++ b/protractor/create/CreateTimer.js @@ -63,7 +63,11 @@ describe('Create Timer', function() { browser.sleep(1000) var timer = element(by.css('.value.ng-binding.active')) timer.getText().then(function (time) { - expect(time).toEqual("0D 00:00:01") + var timerChecker = false; + if(time == "0D 00:00:01" || time == "0D 00:00:02"){ + timerChecker = true; + } + expect(timerChecker).toEqual(true) }) }); From 85f9d5a2da1c1e622ae9c6ca04b76d7cd7a880a6 Mon Sep 17 00:00:00 2001 From: Jesse Date: Mon, 10 Aug 2015 15:26:25 -0700 Subject: [PATCH 32/40] Added Start Run Stop Scripts --- protractor/bin/ctrl.sh | 90 +++++++++++++++++++ protractor/bin/run.js | 12 +++ protractor/bin/start.js | 40 +++++++++ protractor/bin/stop.js | 35 ++++++++ protractor/package.json | 18 ++++ protractor/stressTest/StressTest.js | 78 ++++++++++++++++ protractor/stressTest/StressTestBubble.js | 59 ++++++++++++ .../stressTest/StressTestCreateButton.js | 56 ++++++++++++ protractor/stressTest/StressTestMenu.js | 55 ++++++++++++ protractor/stressTest/StressTestNewPage.js | 61 +++++++++++++ protractor/stressTest/StressTestRightClick.js | 59 ++++++++++++ 11 files changed, 563 insertions(+) create mode 100755 protractor/bin/ctrl.sh create mode 100755 protractor/bin/run.js create mode 100755 protractor/bin/start.js create mode 100755 protractor/bin/stop.js create mode 100644 protractor/package.json create mode 100644 protractor/stressTest/StressTest.js create mode 100644 protractor/stressTest/StressTestBubble.js create mode 100644 protractor/stressTest/StressTestCreateButton.js create mode 100644 protractor/stressTest/StressTestMenu.js create mode 100644 protractor/stressTest/StressTestNewPage.js create mode 100644 protractor/stressTest/StressTestRightClick.js diff --git a/protractor/bin/ctrl.sh b/protractor/bin/ctrl.sh new file mode 100755 index 0000000000..faf385d2ad --- /dev/null +++ b/protractor/bin/ctrl.sh @@ -0,0 +1,90 @@ +#! /bin/bash +ARGUMENT=$1; + +if [ $# != 1 ]; then + echo "Expected 1 Aurgument. Received " $# 1>&2; + exit 1 +fi +#Start webdrive and http-server +if [ $ARGUMENT == start ]; then + echo "Creating Log Directory ..." + mkdir logs; + + cd .. + node app.js -p 1984 -x platform/persistence/elastic -i example/persistence > protractor/logs/nodeApp.log 2>&1 & + sleep 3; + if grep -iq "Error" protractor/logs/nodeApp.log; then + if grep -iq "minimist" protractor/logs/nodeApp.log; then + echo " Node Failed Because Minimist is not installed" + echo " Installng Minimist ..." + npm install minimist express > protractor/logs/minimist.log 2>&1 & + wait $! + if [ $? != 0 ]; then + echo " Error: minimist" + echo " Check Log file" + echo + else + echo " Started: Minimist" + echo + node app.js -p 1984 -x platform/persistence/elastic -i example/persistence > protractor/logs/nodeApp.log 2>&1 & + if grep -iq "Error" protractor/logs/nodeApp.log; then + echo " Error: node app failed" + echo " Check Log file" + echo + else + echo " Started: node app.js" + echo + fi + fi + else + echo " Error: node app failed" + echo " Check Log file" + echo + fi + else + echo " Started: node app.js" + echo + fi + echo "Starting webdriver ..." + + cd protractor; + webdriver-manager start > logs/webdriver.log 2>&1 & + sleep 3; + if grep -iq "Exception" logs/webdriver.log; then + echo " Error: webdriver-manager" + echo " Check Log file" + echo + else + echo " Started: webdriver-manager" + fi + echo "Starting Elastic Search..." + + elasticsearch > logs/elasticSearch.log 2>&1 & + sleep 3; + if grep -iq "Exception" logs/elasticSearch.log; then + echo " Error: ElasticSearch" + echo " Check Log file" + echo + else + echo " Started: ElasticSearch" + fi +#Runs Protractor tests +elif [ $ARGUMENT == run ]; then + protractor ./conf.js +#Kill Process +elif [ $ARGUMENT == stop ]; then + echo "Removing logs" + rm -rf logs + echo "Stopping Node" + kill $(ps aux | grep "[n]ode app.js"| awk '{print $2}'); + + echo "Stopping webdriver ..." + kill $(ps aux | grep "[p]rotractor" | awk '{print $2}'); + kill $(ps aux | grep "[w]ebdriver-manager" | awk '{print $2}'); + sleep 1; + echo "Stopping Elastic..." + kill $(ps aux | grep "[e]lastic" | awk '{print $2}'); + sleep 1; +else + echo "Unkown: Command" $1; +fi diff --git a/protractor/bin/run.js b/protractor/bin/run.js new file mode 100755 index 0000000000..316caa11d0 --- /dev/null +++ b/protractor/bin/run.js @@ -0,0 +1,12 @@ +#! /usr/bin/env node +var shell = require("shelljs/global"); +var sleep = require('sleep'); + +var command = __dirname + "/../node_modules/protractor/bin/protractor " +__dirname + "/../conf.js"; +console.log("Executing Protractor Test") +exec(command, function(code, output) { + if(code != 0){ + console.log('Exit code:', code); + console.log('Program output:', output); + } +}); \ No newline at end of file diff --git a/protractor/bin/start.js b/protractor/bin/start.js new file mode 100755 index 0000000000..682a557760 --- /dev/null +++ b/protractor/bin/start.js @@ -0,0 +1,40 @@ +#! /usr/bin/env node +var shell,sleep; +try { + shell = require("shelljs/global"); + sleep = require('sleep'); +}catch (e){ + console.log("Dependencies Error"); + console.log("Run npm install"); + throw (e); +} +///Users/jsanderf/git/elastic/wtd/protractor/bin +var startdir = process.cwd(); +var command; + + +command = __dirname + "/../node_modules/protractor/bin/webdriver-manager update"; +console.log("Installing Webdriver"); +exec(command,{async:false}); +sleep.sleep(1); + +console.log(); +cd(__dirname + '/../../'); +console.log('Installing Dependencies'); +exec("npm install minimist express", {async:false}); +console.log('Starting Node'); +sleep.sleep(1); +exec("node app.js -p 1984 -i example/localstorage > protractor/logs/nodeApp.log 2>&1 &", {async:false}); +console.log(' Started Node'); + +console.log(); +console.log('Starting Webdriver'); +sleep.sleep(1); +exec("protractor/node_modules/protractor/bin/webdriver-manager start > protractor/logs/webdriver.log 2>&1 &",{async:false}); +if(error() == null){ + console.log(" Webdriver Started"); +}else{ + console.log(" Error : ", error()); +} + +cd(startdir); \ No newline at end of file diff --git a/protractor/bin/stop.js b/protractor/bin/stop.js new file mode 100755 index 0000000000..2a911066ce --- /dev/null +++ b/protractor/bin/stop.js @@ -0,0 +1,35 @@ +#! /usr/bin/env node + +var shell = require("shelljs/global"); +var ps = require('psnode'); +var S = require('string'); + +// A simple pid lookup +ps.list(function(err, results) { + + results.forEach(function( process ){ + //Killing Node + if((process.command.indexOf("node app.js")) != -1) { + console.log(); + console.log( 'Killing Node: %s', process.command); + ps.kill(process.pid, function(err, stdout) { + if (err) { + throw new Error(err); + } + console.log(stdout); + }); + } + if((process.command.indexOf("webdriver")) != -1) { + console.log(); + console.log( 'Killing WebDriver: %s', process.command); + ps.kill(process.pid, function(err, stdout) { + if (err){ + throw new Error(err); + } + console.log(stdout); + }); + } + }); +}); + + diff --git a/protractor/package.json b/protractor/package.json new file mode 100644 index 0000000000..3b76de41f3 --- /dev/null +++ b/protractor/package.json @@ -0,0 +1,18 @@ +{ + "name": "protractorCtr", + "version": "1.0.0", + "bin": { + "start": "bin/start.js", + "run" : "bin/run.js", + "stop" : "bin/stop.js" + }, + "dependencies": { + "protractor": "^2.1.0", + "psnode": "0.0.1", + "shelljs": "^0.5.2", + "sleep": "^3.0.0", + "string": "^3.3.1" + }, + "description": "E2e Protractor Tests.", + "license": "ISC" +} diff --git a/protractor/stressTest/StressTest.js b/protractor/stressTest/StressTest.js new file mode 100644 index 0000000000..789736a9e3 --- /dev/null +++ b/protractor/stressTest/StressTest.js @@ -0,0 +1,78 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(5000); + for(var i=0; i < 25; i++){ + browser.wait(function() { + createClass.createButton().click(); + return true; + }).then(function (){ + var folder = createClass.selectNewItem(ITEM_TYPE); + expect(folder.getText()).toEqual([ ITEM_MENU_GLYPH ]); + browser.sleep(500); + folder.click() + }).then(function() { + browser.wait(function () { + return element.all(by.model('ngModel[field]')).isDisplayed(); + }) + createClass.fillFolderForum(ITEM_NAME, ITEM_TYPE).click(); + browser.sleep(500); + }).then(function (){ + browser.sleep(500); + clickClass.delete(ITEM_SIDE_SELECT, true); + //element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); + + + var MyItem = ">\nF\nMy Items" + element.all(by.repeater('child in composition')).filter(function (ele){ + return ele.getText().then(function(text) { + //expect(text).toEqual(MyItem); + return text === MyItem; + }); + }).all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); + // clickClass.delete(ITEM_SIDE_SELECT, false); + }); + } + browser.pause(); + + }); + +}); diff --git a/protractor/stressTest/StressTestBubble.js b/protractor/stressTest/StressTestBubble.js new file mode 100644 index 0000000000..7cd4358bf1 --- /dev/null +++ b/protractor/stressTest/StressTestBubble.js @@ -0,0 +1,59 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/StressTestBubble.jsStressTestBubble.js +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(10000); + for(var i=0; i < 1000; i++){ + var object = element.all(by.repeater('child in composition')).filter(function (ele){ + return ele.getText().then(function(text) { + return text === ">\nF\nMy Items"; + }); + }); + //browser.sleep(1000) + browser.actions().mouseMove(object.get(0)).perform(); + //browser.actions().click(protractor.Button.RIGHT).perform(); + + element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); + } + browser.pause(); + + }); + +}); diff --git a/protractor/stressTest/StressTestCreateButton.js b/protractor/stressTest/StressTestCreateButton.js new file mode 100644 index 0000000000..6fc2944df1 --- /dev/null +++ b/protractor/stressTest/StressTestCreateButton.js @@ -0,0 +1,56 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(10000); + for(var i=0; i < 1000; i++){ + createClass.createButton().click(); + + //browser.sleep(1000) + //browser.actions().mouseMove(object.get(0)).perform(); + //browser.actions().click(protractor.Button.RIGHT).perform(); + + element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); + } + browser.pause(); + + }); + +}); diff --git a/protractor/stressTest/StressTestMenu.js b/protractor/stressTest/StressTestMenu.js new file mode 100644 index 0000000000..cc26e87d27 --- /dev/null +++ b/protractor/stressTest/StressTestMenu.js @@ -0,0 +1,55 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(10000); + for(var i=0; i < 1000; i++){ + browser.wait(function() { + createClass.createButton().click(); + return true; + }).then(function (){ + element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); + }) + } + browser.pause(); + + }); + +}); diff --git a/protractor/stressTest/StressTestNewPage.js b/protractor/stressTest/StressTestNewPage.js new file mode 100644 index 0000000000..17f71607a9 --- /dev/null +++ b/protractor/stressTest/StressTestNewPage.js @@ -0,0 +1,61 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); +var fullScreenFile = require("./common/FullScreen"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var fullScreenClass = new fullScreenFile(); + + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(15000); + for(var i=0; i < 1000; i++){ + fullScreenClass.newWidnow().click(); + + browser.getAllWindowHandles().then(function (handles) { + //browser.driver.switchTo().window(handles[1]); + browser.sleep(1000); + browser.driver.close(); + browser.sleep(1000); + // browser.driver.switchTo().window(handles[0]); + }); + } + browser.pause(); + + }); + +}); diff --git a/protractor/stressTest/StressTestRightClick.js b/protractor/stressTest/StressTestRightClick.js new file mode 100644 index 0000000000..35adb4a2b3 --- /dev/null +++ b/protractor/stressTest/StressTestRightClick.js @@ -0,0 +1,59 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +var itemCreate = require("./common/CreateItem"); +var itemEdit = require("./common/EditItem"); +var right_click = require("./common/RightMenu.js"); + +describe('Create Folder', function() { + var clickClass = new right_click(); + var createClass = new itemCreate(); + var editItemClass = new itemEdit(); + var ITEM_NAME = "Folder"; + var ITEM_TYPE = "folder"; + var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; + var ITEM_SIDE_SELECT = ">\nF\nFolder" + + beforeEach(function() { + browser.ignoreSynchronization = true; + browser.get('http://localhost:1984/warp/'); + browser.sleep(2000); // 20 seconds + }); + it('should Create new Folder', function(){ + browser.sleep(8000); + for(var i=0; i < 1000; i++){ + var object = element.all(by.repeater('child in composition')).filter(function (ele){ + return ele.getText().then(function(text) { + return text === ">\nF\nMy Items"; + }); + }); + //browser.sleep(1000) + browser.actions().mouseMove(object.get(0)).perform(); + browser.actions().click(protractor.Button.RIGHT).perform(); + + element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); + } + browser.pause(); + + }); + +}); From fde0dc2a352be131efb6a99ec5e4ac11fbbe815a Mon Sep 17 00:00:00 2001 From: Jesse Date: Mon, 10 Aug 2015 16:04:31 -0700 Subject: [PATCH 33/40] Added start.js Creates 'log' folder --- protractor/README | 37 ++++++++++++++++++++++++------------- protractor/bin/start.js | 2 +- protractor/bin/stop.js | 10 ++++++++++ protractor/common/Launch.js | 2 +- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/protractor/README b/protractor/README index d416d7092a..efb01d7623 100644 --- a/protractor/README +++ b/protractor/README @@ -2,19 +2,30 @@ E2e Protractor Tests. 1. Instructions: - 1. ctrl.sh: contains start up, stop, and run scripts. - * May need to modify DIRECTORY variable to reflect location of MMAP. * - -start: This will start 3 processes: MMAP, webdriver, and elastic search, all 3 are needed. - -run: run will run the protractor tests. (protractor conf.js) - -stop: stop will kill the 3 process started by the start command. - - 2. example: - cd protractor - ./ctrl.sh start - ./ctrl.sh run - *Note: multiple test can be run at this point. - ./ctrl.sh stop - + 1. 3 Control Scripts located in bin/. + run.js : node script used to start tests + start.js : node script used to setup test(starts node,localstorage and webdriver) + stop.js : node script, kills the 3 process started in start.js. + + 2. Use npm(Node Package Mangager) to Run Scripts. + *"npm link" will put the scripts on your system path. + a. cd protractor; + b. npm install; + c. npm link; (optional) + d. script_name + -start + -run + -stop + + (optional: Scripts NOT on path) + a. To Run + -./bin/start.js + -./bin/run.js + -./bin/stop.js + 3. To remove the scripts from path run + -npm unlink + + 2. Directory Hierachy: -protractor: base directory diff --git a/protractor/bin/start.js b/protractor/bin/start.js index 682a557760..106be4cd58 100755 --- a/protractor/bin/start.js +++ b/protractor/bin/start.js @@ -11,7 +11,7 @@ try { ///Users/jsanderf/git/elastic/wtd/protractor/bin var startdir = process.cwd(); var command; - +mkdir(__dirname + '/../logs'); command = __dirname + "/../node_modules/protractor/bin/webdriver-manager update"; console.log("Installing Webdriver"); diff --git a/protractor/bin/stop.js b/protractor/bin/stop.js index 2a911066ce..df8de37082 100755 --- a/protractor/bin/stop.js +++ b/protractor/bin/stop.js @@ -29,6 +29,16 @@ ps.list(function(err, results) { console.log(stdout); }); } + if((process.command.indexOf("protractor")) != -1) { + console.log(); + console.log( 'Killing Protractor Driver: %s', process.command); + ps.kill(process.pid, function(err, stdout) { + if (err){ + throw new Error(err); + } + console.log(stdout); + }); + } }); }); diff --git a/protractor/common/Launch.js b/protractor/common/Launch.js index 0bc6e5f7f6..fd745f94c3 100644 --- a/protractor/common/Launch.js +++ b/protractor/common/Launch.js @@ -24,6 +24,6 @@ module.exports = function launch() { 'use strict'; browser.ignoreSynchronization = true; - browser.get('http://localhost:1984/warp'); + browser.get('http://localhost:1984'); browser.sleep(2000); // 2 seconds }; From 7918d7b2878a924d7efc705d2077e2f2d1d66443 Mon Sep 17 00:00:00 2001 From: Jesse Date: Tue, 11 Aug 2015 11:47:52 -0700 Subject: [PATCH 34/40] Updated README and Renamed Tests --- protractor/README | 14 +++--- protractor/UI/Fullscreen.js | 2 +- protractor/UI/InfoBubble.js | 2 +- protractor/UI/NewWindow.js | 2 +- protractor/UI/RightClick.js | 62 +++++++++++++++++++------ protractor/bin/clean.js | 15 ++++++ protractor/bin/start.js | 4 +- protractor/bin/stop.js | 12 +---- protractor/conf.js | 4 +- protractor/create/CreateActivityMode.js | 2 +- protractor/create/CreateClock.js | 35 ++++++++------ protractor/package.json | 6 ++- 12 files changed, 107 insertions(+), 53 deletions(-) create mode 100755 protractor/bin/clean.js diff --git a/protractor/README b/protractor/README index efb01d7623..be1296bca5 100644 --- a/protractor/README +++ b/protractor/README @@ -8,15 +8,15 @@ E2e Protractor Tests. stop.js : node script, kills the 3 process started in start.js. 2. Use npm(Node Package Mangager) to Run Scripts. - *"npm link" will put the scripts on your system path. a. cd protractor; b. npm install; - c. npm link; (optional) - d. script_name - -start - -run - -stop - + c. To Run: + -npm start : will start processes need by protractor + -npm stop : will stop the processes need by protractor + -npm run-script run : will execute Protractor Script + -npm run-script all : will execute "start", "run", and "stop" script + - + (optional: Scripts NOT on path) a. To Run -./bin/start.js diff --git a/protractor/UI/Fullscreen.js b/protractor/UI/Fullscreen.js index 3c1c785228..532ad318d8 100644 --- a/protractor/UI/Fullscreen.js +++ b/protractor/UI/Fullscreen.js @@ -22,7 +22,7 @@ //TODO Add filter for duplications/ var fullScreenFile = require("../common/Buttons"); -describe('Test Fullscreen', function() { +describe('Enable Fullscreen', function() { var fullScreenClass = new fullScreenFile(); beforeEach(require('../common/Launch')); diff --git a/protractor/UI/InfoBubble.js b/protractor/UI/InfoBubble.js index 274b7966b0..c88e9018d0 100644 --- a/protractor/UI/InfoBubble.js +++ b/protractor/UI/InfoBubble.js @@ -25,7 +25,7 @@ var itemEdit = require("../common/EditItem"); var rightMenu = require("../common/RightMenu"); var Drag = require("../common/drag"); -describe('Test Info Bubble', function() { +describe('Info Bubble', function() { var fullScreenClass = new fullScreenFile(); var createClass = new createItem(); var editItemClass = new itemEdit(); diff --git a/protractor/UI/NewWindow.js b/protractor/UI/NewWindow.js index 7a714d79a2..1e98bbc8b4 100644 --- a/protractor/UI/NewWindow.js +++ b/protractor/UI/NewWindow.js @@ -24,7 +24,7 @@ var createClassFile = require("../common/CreateItem") var itemEdit = require("../common/EditItem"); var rightMenu = require("../common/RightMenu.js"); -describe('Test New Window', function() { +describe('New Window', function() { var fullScreenClass = new fullScreenFile(); var createClass = new createClassFile(); var editItemClass = new itemEdit(); diff --git a/protractor/UI/RightClick.js b/protractor/UI/RightClick.js index 0ae4dd0708..5f7d389313 100644 --- a/protractor/UI/RightClick.js +++ b/protractor/UI/RightClick.js @@ -21,28 +21,64 @@ *****************************************************************************/ var right_click = require("../common/RightMenu.js"); var Create = require("../common/CreateItem") -describe('Right Click Interations', function() { +var itemEdit = require("../common/EditItem"); + +describe('The Right Menu', function() { var clickClass = new right_click(); var createClass = new Create(); + var editItemClass = new itemEdit(); var ITEM_NAME = "Folder"; var ITEM_TYPE = "folder"; var ITEM_MENU_GLYPH = 'F\nFolder'; + var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; beforeEach(require('../common/Launch')); - it('should delete the specified object', function(){ - createClass.createButton().click(); - var folder = createClass.selectNewItem(ITEM_TYPE); - expect(folder.getText()).toEqual([ ITEM_MENU_GLYPH ]); - browser.sleep(1000); - folder.click() - browser.sleep(1000); - browser.wait(function () { - return element.all(by.model('ngModel[field]')).isDisplayed(); + it('should Dissapear After Delete', function(){ + browser.wait(function() { + createClass.createButton().click(); + return true; + }).then(function (){ + var folder = createClass.selectNewItem(ITEM_TYPE); + expect(folder.getText()).toEqual([ ITEM_MENU_GLYPH ]); + browser.sleep(1000); + folder.click() + }).then(function() { + browser.wait(function () { + return element.all(by.model('ngModel[field]')).isDisplayed(); + }) + createClass.fillFolderForum(ITEM_NAME, ITEM_TYPE).click(); + browser.sleep(1000); + }).then(function (){ + var item = editItemClass.SelectItem(ITEM_GRID_SELECT); + expect(item.count()).toBe(1); + browser.sleep(1000); + }).then(function () { + var MyItem = ">\nF\nMy Items" + element.all(by.repeater('child in composition')).filter(function (ele){ + return ele.getText().then(function(text) { + return text === MyItem; + }); + }).all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); + var object = element.all(by.repeater('child in composition')).filter(function (ele){ + return ele.getText().then(function(text) { + return text === ">\nF\nFolder"; + }); + }); + browser.sleep(1000) + browser.actions().mouseMove(object.get(0)).perform(); + browser.actions().click(protractor.Button.RIGHT).perform(); + browser.sleep(1000) + var menu = element.all(by.css('.ng-binding')).filter(function (ele){ + return ele.getText().then(function (text) { + return text == "Z\nRemove"; + }) + }) + menu.click(); + browser.sleep(1000) + + expect(menu.isDisplayed()).toBe(false); }) - createClass.fillFolderForum(ITEM_NAME, ITEM_TYPE).click(); - clickClass.delete(ITEM_NAME); - browser.sleep(1000); }); }); diff --git a/protractor/bin/clean.js b/protractor/bin/clean.js new file mode 100755 index 0000000000..82e776901f --- /dev/null +++ b/protractor/bin/clean.js @@ -0,0 +1,15 @@ +#! /usr/bin/env node +var shell = require("shelljs/global"); + +var startdir = process.cwd(); +var command = "npm unlink"; + +console.log("Cleaning Directory") +exec(command, function(code, output) { + if(code != 0){ + console.log('Exit code:', code); + console.log('Program output:', output); + } +}); +console.log("rm -rf node_modules") +rm('-rf', __dirname + "/../node_modules") diff --git a/protractor/bin/start.js b/protractor/bin/start.js index 106be4cd58..e902b79b51 100755 --- a/protractor/bin/start.js +++ b/protractor/bin/start.js @@ -30,11 +30,11 @@ console.log(' Started Node'); console.log(); console.log('Starting Webdriver'); sleep.sleep(1); -exec("protractor/node_modules/protractor/bin/webdriver-manager start > protractor/logs/webdriver.log 2>&1 &",{async:false}); +exec("protractor/node_modules/protractor/bin/webdriver-manager start --standalone> protractor/logs/webdriver.log 2>&1 &",{async:false}); if(error() == null){ console.log(" Webdriver Started"); }else{ console.log(" Error : ", error()); } - +sleep.sleep(1); cd(startdir); \ No newline at end of file diff --git a/protractor/bin/stop.js b/protractor/bin/stop.js index df8de37082..d47e366348 100755 --- a/protractor/bin/stop.js +++ b/protractor/bin/stop.js @@ -3,6 +3,7 @@ var shell = require("shelljs/global"); var ps = require('psnode'); var S = require('string'); +var sleep = require('sleep'); // A simple pid lookup ps.list(function(err, results) { @@ -19,6 +20,7 @@ ps.list(function(err, results) { console.log(stdout); }); } + sleep.usleep(10000); if((process.command.indexOf("webdriver")) != -1) { console.log(); console.log( 'Killing WebDriver: %s', process.command); @@ -29,16 +31,6 @@ ps.list(function(err, results) { console.log(stdout); }); } - if((process.command.indexOf("protractor")) != -1) { - console.log(); - console.log( 'Killing Protractor Driver: %s', process.command); - ps.kill(process.pid, function(err, stdout) { - if (err){ - throw new Error(err); - } - console.log(stdout); - }); - } }); }); diff --git a/protractor/conf.js b/protractor/conf.js index 183e514add..493c196c46 100644 --- a/protractor/conf.js +++ b/protractor/conf.js @@ -32,7 +32,6 @@ exports.config = { 'delete/DeleteActivity.js', 'create/CreateActivityMode.js', 'delete/DeleteActivityMode.js', - 'create/CreateActivityMode.js', 'create/CreateClock.js', 'delete/DeleteClock.js', 'create/CreateDisplay.js', @@ -51,7 +50,8 @@ exports.config = { 'create/CreateButton.js', "UI/DragDrop.js", "UI/NewWindow.js", - 'UI/InfoBubble.js' + 'UI/InfoBubble.js', + 'UI/RightClick.js' ], capabilities: { 'browserName': 'chrome', // or 'safari' diff --git a/protractor/create/CreateActivityMode.js b/protractor/create/CreateActivityMode.js index e9469749aa..17ed700ae6 100644 --- a/protractor/create/CreateActivityMode.js +++ b/protractor/create/CreateActivityMode.js @@ -22,7 +22,7 @@ var itemCreate = require("../common/CreateItem"); var itemEdit = require("../common/EditItem"); -describe('Create Web Page', function() { +describe('Create Activity Mode', function() { var createClass = new itemCreate(); var editItemClass = new itemEdit(); var ITEM_NAME = "Activity Mode"; diff --git a/protractor/create/CreateClock.js b/protractor/create/CreateClock.js index d1dc781b58..c427d91a11 100644 --- a/protractor/create/CreateClock.js +++ b/protractor/create/CreateClock.js @@ -57,7 +57,7 @@ describe('Create Clock', function() { }); it('should check clock', function () { - function getTime() { + function getTime(flag) { function addZero(time){ if(time < 10){ return '0' + time; @@ -66,7 +66,6 @@ describe('Create Clock', function() { } var currentdate = new Date(); - var month = currentdate.getMonth() + 1; month = addZero(month); @@ -77,6 +76,9 @@ describe('Create Clock', function() { hour = addZero(hour); var second = currentdate.getSeconds(); + if(flag == true) { + second = second + 1; + } second = addZero(second); var minute = currentdate.getMinutes(); @@ -85,17 +87,24 @@ describe('Create Clock', function() { return ("UTC " + currentdate.getFullYear() + "/" + (month) + "/" + day + " " + (hour) + ":" + minute + ":" + second + " PM"); } - - var current,clock; - rightClickClass.select(ITEM_MENU_GLYPH, true).click().then(function () { - browser.sleep(1000); - current = browser.executeScript(getTime); - }).then(function () { - clock = element(by.css('.l-time-display.l-digital.l-clock.s-clock.ng-scope')); - clock.getText().then(function (time) { - expect(current).toEqual(time); - }) + this.addMatchers({ + toBeIn: function(expected){ + var posibilities = Array.isArray(this.actual) ? this.actual : [this.actual]; + return posibilities.indexOf(expected) > -1; + } }) - + var current,current1,clock; + rightClickClass.select(ITEM_MENU_GLYPH, true).click().then(function () { + browser.sleep(1000); + browser.executeScript(getTime, false).then(function(current){ + browser.executeScript(getTime, true).then(function(current1) { + clock = element(by.css('.l-time-display.l-digital.l-clock.s-clock.ng-scope')); + clock.getText().then(function (ele) { + expect([current,current1]).toBeIn(ele); + }) + }); + }); + + }) }); }); diff --git a/protractor/package.json b/protractor/package.json index 3b76de41f3..015a75e321 100644 --- a/protractor/package.json +++ b/protractor/package.json @@ -1,10 +1,12 @@ { "name": "protractorCtr", "version": "1.0.0", - "bin": { + "scripts" : { "start": "bin/start.js", "run" : "bin/run.js", - "stop" : "bin/stop.js" + "stop" : "bin/stop.js", + "all" : "bin/start.js; bin/run.js; bin/stop.js;", + "clean": "bin/clean.js" }, "dependencies": { "protractor": "^2.1.0", From eb10cbf87cdd77a953aaeb986d62d01a459701c3 Mon Sep 17 00:00:00 2001 From: Jesse Date: Tue, 11 Aug 2015 13:55:50 -0700 Subject: [PATCH 35/40] Cleaned Up Directory --- protractor/README | 18 ++--- protractor/StressTest.js | 78 ------------------- protractor/StressTestBubble.js | 59 -------------- protractor/StressTestCreateButton.js | 56 ------------- protractor/StressTestMenu.js | 55 ------------- protractor/StressTestNewPage.js | 61 --------------- protractor/StressTestRightClick.js | 59 -------------- protractor/create/CreateClock.js | 3 +- protractor/stressTest/StressTest.js | 6 +- protractor/stressTest/StressTestBubble.js | 6 +- .../stressTest/StressTestCreateButton.js | 6 +- protractor/stressTest/StressTestMenu.js | 6 +- protractor/stressTest/StressTestNewPage.js | 8 +- protractor/stressTest/StressTestRightClick.js | 6 +- 14 files changed, 25 insertions(+), 402 deletions(-) delete mode 100644 protractor/StressTest.js delete mode 100644 protractor/StressTestBubble.js delete mode 100644 protractor/StressTestCreateButton.js delete mode 100644 protractor/StressTestMenu.js delete mode 100644 protractor/StressTestNewPage.js delete mode 100644 protractor/StressTestRightClick.js diff --git a/protractor/README b/protractor/README index be1296bca5..17c38e6fe3 100644 --- a/protractor/README +++ b/protractor/README @@ -3,9 +3,10 @@ E2e Protractor Tests. 1. Instructions: 1. 3 Control Scripts located in bin/. - run.js : node script used to start tests - start.js : node script used to setup test(starts node,localstorage and webdriver) - stop.js : node script, kills the 3 process started in start.js. + run.js : node script used to start tests + start.js: node script used to setup test(starts node,localstorage and webdriver) + stop.js : node script, kills the 3 process started in start.js. + clean.js: node script used to remove the node_module directory.(clean up directory). 2. Use npm(Node Package Mangager) to Run Scripts. a. cd protractor; @@ -15,17 +16,7 @@ E2e Protractor Tests. -npm stop : will stop the processes need by protractor -npm run-script run : will execute Protractor Script -npm run-script all : will execute "start", "run", and "stop" script - - - (optional: Scripts NOT on path) - a. To Run - -./bin/start.js - -./bin/run.js - -./bin/stop.js - 3. To remove the scripts from path run - -npm unlink - - 2. Directory Hierachy: -protractor: base directory @@ -34,6 +25,7 @@ E2e Protractor Tests. -CreateItem: common prototype functions related to creating an item -drag: common functions to test drag and drop. -editItem: common functions used to test edit functionality. + -Launch: common script used to navigate the specified website. -RightMenu: common functions for right click menu(remove). -create -e2e tests that creates the specified object. diff --git a/protractor/StressTest.js b/protractor/StressTest.js deleted file mode 100644 index 789736a9e3..0000000000 --- a/protractor/StressTest.js +++ /dev/null @@ -1,78 +0,0 @@ -/***************************************************************************** - * Open MCT Web, Copyright (c) 2014-2015, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT Web is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT Web includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); - -describe('Create Folder', function() { - var clickClass = new right_click(); - var createClass = new itemCreate(); - var editItemClass = new itemEdit(); - var ITEM_NAME = "Folder"; - var ITEM_TYPE = "folder"; - var ITEM_MENU_GLYPH = 'F\nFolder'; - var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; - var ITEM_SIDE_SELECT = ">\nF\nFolder" - - beforeEach(function() { - browser.ignoreSynchronization = true; - browser.get('http://localhost:1984/warp/'); - browser.sleep(2000); // 20 seconds - }); - it('should Create new Folder', function(){ - browser.sleep(5000); - for(var i=0; i < 25; i++){ - browser.wait(function() { - createClass.createButton().click(); - return true; - }).then(function (){ - var folder = createClass.selectNewItem(ITEM_TYPE); - expect(folder.getText()).toEqual([ ITEM_MENU_GLYPH ]); - browser.sleep(500); - folder.click() - }).then(function() { - browser.wait(function () { - return element.all(by.model('ngModel[field]')).isDisplayed(); - }) - createClass.fillFolderForum(ITEM_NAME, ITEM_TYPE).click(); - browser.sleep(500); - }).then(function (){ - browser.sleep(500); - clickClass.delete(ITEM_SIDE_SELECT, true); - //element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); - - - var MyItem = ">\nF\nMy Items" - element.all(by.repeater('child in composition')).filter(function (ele){ - return ele.getText().then(function(text) { - //expect(text).toEqual(MyItem); - return text === MyItem; - }); - }).all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click(); - // clickClass.delete(ITEM_SIDE_SELECT, false); - }); - } - browser.pause(); - - }); - -}); diff --git a/protractor/StressTestBubble.js b/protractor/StressTestBubble.js deleted file mode 100644 index 7cd4358bf1..0000000000 --- a/protractor/StressTestBubble.js +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************** - * Open MCT Web, Copyright (c) 2014-2015, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT Web is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT Web includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/StressTestBubble.jsStressTestBubble.js -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); - -describe('Create Folder', function() { - var clickClass = new right_click(); - var createClass = new itemCreate(); - var editItemClass = new itemEdit(); - var ITEM_NAME = "Folder"; - var ITEM_TYPE = "folder"; - var ITEM_MENU_GLYPH = 'F\nFolder'; - var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; - var ITEM_SIDE_SELECT = ">\nF\nFolder" - - beforeEach(function() { - browser.ignoreSynchronization = true; - browser.get('http://localhost:1984/warp/'); - browser.sleep(2000); // 20 seconds - }); - it('should Create new Folder', function(){ - browser.sleep(10000); - for(var i=0; i < 1000; i++){ - var object = element.all(by.repeater('child in composition')).filter(function (ele){ - return ele.getText().then(function(text) { - return text === ">\nF\nMy Items"; - }); - }); - //browser.sleep(1000) - browser.actions().mouseMove(object.get(0)).perform(); - //browser.actions().click(protractor.Button.RIGHT).perform(); - - element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); - } - browser.pause(); - - }); - -}); diff --git a/protractor/StressTestCreateButton.js b/protractor/StressTestCreateButton.js deleted file mode 100644 index 6fc2944df1..0000000000 --- a/protractor/StressTestCreateButton.js +++ /dev/null @@ -1,56 +0,0 @@ -/***************************************************************************** - * Open MCT Web, Copyright (c) 2014-2015, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT Web is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT Web includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); - -describe('Create Folder', function() { - var clickClass = new right_click(); - var createClass = new itemCreate(); - var editItemClass = new itemEdit(); - var ITEM_NAME = "Folder"; - var ITEM_TYPE = "folder"; - var ITEM_MENU_GLYPH = 'F\nFolder'; - var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; - var ITEM_SIDE_SELECT = ">\nF\nFolder" - - beforeEach(function() { - browser.ignoreSynchronization = true; - browser.get('http://localhost:1984/warp/'); - browser.sleep(2000); // 20 seconds - }); - it('should Create new Folder', function(){ - browser.sleep(10000); - for(var i=0; i < 1000; i++){ - createClass.createButton().click(); - - //browser.sleep(1000) - //browser.actions().mouseMove(object.get(0)).perform(); - //browser.actions().click(protractor.Button.RIGHT).perform(); - - element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); - } - browser.pause(); - - }); - -}); diff --git a/protractor/StressTestMenu.js b/protractor/StressTestMenu.js deleted file mode 100644 index cc26e87d27..0000000000 --- a/protractor/StressTestMenu.js +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************** - * Open MCT Web, Copyright (c) 2014-2015, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT Web is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT Web includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); - -describe('Create Folder', function() { - var clickClass = new right_click(); - var createClass = new itemCreate(); - var editItemClass = new itemEdit(); - var ITEM_NAME = "Folder"; - var ITEM_TYPE = "folder"; - var ITEM_MENU_GLYPH = 'F\nFolder'; - var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; - var ITEM_SIDE_SELECT = ">\nF\nFolder" - - beforeEach(function() { - browser.ignoreSynchronization = true; - browser.get('http://localhost:1984/warp/'); - browser.sleep(2000); // 20 seconds - }); - it('should Create new Folder', function(){ - browser.sleep(10000); - for(var i=0; i < 1000; i++){ - browser.wait(function() { - createClass.createButton().click(); - return true; - }).then(function (){ - element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); - }) - } - browser.pause(); - - }); - -}); diff --git a/protractor/StressTestNewPage.js b/protractor/StressTestNewPage.js deleted file mode 100644 index 17f71607a9..0000000000 --- a/protractor/StressTestNewPage.js +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************** - * Open MCT Web, Copyright (c) 2014-2015, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT Web is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT Web includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); -var fullScreenFile = require("./common/FullScreen"); - -describe('Create Folder', function() { - var clickClass = new right_click(); - var createClass = new itemCreate(); - var editItemClass = new itemEdit(); - var fullScreenClass = new fullScreenFile(); - - var ITEM_NAME = "Folder"; - var ITEM_TYPE = "folder"; - var ITEM_MENU_GLYPH = 'F\nFolder'; - var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; - var ITEM_SIDE_SELECT = ">\nF\nFolder" - - beforeEach(function() { - browser.ignoreSynchronization = true; - browser.get('http://localhost:1984/warp/'); - browser.sleep(2000); // 20 seconds - }); - it('should Create new Folder', function(){ - browser.sleep(15000); - for(var i=0; i < 1000; i++){ - fullScreenClass.newWidnow().click(); - - browser.getAllWindowHandles().then(function (handles) { - //browser.driver.switchTo().window(handles[1]); - browser.sleep(1000); - browser.driver.close(); - browser.sleep(1000); - // browser.driver.switchTo().window(handles[0]); - }); - } - browser.pause(); - - }); - -}); diff --git a/protractor/StressTestRightClick.js b/protractor/StressTestRightClick.js deleted file mode 100644 index 35adb4a2b3..0000000000 --- a/protractor/StressTestRightClick.js +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************** - * Open MCT Web, Copyright (c) 2014-2015, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT Web is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT Web includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); - -describe('Create Folder', function() { - var clickClass = new right_click(); - var createClass = new itemCreate(); - var editItemClass = new itemEdit(); - var ITEM_NAME = "Folder"; - var ITEM_TYPE = "folder"; - var ITEM_MENU_GLYPH = 'F\nFolder'; - var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items'; - var ITEM_SIDE_SELECT = ">\nF\nFolder" - - beforeEach(function() { - browser.ignoreSynchronization = true; - browser.get('http://localhost:1984/warp/'); - browser.sleep(2000); // 20 seconds - }); - it('should Create new Folder', function(){ - browser.sleep(8000); - for(var i=0; i < 1000; i++){ - var object = element.all(by.repeater('child in composition')).filter(function (ele){ - return ele.getText().then(function(text) { - return text === ">\nF\nMy Items"; - }); - }); - //browser.sleep(1000) - browser.actions().mouseMove(object.get(0)).perform(); - browser.actions().click(protractor.Button.RIGHT).perform(); - - element.all(by.css('.items-holder.grid.abs.ng-scope')).click(); - } - browser.pause(); - - }); - -}); diff --git a/protractor/create/CreateClock.js b/protractor/create/CreateClock.js index c427d91a11..940db62af4 100644 --- a/protractor/create/CreateClock.js +++ b/protractor/create/CreateClock.js @@ -93,12 +93,11 @@ describe('Create Clock', function() { return posibilities.indexOf(expected) > -1; } }) - var current,current1,clock; rightClickClass.select(ITEM_MENU_GLYPH, true).click().then(function () { browser.sleep(1000); browser.executeScript(getTime, false).then(function(current){ browser.executeScript(getTime, true).then(function(current1) { - clock = element(by.css('.l-time-display.l-digital.l-clock.s-clock.ng-scope')); + var clock = element(by.css('.l-time-display.l-digital.l-clock.s-clock.ng-scope')); clock.getText().then(function (ele) { expect([current,current1]).toBeIn(ele); }) diff --git a/protractor/stressTest/StressTest.js b/protractor/stressTest/StressTest.js index 789736a9e3..108e431868 100644 --- a/protractor/stressTest/StressTest.js +++ b/protractor/stressTest/StressTest.js @@ -19,9 +19,9 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); +var itemCreate = require("../common/CreateItem"); +var itemEdit = require("../common/EditItem"); +var right_click = require("../common/RightMenu.js"); describe('Create Folder', function() { var clickClass = new right_click(); diff --git a/protractor/stressTest/StressTestBubble.js b/protractor/stressTest/StressTestBubble.js index 7cd4358bf1..b06b29c1b9 100644 --- a/protractor/stressTest/StressTestBubble.js +++ b/protractor/stressTest/StressTestBubble.js @@ -19,9 +19,9 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/StressTestBubble.jsStressTestBubble.js -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); +var itemCreate = require("../common/CreateItem"); +var itemEdit = require("../common/EditItem"); +var right_click = require("../common/RightMenu.js"); describe('Create Folder', function() { var clickClass = new right_click(); diff --git a/protractor/stressTest/StressTestCreateButton.js b/protractor/stressTest/StressTestCreateButton.js index 6fc2944df1..25debf3bba 100644 --- a/protractor/stressTest/StressTestCreateButton.js +++ b/protractor/stressTest/StressTestCreateButton.js @@ -19,9 +19,9 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); +var itemCreate = require("../common/CreateItem"); +var itemEdit = require("../common/EditItem"); +var right_click = require("../common/RightMenu.js"); describe('Create Folder', function() { var clickClass = new right_click(); diff --git a/protractor/stressTest/StressTestMenu.js b/protractor/stressTest/StressTestMenu.js index cc26e87d27..d6e30bc5b2 100644 --- a/protractor/stressTest/StressTestMenu.js +++ b/protractor/stressTest/StressTestMenu.js @@ -19,9 +19,9 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); +var itemCreate = require("../common/CreateItem"); +var itemEdit = require("../common/EditItem"); +var right_click = require("../common/RightMenu.js"); describe('Create Folder', function() { var clickClass = new right_click(); diff --git a/protractor/stressTest/StressTestNewPage.js b/protractor/stressTest/StressTestNewPage.js index 17f71607a9..2b0e82fbb1 100644 --- a/protractor/stressTest/StressTestNewPage.js +++ b/protractor/stressTest/StressTestNewPage.js @@ -19,10 +19,10 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); -var fullScreenFile = require("./common/FullScreen"); +var itemCreate = require("../common/CreateItem"); +var itemEdit = require("../common/EditItem"); +var right_click = require("../common/RightMenu.js"); +var fullScreenFile = require("../common/FullScreen"); describe('Create Folder', function() { var clickClass = new right_click(); diff --git a/protractor/stressTest/StressTestRightClick.js b/protractor/stressTest/StressTestRightClick.js index 35adb4a2b3..f16f876a90 100644 --- a/protractor/stressTest/StressTestRightClick.js +++ b/protractor/stressTest/StressTestRightClick.js @@ -19,9 +19,9 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -var itemCreate = require("./common/CreateItem"); -var itemEdit = require("./common/EditItem"); -var right_click = require("./common/RightMenu.js"); +var itemCreate = require("../common/CreateItem"); +var itemEdit = require("../common/EditItem"); +var right_click = require("../common/RightMenu.js"); describe('Create Folder', function() { var clickClass = new right_click(); From b74cbf196977d9e2837e5bbad87ca99bc2b886b2 Mon Sep 17 00:00:00 2001 From: Jesse Date: Tue, 11 Aug 2015 14:56:25 -0700 Subject: [PATCH 36/40] Added Window/Unix Freindly String Compare functions --- protractor/README | 30 ++++++++++++++++++------------ protractor/bin/stop.js | 31 +++++++++++++++++++------------ protractor/package.json | 12 ++++++------ 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/protractor/README b/protractor/README index 17c38e6fe3..5734e5702d 100644 --- a/protractor/README +++ b/protractor/README @@ -37,8 +37,17 @@ E2e Protractor Tests. -Contains tests that test the UI(drag drop, fullscreen, info bubble) -conf.js: -protractor config file. Explained below - + -stressTest: + Tests that are used to test for memory leaks. You can use the new tab option on WARP and then open the + timeline in the new tab during the browser.sleep(). Once the test is do the browser will pause and you + can look a the timeline results in the new tab. + NOTE: Cannot open chrome dev tools on same tab as the test are run on. Protractor uses the dev tools to + exectute the tests. + + -StressTest will create and delete folders. + -StressTestBubble.js: creates manny bubbles. + (Delay variable in InfoGesture.js was changed to 0) 3. Conf.js Conf.js is used by protractor to setup and execute the tests. -allScriptsTimeout: gives more time for protractor to synchronize with the page. @@ -50,14 +59,11 @@ E2e Protractor Tests. -specs[]: Is an array of files. Each File should have a "describe, it" test to be executed by protractor. -capabilities: Tells protractor what browser to use and any browser arguments. -4. StressTest: - Tests that are used to test for memory leaks. You can use the new tab option on WARP and then open the - timeline in the new tab during the browser.sleep(). Once the test is do the browser will pause and you can - look a the timeline results in the new tab. - NOTE: Cannot open chrome dev tools on same tab as the test are run on. Protractor uses the dev tools to - exectute the tests. - - -StressTest will create and delete folders. - -StressTestBubble.js: creates manny bubbles. - (Delay variable in InfoGesture.js was changed to 0) - \ No newline at end of file +4. bundle.json + bundle.json is used by npm to determine dependencies and location of script files. + -Dependencies: + "protractor": Contains protractor and webdriver package. + "psnode": Window/Unix Command, used for list/kill process.(ps aux) + "shelljs": Window/Unix Common JS Commands. eg rm,ls,exec + "sleep": Window/Unix Commands used to sleep the script + "string": Window/Unix Commands for string manipulation. \ No newline at end of file diff --git a/protractor/bin/stop.js b/protractor/bin/stop.js index d47e366348..ac2c3b4295 100755 --- a/protractor/bin/stop.js +++ b/protractor/bin/stop.js @@ -10,25 +10,32 @@ ps.list(function(err, results) { results.forEach(function( process ){ //Killing Node - if((process.command.indexOf("node app.js")) != -1) { + if(S(process.command).contains("node app.js")) { console.log(); console.log( 'Killing Node: %s', process.command); ps.kill(process.pid, function(err, stdout) { - if (err) { - throw new Error(err); - } - console.log(stdout); + if (err) { + throw new Error(err); + } + console.log(stdout); }); - } - sleep.usleep(10000); - if((process.command.indexOf("webdriver")) != -1) { + }else if(S(process.command).contains("webdriver")) { console.log(); console.log( 'Killing WebDriver: %s', process.command); ps.kill(process.pid, function(err, stdout) { - if (err){ - throw new Error(err); - } - console.log(stdout); + if (err){ + throw new Error(err); + } + console.log(stdout); + }); + }else if(S(process.command).contains("protractor")) { + console.log(); + console.log( 'Killing Chrome Drive: %s', process.command); + ps.kill(process.pid, function(err, stdout) { + if (err){ + throw new Error(err); + } + console.log(stdout); }); } }); diff --git a/protractor/package.json b/protractor/package.json index 015a75e321..b43b9b1cdb 100644 --- a/protractor/package.json +++ b/protractor/package.json @@ -1,12 +1,12 @@ { - "name": "protractorCtr", + "name": "ProtractorLauncher", "version": "1.0.0", "scripts" : { - "start": "bin/start.js", - "run" : "bin/run.js", - "stop" : "bin/stop.js", - "all" : "bin/start.js; bin/run.js; bin/stop.js;", - "clean": "bin/clean.js" + "start" : "bin/start.js", + "protractor" : "bin/run.js", + "stop" : "bin/stop.js", + "all" : "bin/start.js; bin/run.js; bin/stop.js;", + "clean" : "bin/clean.js" }, "dependencies": { "protractor": "^2.1.0", From 7aea1647a28b97a36f9a6278f04dad418dfac516 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 12 Aug 2015 09:58:20 -0700 Subject: [PATCH 37/40] [Tests] Ensure local storage is used Ensure local storage is used for Protractor tests, WTD-1505. --- protractor/bin/start.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protractor/bin/start.js b/protractor/bin/start.js index e902b79b51..21aacc7efe 100755 --- a/protractor/bin/start.js +++ b/protractor/bin/start.js @@ -24,7 +24,7 @@ console.log('Installing Dependencies'); exec("npm install minimist express", {async:false}); console.log('Starting Node'); sleep.sleep(1); -exec("node app.js -p 1984 -i example/localstorage > protractor/logs/nodeApp.log 2>&1 &", {async:false}); +exec("node app.js -p 1984 -x example/persistence -x platform/persistence/elastic -i example/localstorage > protractor/logs/nodeApp.log 2>&1 &", {async:false}); console.log(' Started Node'); console.log(); @@ -37,4 +37,4 @@ if(error() == null){ console.log(" Error : ", error()); } sleep.sleep(1); -cd(startdir); \ No newline at end of file +cd(startdir); From b6b716b7673d061c57011765ac49dd6b242f707f Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 12 Aug 2015 10:27:24 -0700 Subject: [PATCH 38/40] [Tests] Update protractor instructions WTD-1505 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c36cbea653..42cd060282 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ as described above. An example of this is expressed in `platform/framework`, which follows bundle conventions. -### Regression Testing +### Functional Testing The tests described above are all at the unit-level; an additional test suite using [Protractor](https://angular.github.io/protractor/) @@ -76,9 +76,9 @@ us under development, in the `protractor` folder. To run: * Install protractor following the instructions above. -* `webdriver-manager start` -* `node app.js -p 1984 -x platform/persistence/elastic -i example/persistence -* `protractor protractor/conf.js` +* `cd protractor` +* `npm install` +* `npm run all` ## Build From deb9e3e2ee86dc63e546978c036379937c141e71 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 12 Aug 2015 10:28:20 -0700 Subject: [PATCH 39/40] [Tests] Change Chrome binary env variable Use CHROME_BIN as the environment variable for nonstandard Google Chrome binary locations; this is the same variable used by Karma, so configuration is simplified. WTD-1505. --- protractor/conf.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protractor/conf.js b/protractor/conf.js index 493c196c46..c3c1847228 100644 --- a/protractor/conf.js +++ b/protractor/conf.js @@ -61,7 +61,7 @@ exports.config = { // Allow specifying binary location as an environment variable, // for cases where Chrome is not installed in a usual location. -if (process.env.PROTRACTOR_CHROME_BINARY) { +if (process.env.CHROME_BIN) { exports.config.capabilities.chromeOptions.binary = - process.env.PROTRACTOR_CHROME_BINARY; + process.env.CHROME_BIN; } From 914c823675ea983947a6be6158ec48f3f4c164ef Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 12 Aug 2015 11:57:56 -0700 Subject: [PATCH 40/40] [Tests] Comment out failing tests Comment out tests which relate to object types not yet in open source, WTD-1505 --- protractor/conf.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/protractor/conf.js b/protractor/conf.js index c3c1847228..8b828fcbd7 100644 --- a/protractor/conf.js +++ b/protractor/conf.js @@ -28,30 +28,30 @@ exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', //specs: ['StressTestCarrot.js'], specs: [ - 'create/CreateActivity.js', - 'delete/DeleteActivity.js', - 'create/CreateActivityMode.js', - 'delete/DeleteActivityMode.js', - 'create/CreateClock.js', - 'delete/DeleteClock.js', + // 'create/CreateActivity.js', + // 'delete/DeleteActivity.js', + // 'create/CreateActivityMode.js', + // 'delete/DeleteActivityMode.js', + // 'create/CreateClock.js', + // 'delete/DeleteClock.js', 'create/CreateDisplay.js', 'delete/DeleteDisplay.js', 'create/CreateFolder.js', 'delete/DeleteFolder.js', - 'create/CreateTelemetry.js', - 'delete/DeleteTelemetry.js', - 'create/CreateTimeline.js', - 'delete/DeleteTimeline.js', - 'create/CreateTimer.js', - 'delete/DeleteTimer.js', + // 'create/CreateTelemetry.js', + // 'delete/DeleteTelemetry.js', + // 'create/CreateTimeline.js', + // 'delete/DeleteTimeline.js', + // 'create/CreateTimer.js', + // 'delete/DeleteTimer.js', 'create/CreateWebPage.js', 'delete/DeleteWebPage.js', 'UI/Fullscreen.js', 'create/CreateButton.js', - "UI/DragDrop.js", - "UI/NewWindow.js", - 'UI/InfoBubble.js', - 'UI/RightClick.js' + //"UI/DragDrop.js", + "UI/NewWindow.js" + //'UI/InfoBubble.js', + //'UI/RightClick.js' ], capabilities: { 'browserName': 'chrome', // or 'safari'