Skip to content

Commit

Permalink
feat: Enhance copy results functionality (#967)
Browse files Browse the repository at this point in the history
Addresses #935 by resolving several issues identified with the current test results copying process.

* Supports preserving results of a test even when a command has been removed, added or updated between test versions.
* Previously, if an older test plan report was marked as final, the newly created test plan report would also be marked as final. Instead, the newly created test plan report will always be created as final to allow test administrators to be able to make changes if required and mark as final again, if appropriate.
* Adds support for copying results from an advanced phase instead of just the phase being overwritten. For eg. results would only be copied from DRAFT if the older version is currently in DRAFT but wouldn't have if the older version was in CANDIDATE. This is now being done.
* Now allows results to be copied if adding to Test Queue for a specific combination and an older version exists with that combination that also has valid results. Previously this was only supported by the using the 'Advance to Phase' button on the Data Management page. But if for whatever reason, a report's combination was missed there would be no way to now get that result back. This allows for the result to be included again when adding to the Test Queue with a dialog pop up for an admin to confirm if they want to make a new report or copy the old results (if any exists).
  • Loading branch information
howard-e authored Apr 10, 2024
1 parent f89460f commit 3a4d3c8
Show file tree
Hide file tree
Showing 13 changed files with 829 additions and 383 deletions.
154 changes: 121 additions & 33 deletions client/components/AddTestToQueueWithConfirmation/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,26 @@ function AddTestToQueueWithConfirmation({
buttonText = 'Add to Test Queue',
triggerUpdate = () => {}
}) {
const [errorMessage, setErrorMessage] = useState(false);
const [showPreserveReportDataMessage, setShowPreserveReportDataMessage] =
useState(false);
const [showConfirmation, setShowConfirmation] = useState(false);
const [canUseOldResults, setCanUseOldResults] = useState(false);
const [addTestPlanReport] = useMutation(ADD_TEST_QUEUE_MUTATION);
const [scheduleCollection] = useMutation(SCHEDULE_COLLECTION_JOB_MUTATION);
const { data: existingTestPlanReportsData } = useQuery(
EXISTING_TEST_PLAN_REPORTS,
{
variables: {
testPlanVersionId: testPlanVersion?.id
testPlanVersionId: testPlanVersion?.id,
directory: testPlanVersion?.testPlan?.directory
},
fetchPolicy: 'cache-and-network',
skip: !testPlanVersion?.id
}
);

const existingTestPlanReports =
existingTestPlanReportsData?.testPlanVersion.testPlanReports;
existingTestPlanReportsData?.existingTestPlanVersion?.testPlanReports;

const conflictingReportExists = existingTestPlanReports?.some(report => {
return (
Expand All @@ -49,6 +52,31 @@ function AddTestToQueueWithConfirmation({
);
});

let latestOldVersion;
let oldReportToCopyResultsFrom;

// Prioritize a conflicting report for the current version, otherwise
// check if any results data available from a previous result
if (
!conflictingReportExists &&
existingTestPlanReportsData?.oldTestPlanVersions?.length
) {
latestOldVersion =
existingTestPlanReportsData?.oldTestPlanVersions?.reduce((a, b) =>
new Date(a.updatedAt) > new Date(b.updatedAt) ? a : b
);

if (
new Date(latestOldVersion?.updatedAt) <
new Date(testPlanVersion?.updatedAt)
) {
oldReportToCopyResultsFrom = latestOldVersion?.testPlanReports.some(
({ at: { id: atId }, browser: { id: browserId } }) =>
atId == at?.id && browserId == browser?.id
);
}
}

const { triggerLoad, loadingMessage } = useTriggerLoad();
const buttonRef = useRef();

Expand Down Expand Up @@ -104,7 +132,14 @@ function AddTestToQueueWithConfirmation({
actions.push({
label: 'Add and run later',
onClick: async () => {
await addTestToQueue();
await addTestToQueue(
canUseOldResults
? {
copyResultsFromTestPlanReportId:
latestOldVersion.id
}
: {}
);
await closeWithUpdate();
}
});
Expand All @@ -113,7 +148,14 @@ function AddTestToQueueWithConfirmation({
actions.push({
label: 'Add and run with bot',
onClick: async () => {
const testPlanReport = await addTestToQueue();
const testPlanReport = await addTestToQueue(
canUseOldResults
? {
copyResultsFromTestPlanReportId:
latestOldVersion.id
}
: {}
);
await scheduleCollectionJob(testPlanReport);
await closeWithUpdate();
}
Expand Down Expand Up @@ -141,48 +183,94 @@ function AddTestToQueueWithConfirmation({
);
};

const renderErrorDialog = () => {
const renderPreserveReportDataDialog = () => {
let title;
let content;
let actions = [];

if (oldReportToCopyResultsFrom) {
title = 'Older Results Data Found';
content =
'Older results with the same AT, browser and test plan ' +
'were found for the report being created. Would you like ' +
'to copy the older results into the report or create a ' +
'completely new report?';
actions = [
{
label: 'Create empty report',
onClick: async () => {
setShowPreserveReportDataMessage(false);
if (hasAutomationSupport) {
setShowConfirmation(true);
} else {
await addTestToQueue();
}
}
},
{
label: 'Copy older results',
onClick: async () => {
setShowPreserveReportDataMessage(false);
setCanUseOldResults(true);

if (hasAutomationSupport) {
setShowConfirmation(true);
} else {
await addTestToQueue({
copyResultsFromTestPlanReportId:
latestOldVersion.id
});
}
}
}
];
} else {
title = 'Conflicting Report Found';
content =
'The report could not be created because an existing ' +
'report was found on the reports page with the same AT, ' +
'browser and test plan version. Would you like to return ' +
'the existing report back to the test queue?';
actions = [
{
label: 'Proceed',
onClick: async () => {
setShowPreserveReportDataMessage(false);
if (hasAutomationSupport) {
setShowConfirmation(true);
} else {
await addTestToQueue();
}
}
}
];
}

return (
<BasicModal
show={errorMessage}
title="Conflicting Report Found"
content={
'The report could not be created because an existing ' +
'report was found on the reports page with the same AT, ' +
'browser and test plan version. Would you like to return ' +
'the existing report back to the test queue?'
}
show={showPreserveReportDataMessage}
title={title}
content={content}
closeLabel="Cancel"
staticBackdrop={true}
actions={[
{
label: 'Proceed',
onClick: async () => {
setErrorMessage(false);
if (hasAutomationSupport) {
setShowConfirmation(true);
} else {
await addTestToQueue();
}
}
}
]}
actions={actions}
useOnHide
handleClose={async () => {
setErrorMessage(false);
setShowPreserveReportDataMessage(false);
}}
/>
);
};

const addTestToQueue = async () => {
const addTestToQueue = async ({ copyResultsFromTestPlanReportId } = {}) => {
let tpr;
await triggerLoad(async () => {
const res = await addTestPlanReport({
variables: {
testPlanVersionId: testPlanVersion.id,
atId: at.id,
browserId: browser.id
browserId: browser.id,
copyResultsFromTestPlanReportId
}
});
const testPlanReport =
Expand Down Expand Up @@ -212,8 +300,8 @@ function AddTestToQueueWithConfirmation({
disabled={disabled}
variant="secondary"
onClick={async () => {
if (conflictingReportExists) {
setErrorMessage(true);
if (conflictingReportExists || oldReportToCopyResultsFrom) {
setShowPreserveReportDataMessage(true);
} else {
if (hasAutomationSupport) {
setShowConfirmation(true);
Expand All @@ -227,7 +315,7 @@ function AddTestToQueueWithConfirmation({
>
{buttonText}
</Button>
{renderErrorDialog()}
{renderPreserveReportDataDialog()}
{renderConfirmation()}
</LoadingStatus>
);
Expand Down
23 changes: 21 additions & 2 deletions client/components/AddTestToQueueWithConfirmation/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ export const SCHEDULE_COLLECTION_JOB_MUTATION = gql`
`;

export const EXISTING_TEST_PLAN_REPORTS = gql`
query ExistingTestPlanReports($testPlanVersionId: ID!) {
testPlanVersion(id: $testPlanVersionId) {
query ExistingTestPlanReports(
$testPlanVersionId: ID!
$directory: String!
) {
existingTestPlanVersion: testPlanVersion(id: $testPlanVersionId) {
id
testPlanReports {
id
Expand All @@ -28,5 +31,21 @@ export const EXISTING_TEST_PLAN_REPORTS = gql`
}
}
}
oldTestPlanVersions: testPlanVersions(
phases: [CANDIDATE, RECOMMENDED]
directory: $directory
) {
id
updatedAt
testPlanReports {
id
at {
id
}
browser {
id
}
}
}
}
`;
38 changes: 23 additions & 15 deletions client/components/DataManagement/DataManagementRow/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -572,18 +572,18 @@ const DataManagementRow = ({
}
}

// If there is an earlier version that is draft and that version has some test plan
// If there is an earlier version that is draft or higher, and that version has some test plan
// runs in the test queue, this button will run the process for updating existing
// reports and preserving data for tests that have not changed.
let testPlanVersionDataToInclude;
if (draftTestPlanVersions.length) {
if (otherTestPlanVersions.length) {
const {
latestVersion: draftLatestVersion,
latestVersionDate: draftLatestVersionDate
} = getVersionData(draftTestPlanVersions);
latestVersion: otherLatestVersion,
latestVersionDate: otherLatestVersionDate
} = getVersionData(otherTestPlanVersions);

if (draftLatestVersionDate < latestVersionDate)
testPlanVersionDataToInclude = draftLatestVersion;
if (otherLatestVersionDate < latestVersionDate)
testPlanVersionDataToInclude = otherLatestVersion;
}

// Otherwise, show VERSION_STRING link with a draft transition button. Phase is
Expand Down Expand Up @@ -688,20 +688,28 @@ const DataManagementRow = ({
// If required reports are complete and user is an admin, show "Advance to
// Candidate" button.
if (testPlanVersions.length) {
// If there is an earlier version that is candidate and that version has some
// If there is an earlier version that is candidate or higher and that version has some
// test plan runs in the test queue, this button will run the process for
// updating existing reports and preserving data for tests that have not
// changed.
let testPlanVersionDataToInclude;
if (candidateTestPlanVersions.length) {
const testPlanVersionsDataToInclude = [
...candidateTestPlanVersions,
...recommendedTestPlanVersions
];
if (testPlanVersionsDataToInclude.length) {
const {
latestVersion: candidateLatestVersion,
latestVersionDate: candidateLatestVersionDate
} = getVersionData(candidateTestPlanVersions);

if (candidateLatestVersionDate < latestVersionDate)
latestVersion: testPlanDataToIncludeLatestVersion,
latestVersionDate:
testPlanDataToIncludeLatestVersionDate
} = getVersionData(testPlanVersionsDataToInclude);

if (
testPlanDataToIncludeLatestVersionDate <
latestVersionDate
)
testPlanVersionDataToInclude =
candidateLatestVersion;
testPlanDataToIncludeLatestVersion;
}

let coveredReports = [];
Expand Down
2 changes: 2 additions & 0 deletions client/components/TestQueue/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,14 @@ export const ADD_TEST_QUEUE_MUTATION = gql`
$testPlanVersionId: ID!
$atId: ID!
$browserId: ID!
$copyResultsFromTestPlanReportId: ID
) {
findOrCreateTestPlanReport(
input: {
testPlanVersionId: $testPlanVersionId
atId: $atId
browserId: $browserId
copyResultsFromTestPlanReportId: $copyResultsFromTestPlanReportId
}
) {
populatedData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ export const mockedTestPlanVersion = {
export default (
meQuery,
testPlanReportStatusDialogQuery,
initiatedByAutomationQuery
existingTestPlanReportsQuery
) => [
{
request: {
Expand Down Expand Up @@ -386,14 +386,15 @@ export default (
},
{
request: {
query: initiatedByAutomationQuery,
query: existingTestPlanReportsQuery,
variables: {
testPlanVersionId: '7'
testPlanVersionId: '7',
directory: 'combobox-select-only'
}
},
result: {
data: {
testPlanVersion: {
existingTestPlanVersion: {
id: '7',
testPlanReports: [
{
Expand All @@ -411,7 +412,8 @@ export default (
}
}
]
}
},
oldTestPlanVersions: []
}
}
}
Expand Down
Loading

0 comments on commit 3a4d3c8

Please sign in to comment.