From ee490fc6600f90abd9d324a5c7fd10a82ea98e89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Mon, 9 Feb 2015 19:01:59 +0100 Subject: [PATCH 1/4] Add the --deep-js-analysis option to CLI --- bin/cli.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bin/cli.js b/bin/cli.js index a9e3c5d..832112f 100644 --- a/bin/cli.js +++ b/bin/cli.js @@ -12,7 +12,8 @@ var cli = meow({ ' yellowlabtools ', '', 'Options:', - ' --screenshot Will take a screenshot and use this value as the output path. It needs to end with ".png".', + ' --screenshot Will take a screenshot and use this value as the output path. It needs to end with ".png".', + ' --js-deep-analysis When activated, the javascriptExecutionTree will contain sub-requests.', '' ].join('\n'), pkg: '../package.json' @@ -44,6 +45,10 @@ if (screenshot) { options.screenshot = cli.flags.screenshot; } +// Deep JS analysis option +if (cli.flags.jsDeepAnalysis === true || cli.flags.jsDeepAnalysis === 'true') { + options.jsDeepAnalysis = true; +} (function execute(url, options) { From 42c27af60491181f65193cf24860b346a6029963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Mon, 9 Feb 2015 19:03:04 +0100 Subject: [PATCH 2/4] No more javascriptExecutionTree bu default (option) --- lib/server/controllers/apiController.js | 15 +++++++++++++-- test/api/apiTest.js | 6 +++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/server/controllers/apiController.js b/lib/server/controllers/apiController.js index a74d359..3c0462c 100644 --- a/lib/server/controllers/apiController.js +++ b/lib/server/controllers/apiController.js @@ -32,7 +32,8 @@ var ApiController = function(app) { url: req.body.url, waitForResponse: req.body.waitForResponse !== false && req.body.waitForResponse !== 'false' && req.body.waitForResponse !== 0, partialResult: req.body.partialResult || null, - screenshot: req.body.screenshot || false + screenshot: req.body.screenshot || false, + jsTimeline: req.body.jsTimeline || false } }; @@ -64,7 +65,8 @@ var ApiController = function(app) { debug('Launching test %s on %s', run.runId, run.params.url); var runOptions = { - screenshot: run.params.screenshot ? screenshot.getTmpFilePath() : false + screenshot: run.params.screenshot ? screenshot.getTmpFilePath() : false, + jsDeepAnalysis: run.params.jsTimeline }; return ylt(run.params.url, runOptions); @@ -107,7 +109,16 @@ var ApiController = function(app) { // Save results .then(function() { + // Remove uneeded temp screenshot path delete data.params.options.screenshot; + + // Empty javascriptExecutionTree if not needed + if (!run.params.jsTimeline) { + data.javascriptExecutionTree = {}; + } + + // Remove tools results if not needed + return resultsDatastore.saveResult(data); }) diff --git a/test/api/apiTest.js b/test/api/apiTest.js index 4e960d2..74be9f3 100644 --- a/test/api/apiTest.js +++ b/test/api/apiTest.js @@ -159,7 +159,10 @@ describe('api', function() { body.should.have.a.property('scoreProfiles').that.is.an('object'); body.should.have.a.property('rules').that.is.an('object'); body.should.have.a.property('toolsResults').that.is.an('object'); + + // javascriptExecutionTree should only be filled if option jsTimeline is true body.should.have.a.property('javascriptExecutionTree').that.is.an('object'); + body.javascriptExecutionTree.should.deep.equal({}); // Check if the screenshot temporary file was correctly removed body.params.options.should.not.have.a.property('screenshot'); @@ -188,7 +191,8 @@ describe('api', function() { url: serverUrl + '/api/runs', body: { url: wwwUrl + '/simple-page.html', - waitForResponse: false + waitForResponse: false, + jsTimeline: true }, json: true, headers: { From 2d003febc1b8a3f243a77620aff49d78966288b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Mon, 9 Feb 2015 19:04:47 +0100 Subject: [PATCH 3/4] Front needs the jsTimeline by default --- front/src/js/services/apiService.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/front/src/js/services/apiService.js b/front/src/js/services/apiService.js index 27aaac9..28b4db1 100644 --- a/front/src/js/services/apiService.js +++ b/front/src/js/services/apiService.js @@ -8,7 +8,8 @@ apiService.factory('API', ['$location', 'Runs', 'Results', function($location, R Runs.save({ url: url, waitForResponse: false, - screenshot: true + screenshot: true, + jsTimeline: true }, function(data) { $location.path('/queue/' + data.runId); }, function(response) { From e9bb72a41663e21b49f49adac4b131ba15963556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 12 Feb 2015 17:28:41 +0100 Subject: [PATCH 4/4] Add sub-queries to the JS profiler table --- front/src/css/timeline.css | 40 +++++++++++++++ front/src/js/app.js | 1 + .../src/js/directives/jsChildrenDirective.js | 44 ++++++++++++++++ front/src/less/timeline.less | 50 +++++++++++++++++++ front/src/main.html | 1 + front/src/views/timeline.html | 5 +- 6 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 front/src/js/directives/jsChildrenDirective.js diff --git a/front/src/css/timeline.css b/front/src/css/timeline.css index 43304d1..53d22e9 100644 --- a/front/src/css/timeline.css +++ b/front/src/css/timeline.css @@ -177,6 +177,46 @@ input.textFilter { .table > div > .type { white-space: nowrap; } +.table .children { + margin-top: 0.2em; + font-size: 0.8em; + line-height: 1.6em; +} +.table .child { + margin-left: 0.5em; +} +.table .child > .child { + margin-left: 1em; +} +.table .child:before { + content: "↳"; +} +.table .child .childArgs { + display: none; +} +.table .child span { + position: relative; +} +.table .child span:hover { + background: #EBD8E2; +} +.table .child span:hover .childArgs { + display: block; + position: absolute; + padding: 0 1em 0 2em; + left: 100%; + top: 0; + background: #EBD8E2; + line-height: 1.3em; + height: 1.3em; + z-index: 1; +} +.table .showingDetails .child span:hover { + background: inherit; +} +.table .showingDetails .child span:hover .childArgs { + display: none; +} .table > div > .value { width: 70%; word-break: break-all; diff --git a/front/src/js/app.js b/front/src/js/app.js index 49e1125..923e474 100644 --- a/front/src/js/app.js +++ b/front/src/js/app.js @@ -12,6 +12,7 @@ var yltApp = angular.module('YellowLabTools', [ 'apiService', 'menuService', 'gradeDirective', + 'jsChildrenDirective', 'offendersDirectives' ]); diff --git a/front/src/js/directives/jsChildrenDirective.js b/front/src/js/directives/jsChildrenDirective.js new file mode 100644 index 0000000..ca7372f --- /dev/null +++ b/front/src/js/directives/jsChildrenDirective.js @@ -0,0 +1,44 @@ +var jsChildrenDirective = angular.module('jsChildrenDirective', []); + +jsChildrenDirective.directive('jsChildren', function() { + + return { + restrict: 'E', + scope: { + node: '=node' + }, + template: '
', + replace: true, + link: function(scope, element, attrs) { + + function recursiveHtmlBuilder(node) { + var html = ''; + + if (node.children) { + node.children.forEach(function(child) { + + var childArgs = ''; + if (child.data.callDetails && child.data.callDetails.arguments && child.data.callDetails.arguments.length > 0) { + childArgs = child.data.callDetails.arguments.join(' : '); + if (childArgs.length > 100) { + childArgs = childArgs.substr(0, 98) + '...'; + } + } + + html += '
' + child.data.type + '
' + childArgs + '
' + recursiveHtmlBuilder(child) + '
'; + }); + } + + return html; + } + + element.append(recursiveHtmlBuilder(scope.node)); + + // Bind a very special behavior: + // We want to display something in the next table-cell, at the same hight. + element.find('span').on('mouseenter', function() { + + }); + } + }; +}); \ No newline at end of file diff --git a/front/src/less/timeline.less b/front/src/less/timeline.less index 3c7a541..1f189fc 100644 --- a/front/src/less/timeline.less +++ b/front/src/less/timeline.less @@ -197,6 +197,56 @@ input.textFilter { white-space:nowrap; } +.table .children { + margin-top: 0.2em; + font-size: 0.8em; + line-height: 1.6em; +} + +.table .child { + margin-left: 0.5em; + + > .child { + margin-left: 1em; + } + + &:before { + content: "↳"; + } + + .childArgs { + display: none; + } + + span { + position: relative; + } + + span:hover { + background: #EBD8E2; + + .childArgs { + display: block; + position: absolute; + padding: 0 1em 0 2em; + left: 100%; + top: 0; + background: #EBD8E2; + line-height: 1.3em; + height: 1.3em; + z-index: 1; + } + } +} + +.table .showingDetails .child span:hover { + background: inherit; + + .childArgs { + display: none; + } +} + .table > div > .value { width: 70%; word-break: break-all; diff --git a/front/src/main.html b/front/src/main.html index 1146a0b..083d943 100644 --- a/front/src/main.html +++ b/front/src/main.html @@ -35,6 +35,7 @@ + diff --git a/front/src/views/timeline.html b/front/src/views/timeline.html index 71210ab..33bbedd 100644 --- a/front/src/views/timeline.html +++ b/front/src/views/timeline.html @@ -78,7 +78,10 @@ }">
{{$index + 1}}
-
{{node.data.type}}
+
+ {{node.data.type}} + +
{{node.data.callDetails.arguments[0]}}