Skip to content

Instantly share code, notes, and snippets.

@gregory-seidman
Created April 29, 2019 04:00
Show Gist options
  • Save gregory-seidman/9c8f3f7ba418a8b26c5d6c7d0a14cb5a to your computer and use it in GitHub Desktop.
Save gregory-seidman/9c8f3f7ba418a8b26c5d6c7d0a14cb5a to your computer and use it in GitHub Desktop.
GreaseMonkey script to add a button to clone a test plan in Azure DevOps
// ==UserScript==
// @name CloneTestPlan
// @description Azure DevOps Clone Test Plan Button
// @match https://dev.azure.com/*/*/_testManagement?planId=*
// @version 1.0
// @run-at document-end
// @grant unsafeWindow
// ==/UserScript==
function cloneTestPlan() {
const { XMLHttpRequest, console, decodeURIComponent, document, location } = unsafeWindow;
const urlFrags = ("" + location).split('/').slice(0, 5);
const baseUrl = urlFrags.join('/');
const apiUrl = urlFrags.concat([ "_apis/testplan/Plans/CloneOperation?deepClone=true&api-version=5.1-preview.2" ]).join('/');
const breadCrumbs = document.querySelectorAll('.vss-Breadcrumb li .vss-Breadcrumb--itemText');
const name = breadCrumbs && breadCrumbs.length && breadCrumbs[breadCrumbs.length-1].innerText;
const args = (location.search.length <= 1) ? {} :
location.search.substring(1).split('&').reduce((a, p) => {
let halves = p.split('=');
a[decodeURIComponent(halves[0])] = decodeURIComponent(halves[1]);
return a;
}, {});
const body = {
cloneOptions: {
copyAllSuites: true,
copyAncestorHierarchy: true
},
destinationTestPlan: {
name: "Clone of " + name
},
sourceTestPlan: {
id: args.planId
}
};
//console.log("#####################", apiUrl, body);
var xhr = new XMLHttpRequest();
xhr.open("POST", apiUrl, true);
xhr.setRequestHeader('Content-type', 'application/json; charset=UTF-8');
//xhr.onreadystatechange = console.log;
xhr.send(JSON.stringify(body));
}
window.setTimeout(function(win) {
const doc = win.document;
const parent = doc.querySelector('.vss-HubHeader');
const button = doc.createElement("button");
button.innerText = "Clone";
parent.insertBefore(button, parent.firstChild);
button.addEventListener("click", cloneTestPlan);
}, 3000, window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment