Skip to content

Instantly share code, notes, and snippets.

@gibizer
Last active November 30, 2020 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gibizer/717e0cb5b0da0d60d5ecf1e18c0c171a to your computer and use it in GitHub Desktop.
Save gibizer/717e0cb5b0da0d60d5ecf1e18c0c171a to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name opendev gerrit CI table
// @namespace http://tampermonkey.net/
// @version 0.3
// @description
// @author gibi
// @match https://review.opendev.org/c/*
// @grant none
// ==/UserScript==
const get_place_to_insert_ci_table = function(){
var gr_app = document.getElementsByTagName('gr-app')[0];
var gr_app_element = gr_app.shadowRoot.querySelector(
'gr-app-element');
var gr_change_view = gr_app_element.shadowRoot.querySelector(
'gr-change-view');
var gr_related_changes_list = gr_change_view.shadowRoot.querySelector(
'gr-related-changes-list');
// if there are no related changes then this node is hidden, but we
// need to make it visible so that the CI table become visible
gr_related_changes_list.removeAttribute('hidden');
gr_related_changes_list.removeAttribute('class');
var gr_endpoint_decorator = gr_related_changes_list.shadowRoot.querySelector(
'gr-endpoint-decorator');
return gr_endpoint_decorator;
}
const get_ci_table = function(zuul_message){
var lines = zuul_message.split('- ');
var table = document.createElement('table');
// table header
var tr = document.createElement('tr');
var td = document.createElement('td');
var result = lines[0].split('.')[0];
td.appendChild(document.createTextNode(result));
if (result.includes('succ')){
td.style.color = 'green';
}
if (result.includes('fail')){
td.style.color = 'red';
}
tr.appendChild(td);
tr.appendChild(document.createElement('td'));
table.appendChild(tr);
for (var i=1; i<lines.length; i++){
var fields = lines[i].split(': ');
var job_name = fields[0].split(' ')[0];
var job_link = fields[0].split(' ')[1];
var job_result = fields[1];
tr = document.createElement('tr');
var td1 = document.createElement('td');
var link_text = document.createTextNode(job_name);
var a = document.createElement('a')
a.href = job_link;
a.title = job_name;
a.appendChild(link_text);
td1.appendChild(a);
tr.appendChild(td1);
var td2 = document.createElement('td');
a = document.createElement('a')
a.href = job_link;
a.title = job_name;
link_text = document.createTextNode(job_result);
a.appendChild(link_text);
td2.appendChild(a);
if (job_result.includes('SUCCESS')){
a.style.color = 'green';
}
if (job_result.includes('FAILURE')){
a.style.color = 'red';
}
if (job_result.includes('POST_FAILURE')){
a.style.color = 'orange';
}
if (job_result.includes('TIMED_OUT')){
a.style.color = 'red';
}
tr.appendChild(td2);
table.appendChild(tr);
}
return table;
}
const get_message_author = function(gr_message){
var gr_account_label = gr_message.shadowRoot.querySelector('gr-account-label');
var spans = gr_account_label.shadowRoot.querySelectorAll('span');
for (var i=0; i < spans.length; i++){
if (spans[i].className == 'name'){
return spans[i].innerText;
}
}
return null;
}
const get_message_text = function(gr_message){
if (gr_message==null || gr_message.shadowRoot===undefined){
return null;
}
var divs = gr_message.shadowRoot.querySelectorAll('div');
for (var i=0; i<divs.length; i++){
if (divs[i].className=='message hideOnOpen'){
return divs[i].innerText;
}
}
return null;
}
const get_last_zuul_message = function(){
var gr_app = document.getElementsByTagName('gr-app')[0];
var gr_app_element = gr_app.shadowRoot.querySelector('gr-app-element');
var gr_change_view = gr_app_element.shadowRoot.querySelector('gr-change-view');
var gr_messages_list = gr_change_view.shadowRoot.querySelector('gr-messages-list');
var gr_messages = gr_messages_list.shadowRoot.querySelectorAll('gr-message');
var last_zuul_message = null;
for (var i=0, max=gr_messages.length; i < max; i++) {
var author = get_message_author(gr_messages[i]);
var message_text = get_message_text(gr_messages[i]);
if (author == 'Zuul'){
if (message_text!=null
// ignore some zuul messages
&& message_text.startsWith('Build')
&& !message_text.includes('promote pipeline')){
last_zuul_message = message_text;
}
}
}
return last_zuul_message;
};
var ci_table = null;
const inject_CI_table = function(){
console.log('Injecting CI table...');
var place_to_insert = get_place_to_insert_ci_table();
var zuul_message = get_last_zuul_message();
console.log('Last Zuul CI message: ' + zuul_message);
if (zuul_message == null){
console.log('No Zuul test result comment found.');
return;
}
if (ci_table != null){
console.log('Remove stale CI table');
ci_table.remove();
}
ci_table = get_ci_table(zuul_message);
place_to_insert.appendChild(ci_table);
console.log('CI table injected');
};
const add_performance_observer = function() {
// try to detect when all the data is loaded for the page
const observer = new PerformanceObserver((list, obj) => {
for (let entry of list.getEntries()) {
console.log('!!!! observed' + entry.initiatorType + '|' + entry.name);
if(entry.initiatorType === "fetch"
&& entry.name.includes('submitted_together?')){
console.log('Last REST fetch (submitted_together) ran, inject CI table in 1 second');
// wait a second and then inject the CI table
setTimeout(function(){inject_CI_table();}, 1000);
observer.disconnect();
return;
}
}
});
observer.observe({
type: "resource",
// without buffered: true, page on background tab does not trigger the fetch event.
buffered: true,
});
};
const subscribe_to_navigation_event = function(){
const config = { childList: true, subtree: true };
var href = document.location.href;
const main_page_regexp = RegExp('review.opendev.org/c/.*/./[0-9]+(/[0-9]+/)?$');
var c = function(mutationsList, observer) {
for(const mutation of mutationsList) {
if (mutation.type === 'childList' && href != document.location.href) {
href = document.location.href;
if (main_page_regexp.test(href)){
add_performance_observer();
}
}
}
};
const observer = new MutationObserver(c);
observer.observe(document.querySelector('body'), config);
};
(function() {
'use strict';
console.log('User script triggered');
add_performance_observer();
subscribe_to_navigation_event();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment