Skip to content

Commit

Permalink
Adding link to copy repo tests badge to repo page (#1218)
Browse files Browse the repository at this point in the history
* Adding link to copy repo tests badge to repo page

* Updating badge tooltip text

* Improving vertical spacing between repo sections
  • Loading branch information
craigatk authored Apr 2, 2024
1 parent 25c8a01 commit 9349cd9
Show file tree
Hide file tree
Showing 17 changed files with 278 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,7 @@ fun loadCloverCoverageLarge() {
println("View run with large Clover coverage and UI results at $uiBaseUrl${currentResultsResponse.uri}")
}

fun loadMultipleTestRunsFromSameRepoForTimeline() {
val repoName = "timeline-org/timeline-repo"
fun loadMultipleTestRunsFromSameRepoForTimeline(repoName: String = "timeline-org/timeline-repo", printLink: Boolean = true) {
val branchName = "main"
val gitMetadata = GitMetadata()
gitMetadata.repoName = repoName
Expand All @@ -266,7 +265,18 @@ fun loadMultipleTestRunsFromSameRepoForTimeline() {
sendGroupedResultsToServer(groupedResultsXmlLoader.wrapResultsXmlInGroup(resultsXml = resultsXmlLoader.longOutput(), metadata = resultsMetadata))
sendGroupedResultsToServer(groupedResultsXmlLoader.wrapResultsXmlInGroup(resultsXml = resultsXmlLoader.someIgnored(), metadata = resultsMetadata))

println("View repository test run timeline at $uiBaseUrl/repository/$repoName")
if (printLink) {
println("View repository test run timeline at $uiBaseUrl/repository/$repoName")
}
}

fun loadTestRunTimelineAndCoverageTimeline() {
val repoName = "timeline-org/test-cov-timeline-repo"

loadMultipleTestRunsFromSameRepoForTimeline(repoName, false)
repositoryCoverageTimeline(repoName, false)

println("View repository test run and coverage timeline at $uiBaseUrl/repository/$repoName")
}

fun loadMultipleShortTestRunsFromSameRepoForTimeline() {
Expand Down Expand Up @@ -516,8 +526,7 @@ fun performanceSingleTestTimeline() {
println("View performance test timeline with single test at $uiBaseUrl/repository/$repoName")
}

fun repositoryCoverageTimeline() {
val repoName = "cov-org/cov-repo"
fun repositoryCoverageTimeline(repoName: String = "cov-org/cov-repo", printLink: Boolean = true) {
val branchName = "main"
val gitMetadata = GitMetadata()
gitMetadata.repoName = repoName
Expand All @@ -533,7 +542,9 @@ fun repositoryCoverageTimeline() {
sendCoverageToServer(sendGroupedResultsToServer(groupedResultsXmlLoader.passingGroupedResults(metadata = resultsMetadata)).id, JacocoXmlLoader().junitResultsParser())
sendCoverageToServer(sendGroupedResultsToServer(groupedResultsXmlLoader.passingGroupedResults(metadata = resultsMetadata)).id, JacocoXmlLoader().junitResultsParserReduced())

println("View repository coverage timeline at $uiBaseUrl/repository/$repoName")
if (printLink) {
println("View repository coverage timeline at $uiBaseUrl/repository/$repoName")
}
}

fun repositoryCoverageTimelineDifferentBranches() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ fun main() {
loadMultipleTestRunsFromSameRepoForTimeline()
loadMultipleShortTestRunsFromSameRepoForTimeline()
slowTimeline()
loadTestRunTimelineAndCoverageTimeline()
loadPerformanceK6GetRun()
loadPerformanceK6GetFailedTestCasesLarge()
performanceSingleTestTimeline()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { CopyToClipboard } from "react-copy-to-clipboard";
import {
repositoryLinkUrlAPI,
repositoryLinkUrlUI,
} from "../Repository/RepositoryLink";
} from "../../Repository/RepositoryLink";
import { Chip, Fade, Link, Tooltip } from "@material-ui/core";
import FileCopyOutlinedIcon from "@material-ui/icons/FileCopyOutlined";

Expand Down Expand Up @@ -61,7 +61,7 @@ const CoverageBadge = ({
dangerouslySetInnerHTML={badgeContents}
/>
<span className={classes.badgeLink}>
<Tooltip title="Copy coverage badge readme code to clipboard">
<Tooltip title="Copy coverage badge Markdown readme code to clipboard">
<CopyToClipboard onCopy={onCopy} text={badgeMarkdown}>
<Link
data-testid="coverage-badge-copy-link"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import { fetchRepositoryCoverageBadge } from "../service/RepositoryService";
import { fetchRepositoryCoverageBadge } from "../../service/RepositoryService";
import CoverageBadge from "./CoverageBadge";

interface RepositoryCoverageBadgeProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from "react";
import CoverageBadge from "./CoverageBadge";
import { fetchCoverageBadge } from "../service/TestRunService";
import { fetchCoverageBadge } from "../../service/TestRunService";

interface TestRunCoverageBadgeProps {
publicId: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import "@testing-library/jest-dom/extend-expect";
import React from "react";
import MockAdapter from "axios-mock-adapter";
import { axiosInstance } from "../../service/AxiosService";
import { render } from "@testing-library/react";
import { axiosInstance } from "../../../service/AxiosService";
import { act, render } from "@testing-library/react";
import {
createHistory,
createMemorySource,
Expand Down Expand Up @@ -45,7 +45,9 @@ describe("RepositoryCoverageBadge", () => {
"[![Code coverage percentage](undefined/repo/my-org/my-repo/badge/coverage)](undefined/repository/my-org/my-repo/coverage)",
);

(await findByTestId("coverage-badge-copy-link")).click();
await act(async () => {
(await findByTestId("coverage-badge-copy-link")).click();
});

await findByTestId("coverage-badge-copied");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "@testing-library/jest-dom/extend-expect";
import React from "react";
import MockAdapter from "axios-mock-adapter";
import { axiosInstance } from "../../service/AxiosService";
import { axiosInstance } from "../../../service/AxiosService";
import { render } from "@testing-library/react";
import {
createHistory,
Expand Down
37 changes: 37 additions & 0 deletions ui/src/Badge/tests/RepositoryTestsBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as React from "react";
import { fetchRepositoryTestsBadge } from "../../service/RepositoryService";
import TestsBadge from "./TestsBadge";

interface RepositoryTestsBadgeProps {
repoName: string;
projectName?: string;
}

const RepositoryTestsBadge = ({
repoName,
projectName,
}: RepositoryTestsBadgeProps) => {
const [badgeSvg, setBadgeSvg] = React.useState<string>(null);

React.useEffect(() => {
fetchRepositoryTestsBadge(repoName, projectName)
.then((response) => {
setBadgeSvg(response.data);
})
.catch((_) => {});
}, [setBadgeSvg]);

if (badgeSvg) {
return (
<TestsBadge
badgeSvg={badgeSvg}
repoName={repoName}
projectName={projectName}
/>
);
} else {
return null;
}
};

export default RepositoryTestsBadge;
87 changes: 87 additions & 0 deletions ui/src/Badge/tests/TestsBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import * as React from "react";
import { makeStyles } from "@material-ui/styles";
import { useLocation } from "@reach/router";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { repositoryLinkUrlAPI } from "../../Repository/RepositoryLink";
import { Chip, Fade, Link, Tooltip } from "@material-ui/core";
import FileCopyOutlinedIcon from "@material-ui/icons/FileCopyOutlined";

interface TestsBadgeProps {
badgeSvg: string;
repoName: string;
projectName?: string;
}

const useStyles = makeStyles(() => ({
badgeLink: {
display: "inline-block",
marginLeft: "8px",
cursor: "pointer",
},
copied: {
marginLeft: "5px",
verticalAlign: "top",
},
}));

const TestsBadge = ({ badgeSvg, repoName, projectName }: TestsBadgeProps) => {
const classes = useStyles({});

const [showCopied, setShowCopied] = React.useState<boolean>(false);

const location = useLocation();

const badgeContents = { __html: badgeSvg };

const latestTestRunPageLink =
location.origin +
repositoryLinkUrlAPI(repoName, projectName, "/run/latest");
const badgeSvgUrl =
location.origin +
repositoryLinkUrlAPI(repoName, projectName, "/badge/tests");
const badgeMarkdown = `[![Test results](${badgeSvgUrl})](${latestTestRunPageLink})`;

const onCopy = () => {
setShowCopied(true);

setTimeout(() => setShowCopied(false), 3000);
};

if (badgeSvg) {
return (
<div>
<span
data-testid="tests-badge-contents"
dangerouslySetInnerHTML={badgeContents}
/>
<span className={classes.badgeLink}>
<Tooltip title="Copy tests badge Markdown readme code to clipboard">
<CopyToClipboard onCopy={onCopy} text={badgeMarkdown}>
<Link
data-testid="tests-badge-copy-link"
data-badge={badgeMarkdown}
>
<FileCopyOutlinedIcon fontSize="small" />
</Link>
</CopyToClipboard>
</Tooltip>
<span>
<Fade in={showCopied}>
<Chip
label="Copied to clipboard"
variant="outlined"
size="small"
className={classes.copied}
data-testid="tests-badge-copied"
/>
</Fade>
</span>
</span>
</div>
);
} else {
return null;
}
};

export default TestsBadge;
56 changes: 56 additions & 0 deletions ui/src/Badge/tests/__tests__/RepositoryTestsBadge.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import "@testing-library/jest-dom/extend-expect";
import React from "react";
import MockAdapter from "axios-mock-adapter";
import { axiosInstance } from "../../../service/AxiosService";
import { act, render } from "@testing-library/react";
import {
createHistory,
createMemorySource,
LocationProvider,
} from "@reach/router";
import RepositoryTestsBadge from "../RepositoryTestsBadge";

describe("RepositoryTestsBadge", () => {
let mockAxios;

beforeEach(() => {
// @ts-ignore
mockAxios = new MockAdapter(axiosInstance);
});

afterEach(() => {
mockAxios.restore();
});

it("should display tests badge", async () => {
const repoName = "my-org/my-repo";
mockAxios
.onGet(`http://localhost:8080/repo/${repoName}/badge/tests`)
.reply(200, "<span>my-badge</span>");

document.execCommand = jest.fn();

const { findByTestId } = render(
<LocationProvider history={createHistory(createMemorySource("/ui"))}>
<RepositoryTestsBadge repoName={repoName} />
</LocationProvider>,
);

expect(await findByTestId("tests-badge-contents")).toHaveTextContent(
"my-badge",
);

expect(await findByTestId("tests-badge-copy-link")).toHaveAttribute(
"data-badge",
"[![Test results](undefined/repo/my-org/my-repo/badge/tests)](undefined/repo/my-org/my-repo/run/latest)",
);

await act(async () => {
(await findByTestId("tests-badge-copy-link")).click();
});

await findByTestId("tests-badge-copied");

expect(document.execCommand).toHaveBeenCalledWith("copy");
});
});
2 changes: 1 addition & 1 deletion ui/src/Coverage/CoverageSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { fetchCoverage } from "../service/TestRunService";
import OverallCoverageGraphs from "./OverallCoverageGraphs";
import CleanLink from "../Link/CleanLink";
import { makeStyles } from "@material-ui/styles";
import TestRunCoverageBadge from "../Badge/TestRunCoverageBadge";
import TestRunCoverageBadge from "../Badge/coverage/TestRunCoverageBadge";
import { Grid, Hidden } from "@material-ui/core";

interface CoverageSummaryProps {
Expand Down
3 changes: 1 addition & 2 deletions ui/src/Repository/Coverage/RepositoryCoverageDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as React from "react";
import { RepositoryCoverageTimeline } from "../../model/RepositoryModel";
import PageTitle from "../../PageTitle";
import RepositoryCoverageTimelineGraph from "./RepositoryCoverageTimelineGraph";
import { Typography } from "@material-ui/core";
import { makeStyles } from "@material-ui/styles";
import RepositoryCoverageBadge from "../../Badge/RepositoryCoverageBadge";
import RepositoryCoverageBadge from "../../Badge/coverage/RepositoryCoverageBadge";

interface RepositoryCoverageDetailsProps {
coverageTimeline: RepositoryCoverageTimeline;
Expand Down
Loading

0 comments on commit 9349cd9

Please sign in to comment.