Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X ray #797

Merged
merged 76 commits into from
Dec 3, 2024
Merged

X ray #797

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
3afd191
Extend JIRA integration to fetch tests and their steps; steps are dis…
bessaYo Jan 27, 2024
d19792a
Add css to show line breaks in storydescription
bessaYo Jan 31, 2024
b546fa6
Removed data field from description
bessaYo Feb 2, 2024
c88ee7b
Implented logic to update steps in XRay. Still hardcoded
bessaYo Feb 27, 2024
f55399d
download directory os related
jonycoo Jan 23, 2024
ac0d62a
increase version number, adjust order of steps, remove unnecessary slide
adessoCucumber Feb 2, 2024
e00481d
Bug is fixed
nkarmazina Jan 31, 2024
c984d36
Special-Commands (#526)
i3rotlher Feb 12, 2024
8156485
Bug fixed (#528)
nkarmazina Feb 23, 2024
75f929d
npm update
i3rotlher Feb 27, 2024
9747ae0
chromedriver download link
i3rotlher Feb 27, 2024
7ca8384
refactor functionality for xray extraction. Modified scenario merging…
bessaYo Mar 5, 2024
ea4fecd
xray data not hard coded anymore
bessaYo Mar 5, 2024
9b394fb
Merge branch 'xRay' of https://github.com/adessoSE/Seed-Test into xRay
bessaYo Mar 5, 2024
eaf03df
reimplent logic, each scenario has a list of test exeuction steps now
bessaYo Mar 6, 2024
e19c7b0
works with story run
bessaYo Mar 7, 2024
44e8306
manage db merging with new xray steps/test runs
bessaYo Mar 7, 2024
92692c1
fix description
bessaYo Mar 11, 2024
142440e
fix variable name
bessaYo Mar 15, 2024
95bbc69
parallel processing jira story fetch, to improve performance.
jonycoo Apr 4, 2024
7efa88f
fetch xray data outside of loop, increased performance
bessaYo Apr 4, 2024
47c8d2d
add reportComment option to global settings menu & integrate backend
jonycoo Feb 6, 2024
cdc30da
add global config for IssueTracker
jonycoo Apr 8, 2024
ea52b81
Merge branch 'IssueTrackerReportComment' into CUC-570_ProjectSettings…
jonycoo Apr 9, 2024
66711d3
remove owner search, not needed
jonycoo Apr 11, 2024
0a8f8ba
remove logs
jonycoo Apr 11, 2024
f013843
correct value in checkbox reportComment
jonycoo Apr 11, 2024
ca7d5f0
fix step matching, add xray indicator field to scenarios
bessaYo Apr 11, 2024
069b7b9
implemented logic to delete xray steps in jira
bessaYo Apr 11, 2024
e4022d0
Add test execution modal for xray
bessaYo Apr 18, 2024
5a1740e
Merge 570 Project Settings
bessaYo Apr 18, 2024
f6b02b3
Implemented logic to execute selected test executions, works for sing…
bessaYo Apr 18, 2024
87aa61c
Implemented logic for executions list modal and run story
bessaYo Apr 19, 2024
fd7eb19
select all toggle for execution list
bessaYo Apr 22, 2024
2604f80
darkTheme
nkarmazina Apr 22, 2024
3b51700
group creation for xray test sets
bessaYo May 6, 2024
4755377
Merge branch 'dev' into xRay
sMeilbeck May 10, 2024
33ea78b
Package-lock after merge
sMeilbeck May 10, 2024
33b5919
extend group with xray field. extend execution list modal for groups
bessaYo May 14, 2024
4c0e822
add group xray execution
bessaYo May 15, 2024
2c86786
check if scenario has testruns, before access
bessaYo May 22, 2024
3a0aa8e
Merge branch 'test-execution-list' into xRay
bessaYo May 23, 2024
2044f45
merge 2
bessaYo May 23, 2024
982267a
new functions to check for identical steps from stepdefs and xray
bessaYo May 23, 2024
92f7a1c
fix regex for links and emails
bessaYo May 24, 2024
bd1f22c
update comment and var name
bessaYo May 24, 2024
6be9382
Update fusedb function to add new scenario step defintions
bessaYo May 24, 2024
5998ea1
fix logic, maintain scenario order
bessaYo May 29, 2024
56cbf1c
origin labels for xray steps. reimplented logic for merging
bessaYo Jun 3, 2024
d770c03
New logic for precondition in xray storys. Preconditions are displaye…
bessaYo Jun 15, 2024
30eae09
update logic in frontend
bessaYo Jun 28, 2024
4c22617
selected story also changes in story bar
bessaYo Jul 2, 2024
7a18290
Scrolls to selected story in story bar
bessaYo Jul 2, 2024
3024691
Cleaned code for run test in story editor. Add backend route for temp…
bessaYo Jul 4, 2024
e907fe7
fix var
bessaYo Jul 5, 2024
dd19273
WIP reporting not running yet
bessaYo Jul 8, 2024
e23cdd6
add logic to create temp groups with nested pre conditions. No cycle …
bessaYo Jul 9, 2024
e4d0ed4
npm audit fix
jonycoo Jul 11, 2024
4a08e03
step.mid no longer required
jonycoo Jul 11, 2024
df387d0
Corrected nested pre condition logic.
bessaYo Jul 16, 2024
efe7325
minor fixes
bessaYo Jul 17, 2024
055ce71
Merge remote-tracking branch 'origin/dev' into xRay. + fix merge
jonycoo Jul 19, 2024
6a5f412
minor fixes
bessaYo Jul 17, 2024
c786449
Merge branch 'xray-preconditions' of https://github.com/adessoSE/Seed…
jonycoo Jul 19, 2024
8b03d50
Merge branch 'identical-steps' into xRay
jonycoo Jul 19, 2024
ab46b07
update status fix
bessaYo Jul 19, 2024
3ecda17
fix input paramter bug
bessaYo Jul 24, 2024
bd4dfd4
Add xray status update with precondition
bessaYo Jul 24, 2024
528e1d4
fix story status
bessaYo Jul 31, 2024
eebf4ab
add refactoring
bessaYo Aug 5, 2024
3e06bc8
jsdoc comments
bessaYo Aug 30, 2024
e0e3691
Merge branch 'dev' into xRay
bessaYo Sep 8, 2024
864684d
Merge branch 'dev' of github.com:adessoSE/Seed-Test into xRay
adessoCucumber Dec 3, 2024
dbbc07e
do not show scenarios from other stories, add "create first scenario"…
adessoCucumber Dec 3, 2024
ddc77a6
Fix export
sMeilbeck Dec 3, 2024
7a8c6f1
Merge pull request #796 from adessoSE/cleanXray
sMeilbeck Dec 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,896 changes: 1,471 additions & 1,425 deletions backend/src/database/DbServices.js

Large diffs are not rendered by default.

197 changes: 172 additions & 25 deletions backend/src/helpers/projectManagement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ import AdmZip from "adm-zip";
import path from "path";

enum Sources {
GITHUB = "github",
JIRA = "jira",
DB = "db",
GITHUB = "github",
JIRA = "jira",
DB = "db"
}

class Group {
_id: string;
name: string;
member_stories: Array<string>;
isSequential: boolean;
_id: string
name: string
member_stories: Array<string>
isSequential: boolean
xrayTestSet: boolean
}

class Repository {
Expand Down Expand Up @@ -211,19 +212,120 @@ function starredRepositories(ownerId, githubId, githubName, token) {
);
}

async function fuseStoryWithDb(story) {
const result = await mongo.getOneStory(parseInt(story.story_id, 10));
if (result !== null) {
story.scenarios = result.scenarios;
story.background = result.background;
story.lastTestPassed = result.lastTestPassed;
function mergeTestRunSteps(dbTestRunSteps, jiraTestRunSteps) {
if (dbTestRunSteps !== jiraTestRunSteps) {
return jiraTestRunSteps; }
else {
return dbTestRunSteps;
}
}

function mergeStepDefinitions(dbStepDefinitions, jiraStepDefinitions) {
const mergedStepDefinitions = {};
['given', 'when', 'then', 'example'].forEach(stepType => {
const dbSteps = dbStepDefinitions[stepType] || [];
const jiraSteps = jiraStepDefinitions[stepType] || [];

const allJiraInDb = jiraSteps.every(jiraStep =>
dbSteps.some(dbStep => dbStep.id === jiraStep.id)
);

if (allJiraInDb) {
mergedStepDefinitions[stepType] = dbSteps.map(dbStep => {
const jiraStep = jiraSteps.find(jStep => jStep.id === dbStep.id);
return jiraStep ? {...dbStep, ...jiraStep} : dbStep;
});
} else {
mergedStepDefinitions[stepType] = [
...jiraSteps,
...dbSteps.filter(dbStep => !jiraSteps.some(jStep => jStep.id === dbStep.id))
];
}
});

return mergedStepDefinitions;
}


function mergeStories(dbStory, jiraStory) {
const mergedStory = { ...dbStory };
const dbScenarios = dbStory.scenarios;
const jiraScenarios = jiraStory.scenarios;

const dbScenarioMap = new Map();
dbScenarios.forEach(scenario => dbScenarioMap.set(scenario.scenario_id, scenario));

const jiraScenarioMap = new Map();
jiraScenarios.forEach(scenario => jiraScenarioMap.set(scenario.scenario_id, scenario));

// inidicates if all xray jira scenarios are in db
const allJiraInDb = jiraScenarios.every(jiraScenario => dbScenarioMap.has(jiraScenario.scenario_id));

const mergedScenarios = [];

// if all jira scenarios are in db, we keep db order and merge jira scenarios
if (allJiraInDb) {

dbScenarios.forEach(dbScenario => {
const jiraScenario = jiraScenarioMap.get(dbScenario.scenario_id);
if (jiraScenario) {
mergedScenarios.push({
...dbScenario,
name: jiraScenario.name,
stepDefinitions: mergeStepDefinitions(dbScenario.stepDefinitions, jiraScenario.stepDefinitions),
testRunSteps: mergeTestRunSteps(dbScenario.testRunSteps, jiraScenario.testRunSteps),
testKey: jiraScenario.testKey
});
} else {
mergedScenarios.push(dbScenario);
}
});
// if not all jira scenarios are in db, we keep jira order first and add db scenarios
} else {
story.scenarios = [emptyScenario()];
story.background = emptyBackground();
jiraScenarios.forEach(jiraScenario => {
const dbScenario = dbScenarioMap.get(jiraScenario.scenario_id);
if (dbScenario) {
mergedScenarios.push({
...dbScenario,
name: jiraScenario.name,
stepDefinitions: mergeStepDefinitions(dbScenario.stepDefinitions, jiraScenario.stepDefinitions),
testRunSteps: mergeTestRunSteps(dbScenario.testRunSteps, jiraScenario.testRunSteps),
testKey: jiraScenario.testKey
});
} else {
mergedScenarios.push(jiraScenario);
}
});

// add remaining db scenarios that were not processed
dbScenarios.forEach(dbScenario => {
if (!jiraScenarioMap.has(dbScenario.scenario_id)) {
mergedScenarios.push(dbScenario);
}
});
}
story.story_id = parseInt(story.story_id, 10);
if (story.storySource !== "jira")
story.issue_number = parseInt(story.issue_number, 10);

mergedStory.scenarios = mergedScenarios;

return mergedStory;
}


async function fuseStoryWithDb(story) {
const result = await mongo.getOneStory(parseInt(story.story_id, 10));

if (result !== null) {

const mergedStory = mergeStories(result, story);
story.scenarios = mergedStory.scenarios;
story.background = result.background;
story.lastTestPassed = result.lastTestPassed;
} else {
story.scenarios = [emptyScenario()];
story.background = emptyBackground();
}
story.story_id = parseInt(story.story_id, 10);
if (story.storySource !== 'jira') story.issue_number = parseInt(story.issue_number, 10);

const finalStory = await mongo.upsertEntry(story.story_id, story);
story._id = finalStory._id;
Expand Down Expand Up @@ -326,7 +428,6 @@ function checkAndAddSuffix(name, conflictingNameList) {

// Add the new name (with or without suffix) to the list
conflictingNameList.push(newName);
console.log(conflictingNameList);
return newName;
}

Expand Down Expand Up @@ -371,10 +472,8 @@ async function importProject(file, repo_id?, projectName?, importMode?) {
});
const repoJsonData = zip.readAsText("repo.json");
const repoData = JSON.parse(repoJsonData);
console.log(repoData);
const mappingJsonData = zip.readAsText("keyStoryIds.json");
const mappingData = JSON.parse(mappingJsonData);
console.log(mappingData);
const repoBlocksJsonData = zip.readAsText("repoBlocks.json");
const repoBlocksData = JSON.parse(repoBlocksJsonData);
let groupMapping = [];
Expand All @@ -398,7 +497,7 @@ async function importProject(file, repo_id?, projectName?, importMode?) {
existingName: title,
associatedID: _id.toHexString(),
}));
console.log(existingNames);

const newData = existingNames.map(({ existingName }) => existingName);
existingNameList = existingNameList.concat(newData);
for (const storyFile of storyFiles) {
Expand All @@ -424,7 +523,7 @@ async function importProject(file, repo_id?, projectName?, importMode?) {
existingName: name,
associatedID: _id.toHexString(),
}));
console.log(existingNames);

const newData = existingNames.map(({ existingName }) => existingName);
existingNameList = existingNameList.concat(newData);
for (const singularBlock of repoBlocksData) {
Expand All @@ -448,7 +547,7 @@ async function importProject(file, repo_id?, projectName?, importMode?) {
existingName: name,
associatedID: _id.toHexString(),
}));
console.log(existingNames);

