Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
[JENKINS-35847] Refactor gitCommit to return a promise. Add tests for…
… notSet, condensed and notCondensed for a.authors
  • Loading branch information
scherler committed Aug 31, 2016
1 parent c244fdb commit d8528c2
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 84 deletions.
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -33,6 +33,7 @@
"nodegit": "^0.13.2"
},
"dependencies": {
"async": "^2.0.1"
"async": "^2.0.1",
"faker": "^3.1.0"
}
}
80 changes: 44 additions & 36 deletions src/main/js/api/git.js
@@ -1,6 +1,7 @@
var NodeGit = require("nodegit");
var fse = require('fs-extra');
var path = require("path");
var faker = require('faker');

exports.init = function (pathToRepo, onInit) {
var pathToRepo = path.resolve(pathToRepo);
Expand Down Expand Up @@ -111,42 +112,49 @@ exports.createBranch = function (branchName, pathToRepo) {

exports.createCommit = function (pathToRepo, files) {

const signatureAuthor = NodeGit.Signature.now('Iron Thor', 'ironThor@avengers.com');
var repo, index, oid, remote;

return NodeGit.Repository.open(pathToRepo)
.then(function (repoResult) {
repo = repoResult;
return repo.refreshIndex();
})
.then(function (indexResult) {
index = indexResult;
// this file is in the root of the directory and doesn't need a full path
return files.map(function (fileName) {
console.log('++++Adding file +++', fileName);
index.addByPath(fileName);
return new Promise(function (resolve, reject) {
const message = faker.lorem.sentence();
const signatureAuthor = NodeGit.Signature.now(faker.name.findName(), faker.internet.email());
const committerAuthor = NodeGit.Signature.now(faker.name.findName(), faker.internet.email());
var repo, index, oid, remote;
NodeGit.Repository.open(pathToRepo)
.then(function (repoResult) {
repo = repoResult;
return repo.refreshIndex();
})
})
.then(function() {
// this will write files to the index
return index.write();
})
.then(function() {
return index.writeTree();
})
.then(function (oidResult) {
oid = oidResult;
return NodeGit.Reference.nameToId(repo, "HEAD");
})
.then(function (head) {
return repo.getCommit(head);
})
.then(function (parent) {
return repo.createCommit("HEAD", signatureAuthor, signatureAuthor, 'testing commit tab', oid, [parent]);
})
.done(function (commitId) {
console.log("New Commit: ", commitId);
return commitId;
});
.then(function (indexResult) {
index = indexResult;
// this file is in the root of the directory and doesn't need a full path
return files.map(function (fileName) {
console.log('++++Adding file +++', fileName);
index.addByPath(fileName);
})
})
.then(function() {
// this will write files to the index
return index.write();
})
.then(function() {
return index.writeTree();
})
.then(function (oidResult) {
oid = oidResult;
return NodeGit.Reference.nameToId(repo, "HEAD");
})
.then(function (head) {
return repo.getCommit(head);
})
.then(function (parent) {
return repo.createCommit("HEAD", signatureAuthor, committerAuthor, message, oid, [parent]);
})
.then(function (commitId) {
console.log("New Commit: ", commitId);
resolve(commitId);
})
.catch(function (err) {
reject(err);
})
;
});

};
83 changes: 58 additions & 25 deletions src/main/js/page_objects/blueocean/bluePipelineRunDetail.js
Expand Up @@ -19,34 +19,35 @@ module.exports = {
artifactTable: 'table.artifacts-table tr',
changes: 'table.changeset-table tr',
tests: 'div.new-failure-block div.result-item',
authors: 'a.authors',
}
};

// Nightwatch commands.
// http://nightwatchjs.org/guide#writing-commands
module.exports.commands = [{
forRun: function(jobName, orgName, branchName, buildNumber) {
forRun: function (jobName, orgName, branchName, buildNumber) {
this.jobName = jobName;
this.orgName = orgName;
this.multiBranchJob = (typeof branchName === 'string' ? branchName : jobName);
this.buildNumber = (typeof branchName === 'number' ? branchName : buildNumber);
return this.navigate(this.pageUrl());
},
pageUrl: function(relative) {
var runUrl = url.makeRelative(url.viewRunPipeline(this.orgName, this.jobName, this.multiBranchJob, this.buildNumber));
pageUrl: function (relative) {
var runUrl = url.makeRelative(url.viewRunPipeline(this.orgName, this.jobName, this.multiBranchJob, this.buildNumber));

return !relative ?
this.api.launchUrl + runUrl :
this.api.launchUrl + runUrl :
runUrl;
},
forNode: function(id) {
forNode: function (id) {
const baseUrl = this.pageUrl();
return this.navigate(baseUrl + '/pipeline/' + id);
},
tabUrl: function(tabName, relative) {
tabUrl: function (tabName, relative) {
return this.pageUrl(relative) + '/' + tabName;
},
assertBasicLayoutOkay: function() {
assertBasicLayoutOkay: function () {
this.waitForElementVisible(url.tabSelector('pipeline'));
this.waitForElementVisible(url.tabSelector('changes'));
this.waitForElementVisible(url.tabSelector('tests'));
Expand All @@ -62,10 +63,10 @@ module.exports.commands = [{
self.getText('@detailTitle', function (response) {
self.assert.equal(typeof response, "object");
self.assert.equal(response.status, 0);
const urlProect = (response.value);
self.assert.equal(urlProect.indexOf(expected)>-1, true);
return self;
const urlProject = (response.value);
self.assert.equal(urlProject.indexOf(expected) > -1, true);
})
return self;

},
closeModal: function (browser) {
Expand All @@ -75,15 +76,15 @@ module.exports.commands = [{
browser.url(function (response) {
self.assert.equal(typeof response, "object");
self.assert.equal(response.status, 0);
this.pause(10000)
// FIXME JENKINS-36619 -> somehow the close in AT is not working as it should
// I debugged a bit and found out that the "previous" location is the same as
// current, this is the reason, why no url change is triggered. The question remains
// why that is happening
// this.pause(10000)
return self;
})
},
clickTab: function(browser, tab) {
clickTab: function (browser, tab) {
var self = this;
return url.clickTab(browser, self, tab);
},
Expand All @@ -92,16 +93,16 @@ module.exports.commands = [{
self.waitForElementVisible('@fullLog');
self.click('@fullLog')
browser.url(function (response) {
self.assert.equal(typeof response, "object");
self.assert.equal(response.status, 0);
// is the "full log" link gone?
self.fullLogButtonNotPresent();
// is the progressbar visible and not the code?
self.validateLoading();
// did we changed the url on change?
self.assert.equal(response.value.includes('start=0'), true);
return self;
})
self.assert.equal(typeof response, "object");
self.assert.equal(response.status, 0);
// is the "full log" link gone?
self.fullLogButtonNotPresent();
// is the progressbar visible and not the code?
self.validateLoading();
// did we changed the url on change?
self.assert.equal(response.value.includes('start=0'), true);
return self;
})
},
fullLogButtonNotPresent: function () {
// is the "full log" link gone?
Expand Down Expand Up @@ -154,9 +155,13 @@ module.exports.commands = [{
validateNotEmptyChanges: function (browser, expectedCount) {
var self = this;
self.waitForElementVisible('@changes');
if (browser && expectedCount) {
if (browser) {
browser.elements('css selector', 'table.changeset-table tr', function (codeCollection) {
this.assert.equal(codeCollection.value.length, expectedCount + 1); // +1 because of the heading row
if (expectedCount) {
this.assert.equal(codeCollection.value.length, expectedCount + 1); // +1 because of the heading row
} else {
this.assert.equal(codeCollection.value.length > 1, true); // +1 because of the heading row
}
return self;
});
}
Expand All @@ -167,5 +172,33 @@ module.exports.commands = [{
self.waitForElementVisible('@tests');
return self;
},
authorsIsCondensed: function (browser) {
var self = this;
self.waitForElementVisible('@authors');
self.getText('@authors', function (response) {
self.assert.equal(typeof response, "object");
self.assert.equal(response.status, 0);
const hint = (response.value);
console.log(hint)
self.assert.equal(hint.indexOf('Changes by') > -1, false);
});
return self;
},
authorsIsNotCondensed: function (browser) {
var self = this;
self.waitForElementVisible('@authors');
self.getText('@authors', function (response) {
self.assert.equal(typeof response, "object");
self.assert.equal(response.status, 0);
const hint = (response.value);
self.assert.equal(hint.indexOf('Changes by') > -1, true);
});
return self;
},
authorsIsNotSet: function (browser) {
var self = this;
self.expect.element('@authors').to.not.be.present.before(1000);
return self;
}

}];
}];
118 changes: 96 additions & 22 deletions src/test/js/edgeCases/folder.js
Expand Up @@ -82,6 +82,8 @@ module.exports = {
// JENKINS-36613 Unable to load steps for multibranch pipelines with / in them
blueRunDetailPage.validateGraph();
blueRunDetailPage.validateSteps(browser);
// There should be no authors
blueRunDetailPage.authorsIsNotSet(browser);
},

'Check whether the artifacts tab shows artifacts': function (browser) {
Expand All @@ -97,34 +99,106 @@ module.exports = {
blueRunDetailPage.validateFailingTests();
},

'Check whether the changes tab shows changes': function (browser) {
async.series([
function(callback) {
// create new files and a commit
fse.writeFile(path.join(pathToRepo, '666.txt'), '666');
git.createCommit(pathToRepo, ['666.txt']);
callback(null, null);
},
function(callback) {
// now we have to index the branch
const masterJob = browser.page.jobUtils()
.forJob(getProjectName(anotherFolders), '/indexing');
// start a new build by starting indexing
masterJob.indexingStarted();
// test whether we have commit
const blueRunDetailPage = browser.page.bluePipelineRunDetail().forRun(projectName, 'jenkins', 'master', 2);
blueRunDetailPage.clickTab(browser, 'changes');
blueRunDetailPage.validateNotEmptyChanges(browser, 1);
callback(null, null);
}
]);
'Check whether the changes tab shows changes - one commit': function (browser) {
// magic number
const magic = 1;
// creating an array
const committs = Array.from(new Array(magic), function (x, i) {
return i;
});
var recordedCommits = 0;
// creating commits from that array with a mapSeries -> not parallel
async.mapSeries(committs, function (file, callback) {
const filename = file + '.txt';
// writeFile is async so we need to use callback
fse.writeFile(path.join(pathToRepo, filename), file, function (err) {
// when we get an error we call with error
if (err) {
callback(err);
}
// createCommit returns a promise just passing it alone
return git.createCommit(pathToRepo, [filename])
.then(function (commitId) {
// if we reached here we have a commit
console.log('commitId', commitId)
/* We are sure that all async functions have finished.
* Now we let async know about it by
* callback without error and the commitId
*/
callback(null, commitId);
})
});

}, function(err, results) {
// results is an array of names
recordedCommits = results.length;
console.log(results.length, 'commits recorded')
});
console.log('Now starting the indexing', recordedCommits)
// now we have to index the branch
const masterJob = browser.page.jobUtils()
.forJob(getProjectName(anotherFolders), '/indexing');
// start a new build by starting indexing
masterJob.indexingStarted();
// test whether we have commit
const blueRunDetailPage = browser.page.bluePipelineRunDetail().forRun(projectName, 'jenkins', 'master', 2);
blueRunDetailPage.clickTab(browser, 'changes');
blueRunDetailPage.validateNotEmptyChanges(browser);
blueRunDetailPage.authorsIsNotCondensed(browser);
},

'Check whether the changes tab shows changes - condensed': function (browser) {
// magic number
const magic = 15;
// creating an array
const committs = Array.from(new Array(magic), function (x, i) {
return i;
});
var recordedCommits = 0;
// creating commits from that array with a mapSeries -> not parallel
async.mapSeries(committs, function (file, callback) {
const filename = file + '.txt';
// writeFile is async so we need to use callback
fse.writeFile(path.join(pathToRepo, filename), file, function (err) {
// when we get an error we call with error
if (err) {
callback(err);
}
// createCommit returns a promise just passing it alone
return git.createCommit(pathToRepo, [filename])
.then(function (commitId) {
// if we reached here we have a commit
console.log('commitId', commitId)
/* We are sure that all async functions have finished.
* Now we let async know about it by
* callback without error and the commitId
*/
callback(null, commitId);
})
});

}, function(err, results) {
// results is an array of names
recordedCommits = results.length;
console.log(results.length, 'commits recorded')
});
console.log('Now starting the indexing', recordedCommits)
// now we have to index the branch
const masterJob = browser.page.jobUtils()
.forJob(getProjectName(anotherFolders), '/indexing');
// start a new build by starting indexing
masterJob.indexingStarted();
// test whether we have commit
const blueRunDetailPage = browser.page.bluePipelineRunDetail().forRun(projectName, 'jenkins', 'master', 3);
blueRunDetailPage.clickTab(browser, 'changes');
blueRunDetailPage.validateNotEmptyChanges(browser);
blueRunDetailPage.authorsIsCondensed(browser);
},

// JENKINS-36615 the multibranch project has the branch 'feature/1'
'Jobs can be started from branch tab. - RUN': function (browser) {
const blueActivityPage = browser.page.bluePipelineActivity().forJob(projectName, 'jenkins');
blueActivityPage.assertActivitiesToBeEqual(browser, 3);
blueActivityPage.assertActivitiesToBeEqual(browser, 4);
blueActivityPage.clickTab(browser, 'branches');
browser.page.bluePipelineBranch().clickRunButton(browser);
const blueRunDetailPage = browser.page.bluePipelineRunDetail().forRun(projectName, 'jenkins', 'feature%2F1', 2);
Expand Down

0 comments on commit d8528c2

Please sign in to comment.