Skip to content

Commit 125ae79

Browse files
Venefilynlachmanfrantisek
authored andcommitted
Initial poc
1 parent 0065ab5 commit 125ae79

File tree

3 files changed

+170
-0
lines changed

3 files changed

+170
-0
lines changed

frontend/src/app/Results/ResultsPageTestingFarm.tsx

+20
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
DataListCell,
2323
DataListToggle,
2424
ClipboardCopy,
25+
CardHeader,
2526
} from "@patternfly/react-core";
2627

2728
import { ErrorConnection } from "../Errors/ErrorConnection";
@@ -45,6 +46,7 @@ import {
4546
import { Preloader } from "../Preloader/Preloader";
4647
import { ResultsPageCoprDetails } from "./ResultsPageCoprDetails";
4748
import { SHACopy } from "../utils/SHACopy";
49+
import { TestingFarmPoC } from "./TestingFarmPoC";
4850

4951
export interface TestingFarmOverview {
5052
pipeline_id: string; // UUID
@@ -218,6 +220,24 @@ const ResultsPageTestingFarm = () => {
218220
</Text>
219221
</TextContent>
220222
</PageSection>
223+
<PageSection>
224+
<Card>
225+
<CardBody>
226+
<CardHeader>
227+
<Title headingLevel={"h1"}>Testing Farm proof of concept</Title>
228+
</CardHeader>
229+
<CardBody>
230+
{!data ? (
231+
<Preloader />
232+
) : (
233+
<TestingFarmPoC
234+
url={`https://api.testing-farm.io/v0.1/requests/${data.pipeline_id}`}
235+
/>
236+
)}
237+
</CardBody>
238+
</CardBody>
239+
</Card>
240+
</PageSection>
221241
<PageSection>
222242
<Card>
223243
{!data ? (
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright Contributors to the Packit project.
2+
// SPDX-License-Identifier: MIT
3+
4+
import { LogViewer } from "@patternfly/react-log-viewer";
5+
import { useQuery } from "@tanstack/react-query";
6+
import { fetchLog } from "./TestingFarmPoC";
7+
8+
export const TestcaseLog: React.FC<{ testCase: Element }> = ({ testCase }) => {
9+
const logs = Array.from(testCase.querySelectorAll("logs > log"));
10+
const logToDisplay = logs
11+
.find((log) => log.getAttribute("name")?.endsWith("testout.log"))
12+
?.getAttribute("href");
13+
14+
const { data, isInitialLoading } = useQuery([logToDisplay], () =>
15+
logToDisplay ? fetchLog(logToDisplay) : "",
16+
);
17+
18+
if (isInitialLoading) {
19+
return <Preloader />;
20+
}
21+
22+
return <LogViewer theme="dark" data={data} />;
23+
};
+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright Contributors to the Packit project.
2+
// SPDX-License-Identifier: MIT
3+
4+
import { Tab, TabTitleText, Tabs } from "@patternfly/react-core";
5+
import { LogViewer } from "@patternfly/react-log-viewer";
6+
import { useQuery } from "@tanstack/react-query";
7+
import { name } from "ejs";
8+
import { useMemo, useState } from "react";
9+
import { Preloader } from "../Preloader/Preloader";
10+
11+
const fetchTestingFarm = (url: string): Promise<unknown> =>
12+
fetch(url).then((response) => {
13+
if (!response.ok && response.status !== 404) {
14+
throw Promise.reject(response);
15+
}
16+
return response.json();
17+
});
18+
19+
interface TestingFarmPoCProps {
20+
url: string;
21+
}
22+
export const TestingFarmPoC: React.FC<TestingFarmPoCProps> = ({ url }) => {
23+
const { data, isError, isInitialLoading } = useQuery<any>([url], () =>
24+
fetchTestingFarm(url),
25+
);
26+
if (isInitialLoading) {
27+
return <>Loading</>;
28+
}
29+
const xunit = new DOMParser().parseFromString(data.result.xunit, "text/xml");
30+
console.log(xunit);
31+
console.log(xunit.getElementsByTagName("testsuites"));
32+
const testsuitesDom = Array.from(xunit.getElementsByTagName("testsuites"));
33+
const testsuiteDom = Array.from(
34+
testsuitesDom[0].getElementsByTagName("testsuite"),
35+
); //.map(testSuite => <>test</>)
36+
console.log(testsuiteDom);
37+
return (
38+
<>
39+
Overall status: {testsuitesDom[0].getAttribute("overall-result")}
40+
<TestSuiteTabs testSuitesDom={testsuitesDom}></TestSuiteTabs>
41+
</>
42+
);
43+
};
44+
45+
const TestSuiteTabs: React.FC<{ testSuitesDom: Element[] }> = ({
46+
testSuitesDom,
47+
}) => {
48+
const [activeKey, setActiveKey] = useState<string | number>(0); // Toggle currently active tab
49+
const handleTabClick = (
50+
event: React.MouseEvent<any> | React.KeyboardEvent | MouseEvent,
51+
tabIndex: string | number,
52+
) => {
53+
setActiveKey(tabIndex);
54+
};
55+
const t = testSuitesDom.map((testSuite, i) => {
56+
const testsuiteTabs = Array.from(
57+
testSuite.getElementsByTagName("testsuite"),
58+
).map((testSuite, j) => testSuiteTab(j, testSuite));
59+
return (
60+
<Tabs key={i} isBox onSelect={handleTabClick} activeKey={activeKey}>
61+
{testsuiteTabs}
62+
</Tabs>
63+
);
64+
});
65+
return <>{t}</>;
66+
};
67+
68+
const testSuiteTab = (eventKey: string | number, testSuiteDom: Element) => {
69+
const testcases = Array.from(testSuiteDom.getElementsByTagName("testcase"));
70+
return (
71+
<Tab
72+
key={eventKey}
73+
eventKey={eventKey}
74+
title={
75+
<TabTitleText role="region">
76+
{testSuiteDom.getAttribute("name")} -{" "}
77+
{testSuiteDom.getAttribute("result")}
78+
</TabTitleText>
79+
}
80+
>
81+
<Tabs isSecondary activeKey={0}>
82+
{testcases.map((testcase, i) => (
83+
<Tab
84+
key={i}
85+
eventKey={i}
86+
title={
87+
<TabTitleText>
88+
{testcase.getAttribute("name")} -{" "}
89+
{testSuiteDom.getAttribute("result")}
90+
</TabTitleText>
91+
}
92+
>
93+
<TestcaseLog testCase={testcase} />
94+
</Tab>
95+
))}
96+
</Tabs>
97+
</Tab>
98+
);
99+
};
100+
101+
const fetchLog = async (url: string): Promise<any> => {
102+
const response = await fetch(url);
103+
if (!response.ok && response.status !== 404) {
104+
throw Promise.reject(response);
105+
}
106+
return await response.text();
107+
};
108+
109+
const TestcaseLog: React.FC<{ testCase: Element }> = ({ testCase }) => {
110+
const logs = Array.from(testCase.querySelectorAll("logs > log"));
111+
const logToDisplay = logs
112+
.find((log) => log.getAttribute("name")?.endsWith("testout.log"))
113+
?.getAttribute("href");
114+
115+
console.log("logToDisplay", logToDisplay);
116+
const { data, isInitialLoading } = useQuery({
117+
queryKey: [logToDisplay],
118+
queryFn: () => (logToDisplay ? fetchLog(logToDisplay) : ""),
119+
enabled: !!logToDisplay,
120+
});
121+
122+
if (isInitialLoading) {
123+
return <Preloader />;
124+
}
125+
126+
return <LogViewer theme="dark" data={data} />;
127+
};

0 commit comments

Comments
 (0)