const newData = existingNames.map(({ existingName }) => existingName);
existingNameList = existingNameList.concat(newData);
for (const groupFile of groupFiles) {
Expand Down Expand Up @@ -571,7 +670,7 @@ async function importProject(file, repo_id?, projectName?, importMode?) {
client,
file
);
console.log(groupMapping);

await mongo.importBlocks(
true,
newRepo.toHexString(),
Expand Down Expand Up @@ -613,6 +712,53 @@ async function importProject(file, repo_id?, projectName?, importMode?) {
await client.close();
}
}
async function updateTestSets(testSets, repo_id) {
for (const testSet of testSets) {
try {
const storyIds = await getStorysByIssue(testSet.tests);

if (storyIds.length === 0) {
console.log(`No stories found for Test Set ${testSet.testSetKey}. Skipping group creation.`);
continue;
}

// Get repository to update groups
const repository = await mongo.getOneRepositoryById(repo_id);

// Find existing group by testSetKey
let existingGroup = repository.groups.find(group => group.name === testSet.testSetKey);

if (existingGroup) {
// Update existing group
const updatedGroup = { ...existingGroup, member_stories: storyIds };
await mongo.updateStoryGroup(repo_id, existingGroup._id.toString(), updatedGroup);
console.log(`Updated group for Test Set: ${testSet.testSetKey}`);
} else {
// Create a new group if it does not exist
const groupId = await mongo.createStoryGroup(
repo_id,
testSet.testSetKey,
storyIds,
true,
testSet.xrayTestSet
);
console.log(`Group created for Test Set: ${testSet.testSetKey}`);
}
} catch (e) {
console.error(`Error processing group for Test Set: ${testSet.testSetKey}:`, e);
}
}
}

async function getStorysByIssue(issueKeys) {
try {
const storiesIds = await mongo.getStoriesByIssueKeys(issueKeys);
return storiesIds
} catch (error) {
console.error("Error fetching stories by issue keys:", error);
return [];
}
}

module.exports = {
getJiraRepos,
Expand All @@ -625,4 +771,5 @@ module.exports = {
importProject,
checkAndAddSuffix,
findAssociatedID,
updateTestSets
};
16 changes: 8 additions & 8 deletions backend/src/helpers/reporting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ function analyzeScenarioReport(stories: Array<any>, reportName: string, scenario
console.log(`NUMBER OF SCENARIOS IN THE REPORT (must be 1): ${storyReport.elements.length}`);
const story = stories[0];
console.log(`Story ID: ${story._id}`);
console.log(story);
reportResults.storyId = story._id;
const scenarioReport = storyReport.elements[0]

Expand Down Expand Up @@ -203,10 +202,11 @@ function analyzeGroupReport(grpName: string, stories: any[], reportOptions: any)
reportResults.storyStatuses.push(result);
}
// end of for each story
reportResults.status = testPassed(overallPassedSteps, overallFailedSteps);
reportResults.status = testPassed(overallFailedSteps, overallPassedSteps);
reportResults.groupTestResults = { passedSteps: overallPassedSteps, failedSteps: overallFailedSteps, skippedSteps: overallSkippedSteps };
reportResults.scenariosTested = scenariosTested;
reportResults.reportName = grpName;
reportResults.storiesTested = stories;
return reportResults
} catch (error) {
reportResults.status = false;
Expand Down Expand Up @@ -254,7 +254,7 @@ async function createReport(res, reportName: string) {//TODO remove res here pus
try {
fs.writeFileSync(resolvedPath, report.jsonReport);
} catch (error) {
console.log('Error:', error);
console.error('Error:', error);
}

reporter.generate(setOptions(reportName));
Expand Down Expand Up @@ -344,7 +344,7 @@ function scenarioResult(scenarioReport: any, scenario: any) {
function deleteReport(jsonReport: string) {
const report = path.normalize(`${reportPath}${jsonReport}`);
fs.unlink(report, (err) => {
if (err) console.log(err);
if (err) console.error(err);
else console.log(`${report} deleted.`);
});
}
Expand All @@ -355,7 +355,6 @@ async function fetchFiles(stories, repoId){
.flatMap(scen => scen.stepDefinitions.when)
.filter(step => step.type === "Upload File")
.map(step => step.values[0]);
console.log(neededFiles)
if (neededFiles) return mongo.getFiles(neededFiles, repoId)
}

Expand All @@ -365,10 +364,10 @@ async function runReport(req, res, stories: any[], mode: ExecutionMode, paramete
try {
if (mode === ExecutionMode.GROUP) {
await fetchFiles(stories, parameters.repositoryId)
req.body.name = req.body.name.replace(/ /g, '_') + Date.now();
req.body.name = req.body.name.replace(/[ <>&]/g, '_') + Date.now();
fs.mkdirSync(`./features/${req.body.name}`);
if (parameters.isSequential == undefined || !parameters.isSequential)
reportObj = await Promise.all(stories.map((story) => testExecutor.executeTest(req, mode, story))).then((valueArr)=>valueArr.pop());
if (parameters.isSequential == undefined || !parameters.isSequential){
reportObj = await Promise.all(stories.map((story) => testExecutor.executeTest(req, mode, story))).then((valueArr)=>valueArr.pop());}
else {
for (const story of stories) {
reportObj = await testExecutor.executeTest(req, mode, story);
Expand All @@ -380,6 +379,7 @@ async function runReport(req, res, stories: any[], mode: ExecutionMode, paramete
reportObj = await testExecutor.executeTest(req, mode, story).catch((reason) =>{console.log('crashed in execute test');res.send(reason).status(500)});
}
} catch (error) {
console.error(error)
res.status(404).send(error);
return;
}
Expand Down
Loading
Loading