aboutsummaryrefslogtreecommitdiffstats
path: root/tipboard/extras/jira-ds.js
diff options
context:
space:
mode:
Diffstat (limited to 'tipboard/extras/jira-ds.js')
-rw-r--r--tipboard/extras/jira-ds.js191
1 files changed, 191 insertions, 0 deletions
diff --git a/tipboard/extras/jira-ds.js b/tipboard/extras/jira-ds.js
new file mode 100644
index 0000000..f7ab479
--- /dev/null
+++ b/tipboard/extras/jira-ds.js
@@ -0,0 +1,191 @@
+// If you want to use this script directly (i.e. without jira-ds.py), you can
+// do it like this (remember to fill 'username' & 'password' in casper.start):
+//
+// casperjs jira-ds.js \
+// (--project-key=P_KEY | --project-id=P_ID | --board-id=B_ID) --step=STEP
+
+var utils = require('utils');
+var casper = require('casper').create({
+ verbose: false,
+ logLevel: 'info',
+ pageSettings: {
+ loadImages: false,
+ loadPlugins: false,
+ },
+ timeout: 10000, // in milliseconds
+ onTimeout: function () {
+ this.echo('Timeout of 10 seconds has been reached');
+ this.exit(1);
+ },
+});
+
+// Uncomment if you need some additional diagnostic info.
+// casper.on('remote.message', function (msg) {
+// this.echo('=== Remote message caught: ' + msg);
+// });
+// casper.on("page.error", function (msg, trace) {
+// this.echo("=== Page error: " + msg, "ERROR");
+// });
+
+// available steps: 'control-chart', 'summary', 'cvsr','velocity', 'issues-counts'
+var step = casper.cli.options.step;
+var project_key = casper.cli.options['project-key'];
+var project_id = casper.cli.options['project-id'];
+var board_id = casper.cli.options['board-id'];
+
+var url_jira_login = ''; // needs to be filled in
+var url_jira = ''; // needs to be filled in
+var url_board = url_jira + '/secure/RapidBoard.jspa?rapidView=' + board_id;
+var url_control = url_board + '&view=reporting&chart=controlChart&days=30';
+var url_cumulative = url_jira + '/secure/ConfigureReport.jspa' +
+ '?projectOrFilterId=project-' + project_id +
+ '&periodName=daily&daysprevious=30&cumulative=true&versionLabels=major' +
+ '&selectedProjectId=' + project_id + '&reportKey=' +
+ 'com.atlassian.jira.plugin.system.reports:createdvsresolved-report' +
+ '&Next=Next';
+var url_velocity = url_board + '&view=reporting&chart=velocityChart';
+var url_summary = url_jira + '/browse/' + project_key;
+var url_issues = url_summary + '?selectedTab=' +
+ 'com.atlassian.jira.plugin.system.project%3Aissues-panel';
+
+casper.start(url_jira_login, function login() {
+ "use strict";
+ var form_selector = '#login-form',
+ credentials = {};
+ (function () {
+ var system = require('system');
+ credentials.user = system.env.JIRA_USER;
+ credentials.password = system.env.JIRA_PASSWORD;
+ }());
+ this.fill(form_selector, {
+ // 'os_username' and 'os_password' - names of the fields in login form
+ 'os_username': credentials.user,
+ 'os_password': credentials.password
+ }, true);
+});
+
+casper.thenBypassUnless(step === 'control-chart', 2);
+casper.thenOpen(url_control, function control_chart() {
+ "use strict";
+
+ var selector_data = '#ghx-chart-snapshot dt',
+ selector_timeframe = '#ghx-chart-selector .js-chart-time-window',
+ data = {};
+ data = this.evaluate(function (selector_data, selector_timeframe) {
+ var elems = document.querySelectorAll(selector_data),
+ data = {},
+ idxs = ['mean', 'median', 'min-time', 'max-time', 'issue-count'];
+ for (i = 0; i < idxs.length; i += 1) {
+ data[idxs[i]] = elems[i].textContent;
+ };
+ data.timeframe = document.querySelector(selector_timeframe).textContent;
+ return data;
+ }, selector_data, selector_timeframe);
+ utils.dump(data);
+});
+
+casper.thenBypassUnless(step === 'summary', 2);
+casper.thenOpen(url_summary, function summary() {
+ "use strict";
+ var selector_created = '#fragcreatedvsresolved span.created-issue-count',
+ selector_resolved = '#fragcreatedvsresolved span.resolved-issue-count',
+ data = {};
+ data = this.evaluate(function (selector_created, selector_resolved) {
+ var issues_created, issues_resolved, data = {};
+ issues_created = document.querySelector(selector_created).textContent;
+ issues_resolved = document.querySelector(selector_resolved).textContent;
+ data = {
+ 'issues_created': issues_created,
+ 'issues_resolved': issues_resolved,
+ };
+ return data;
+ }, selector_created, selector_resolved);
+ utils.dump(data);
+});
+
+casper.thenBypassUnless(step === 'cvsr', 2);
+casper.thenOpen(url_cumulative, function cvsr() {
+ "use strict";
+ var selector = '#createdvsresolved-report-datatable > tbody > tr',
+ data = {};
+ data = this.evaluate(function (selector) {
+ var i, rows, data = {};
+ rows = document.querySelectorAll(selector);
+ for (i = 1; i < rows.length; i += 1) {
+ data[rows[i].cells[0].textContent] = {
+ 'created': parseInt(rows[i].cells[1].textContent, 10),
+ 'resolved': parseInt(rows[i].cells[2].textContent, 10),
+ };
+ }
+ return data;
+ }, selector);
+ utils.dump(data);
+});
+
+casper.thenBypassUnless(step === 'velocity', 2);
+casper.thenOpen(url_velocity, function velocity() {
+ "use strict";
+ var selector = '#ghx-chart-data > table > tbody tr',
+ data = {};
+ data = this.evaluate(function (selector) {
+ var i, rows = {}, data = {};
+ rows = document.querySelectorAll(selector);
+ for (i = 0; i < rows.length; i += 1) {
+ data[rows[i].cells[0].textContent] = {
+ 'commitment': parseInt(rows[i].cells[1].textContent, 10),
+ 'completed': parseInt(rows[i].cells[2].textContent, 10),
+ };
+ }
+ return data;
+ }, selector);
+ utils.dump(data);
+});
+
+casper.thenBypassUnless(step === 'issues-counts', 2);
+casper.thenOpen(url_issues, function issues_counts() {
+ // function that we gonna use in a loop to retrieve data from selectors
+ "use strict";
+ function get_data(selector) {
+ var data = {};
+ data = this.evaluate(function (selector) {
+ var i, idx, rows = {}, data = {};
+ rows = document.querySelectorAll(selector);
+ // pack tr cells contents into more convenient structures
+ for (i = 0; i < rows.length; i += 1) {
+ idx = rows[i].cells[0].textContent.trim();
+ if (rows[i].cells.length === 3) {
+ data[idx] = [
+ parseInt(rows[i].cells[1].textContent, 10),
+ rows[i].cells[2].textContent.trim(),
+ ];
+ } else {
+ data[idx] = parseInt(rows[i].cells[1].textContent, 10);
+ }
+ }
+ return data;
+ }, selector);
+ return data;
+ }
+ var i, issues = {}, selectors = [
+ ['by_priority', '#fragunresolvedissuesbypriority div.mod-content table.aui > tbody > tr'],
+ ['status_summary', '#fragstatussummary div.mod-content table.aui > tbody > tr'],
+ ['by_issuetype', '#fragunresolvedissuesbyissuetype div.mod-content table.aui > tbody > tr'],
+ ['by_assignee', '#fragunresolvedissuesbyassignee div.mod-content table.aui > tbody > tr'],
+ ['by_component', '#fragunresolvedissuesbycomponent div.mod-content table.aui > tbody > tr'],
+ //['by_version', '#fragunresolvedissuesbyfixversion div.mod-content table.aui > tbody > tr'], // doesn't work (yet)
+ ];
+ for (i = 0; i < selectors.length; i += 1) {
+ issues[selectors[i][0]] = get_data.call(this, selectors[i][1]);
+ }
+ utils.dump(issues);
+});
+
+// Prints all defined steps (useful for diagnostics). Please notice that
+// both 'casper.thenOpen' and 'casper.start' contain 'casper.open', hence
+// every on of these counts as two steps.
+// Also, every 'casper.thenBypass' (and friends) counts as a separate step.
+// utils.dump(casper.steps.map(function (step) {
+// return step.toString();
+// }));
+
+casper.run();