Skip to content

Commit ab14e84

Browse files
authored
Merge pull request #24 from WebFuzzing/low-code
low-code support
2 parents 8e0554d + 3c53d02 commit ab14e84

7 files changed

Lines changed: 997 additions & 453 deletions

File tree

web-report/package-lock.json

Lines changed: 889 additions & 427 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web-report/package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,26 @@
88
"generate": "json2ts ../src/main/resources/wfc/schemas/report.yaml src/types/GeneratedTypes.tsx && ts-to-zod src/types/GeneratedTypes.tsx src/types/GeneratedTypesZod.ts",
99
"build": "tsc -b && vite build",
1010
"installAndBuild": "npm install && npm run generate && vitest --no-watch && tsc -b && vite build && npm run copyRunFiles",
11-
"copyRunFiles": "cpx webreport.bat '../target/classes/webreport' && cpx webreport.command '../target/classes/webreport' && cpx webreport.py '../target/classes/webreport' && cpx 'src-e2e/static/robots.txt' '../target/classes/webreport'",
11+
"copyRunFiles": "cpx webreport.bat \"../target/classes/webreport\" && cpx webreport.command \"../target/classes/webreport\" && cpx webreport.py \"../target/classes/webreport\" && cpx \"src-e2e/static/robots.txt\" \"../target/classes/webreport\"",
1212
"lint": "eslint .",
1313
"preview": "vite preview",
14-
"debug": "vite build && cpx 'src-e2e/static/*' '../target/classes/webreport' && vite preview",
14+
"debug": "vite build && cpx \"src-e2e/static/*\" \"../target/classes/webreport\" && vite preview",
1515
"test": "vitest"
1616
},
1717
"dependencies": {
1818
"@radix-ui/react-accordion": "^1.2.3",
1919
"@radix-ui/react-progress": "^1.1.3",
2020
"@radix-ui/react-scroll-area": "^1.2.3",
2121
"@radix-ui/react-slot": "^1.1.2",
22+
"@radix-ui/react-switch": "^1.2.6",
2223
"@radix-ui/react-tabs": "^1.1.3",
2324
"@radix-ui/react-tooltip": "^1.2.7",
2425
"@tailwindcss/vite": "^4.0.14",
2526
"class-variance-authority": "^0.7.1",
2627
"clsx": "^2.1.1",
2728
"json-schema-to-typescript": "^15.0.4",
2829
"lucide-react": "^0.483.0",
30+
"radix-ui": "^1.4.3",
2931
"react": "^19.0.0",
3032
"react-dom": "^19.0.0",
3133
"react-syntax-highlighter": "^15.6.1",
@@ -36,13 +38,13 @@
3638
"zod": "^3.25.67"
3739
},
3840
"optionalDependencies": {
41+
"@esbuild/darwin-arm64": "0.19.12",
3942
"@tailwindcss/oxide-linux-arm64-gnu": "^4.0.1",
4043
"@tailwindcss/oxide-linux-arm64-musl": "^4.0.1",
4144
"@tailwindcss/oxide-linux-x64-musl": "^4.0.1",
4245
"lightningcss-linux-arm64-gnu": "^1.29.1",
4346
"lightningcss-linux-arm64-musl": "^1.29.1",
44-
"lightningcss-linux-x64-musl": "^1.29.1",
45-
"@esbuild/darwin-arm64": "0.19.12"
47+
"lightningcss-linux-x64-musl": "^1.29.1"
4648
},
4749
"devDependencies": {
4850
"@eslint/js": "^9.21.0",

web-report/src/AppProvider.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ type AppContextType = {
1414
filterEndpoints: (activeFilters: Record<number, string>) => ITransformedReport[];
1515
filteredEndpoints: ITransformedReport[];
1616
invalidReportErrors: ZodIssue[] | null;
17+
lowCodeMode: boolean;
18+
setLowCodeMode: (v: boolean) => void;
1719
};
1820

1921
const AppContext = createContext<AppContextType | undefined>(undefined);
@@ -24,11 +26,14 @@ type AppProviderProps = {
2426

2527
export const AppProvider = ({ children }: AppProviderProps) => {
2628

29+
const initialLowCode = (window as unknown as { __WFC_LOW_CODE__?: boolean }).__WFC_LOW_CODE__ === true;
30+
2731
const [data, setData] = useState<WebFuzzingCommonsReport | null>(null);
2832
const [loading, setLoading] = useState(true);
2933
const [error, setError] = useState<string | null>(null);
3034
const [invalidReportErrors, setInvalidReportErrors] = useState<ZodIssue[] | null>(null);
3135
const [testFiles, setTestFiles] = useState<ITestFiles[]>([]);
36+
const [lowCodeMode, setLowCodeMode] = useState<boolean>(initialLowCode);
3237
const transformedReport = transformWebFuzzingReport(data);
3338

3439
useEffect(() => {
@@ -170,7 +175,7 @@ export const AppProvider = ({ children }: AppProviderProps) => {
170175
return filtered;
171176
}
172177

173-
const value: AppContextType = { data, loading, error, testFiles, transformedReport, filterEndpoints, filteredEndpoints, invalidReportErrors };
178+
const value: AppContextType = { data, loading, error, testFiles, transformedReport, filterEndpoints, filteredEndpoints, invalidReportErrors, lowCodeMode, setLowCodeMode };
174179

175180
return (
176181
<AppContext.Provider value={value}>
Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,48 @@
11
import type React from "react";
22
import {ReportTooltip} from "@/components/ui/report-tooltip.tsx";
3+
import {Switch} from "@/components/ui/switch.tsx";
34
import info from "@/assets/info.json";
5+
import {useAppContext} from "@/AppProvider.tsx";
46

57
interface IHeaderProps {
68
date: string;
79
toolNameVersion: string;
810
schemaVersion: string;
911
}
1012

11-
export const Header: React.FC<IHeaderProps> = ({date, toolNameVersion, schemaVersion}) => (
12-
<>
13-
<div className="justify-between border-b border-black pb-2 mb-4">
14-
<div className="font-extrabold">WEB FUZZING COMMONS</div>
15-
</div>
16-
<div className="flex justify-between border-b border-black pb-2 mb-4">
17-
<ReportTooltip tooltipText={info.creationDate}>
18-
<div className="font-bold" data-testid="header-creation-date">Creation Date: {new Date(date).toUTCString()}</div>
19-
</ReportTooltip>
20-
<ReportTooltip tooltipText={info.toolNameVersion}>
21-
<div className="font-bold text-center" data-testid="header-tool-name-version">Tool: {toolNameVersion}</div>
22-
</ReportTooltip>
23-
<ReportTooltip tooltipText={info.schemaVersion}>
24-
<div className="font-bold text-right" data-testid="header-schema-version">Schema Version: {schemaVersion}</div>
25-
</ReportTooltip>
26-
</div>
27-
</>
28-
)
13+
export const Header: React.FC<IHeaderProps> = ({date, toolNameVersion, schemaVersion}) => {
14+
const {lowCodeMode, setLowCodeMode} = useAppContext();
15+
16+
return (
17+
<>
18+
<div className="flex justify-between items-center border-b border-black pb-2 mb-4">
19+
<div className="font-extrabold">WEB FUZZING COMMONS</div>
20+
<ReportTooltip tooltipText="Show only /** */ documentation comments instead of full test source code.">
21+
<label
22+
htmlFor="low-code-switch"
23+
className="flex items-center gap-2 text-sm font-bold cursor-pointer select-none"
24+
data-testid="header-low-code-toggle"
25+
>
26+
<span>Low-code view</span>
27+
<Switch
28+
id="low-code-switch"
29+
checked={lowCodeMode}
30+
onCheckedChange={setLowCodeMode}
31+
/>
32+
</label>
33+
</ReportTooltip>
34+
</div>
35+
<div className="flex justify-between border-b border-black pb-2 mb-4">
36+
<ReportTooltip tooltipText={info.creationDate}>
37+
<div className="font-bold" data-testid="header-creation-date">Creation Date: {new Date(date).toUTCString()}</div>
38+
</ReportTooltip>
39+
<ReportTooltip tooltipText={info.toolNameVersion}>
40+
<div className="font-bold text-center" data-testid="header-tool-name-version">Tool: {toolNameVersion}</div>
41+
</ReportTooltip>
42+
<ReportTooltip tooltipText={info.schemaVersion}>
43+
<div className="font-bold text-right" data-testid="header-schema-version">Schema Version: {schemaVersion}</div>
44+
</ReportTooltip>
45+
</div>
46+
</>
47+
);
48+
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import * as React from "react"
2+
import { Switch as SwitchPrimitive } from "radix-ui"
3+
4+
import { cn } from "@/lib/utils"
5+
6+
function Switch({
7+
className,
8+
...props
9+
}: React.ComponentProps<typeof SwitchPrimitive.Root>) {
10+
return (
11+
<SwitchPrimitive.Root
12+
data-slot="switch"
13+
className={cn(
14+
"relative peer inline-block h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-black shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-green-500 data-[state=unchecked]:bg-gray-300",
15+
className
16+
)}
17+
{...props}
18+
>
19+
<SwitchPrimitive.Thumb
20+
data-slot="switch-thumb"
21+
className={cn(
22+
"pointer-events-none absolute top-1/2 -translate-y-1/2 block h-4 w-4 rounded-full bg-white shadow-md ring-0 transition-[left] duration-200 data-[state=checked]:left-[22px] data-[state=unchecked]:left-[2px]"
23+
)}
24+
/>
25+
</SwitchPrimitive.Root>
26+
)
27+
}
28+
29+
export { Switch }

web-report/src/lib/utils.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@ export const extractCodeLines = (
7272
return lines.slice(startIndex, endIndex + 2).join('\n');
7373
};
7474

75+
export const extractComments = (code: string): string => {
76+
const blockRegex = /\/\*\*[\s\S]*?\*\//g;
77+
const blocks = code.match(blockRegex);
78+
if (!blocks || blocks.length === 0) {
79+
return "";
80+
}
81+
82+
return blocks
83+
.map(block => {
84+
const inner = block.replace(/^\/\*\*/, "").replace(/\*\/$/, "");
85+
return inner
86+
.split("\n")
87+
.map(line => line.replace(/^\s*\*\s?/, ""))
88+
.join("\n")
89+
.trim();
90+
})
91+
.filter(text => text.length > 0)
92+
.join("\n\n");
93+
};
94+
7595
export const calculateAllStatusCounts = (coveredHttpStatus: CoveredEndpoint[], endpointIds:string[]) => {
7696
const allStatusCounts ={
7797
"NO_RESPONSE": 0,

web-report/src/pages/TestResults.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {Card} from "@/components/ui/card.tsx";
22
import type React from "react";
33
import {Badge} from "@/components/ui/badge.tsx";
44
import {CodeBlock} from "@/components/CodeBlock.tsx";
5-
import {extractCodeLines, getColor, getLanguage} from "@/lib/utils";
5+
import {extractCodeLines, extractComments, getColor, getLanguage} from "@/lib/utils";
66
import {useAppContext} from "@/AppProvider.tsx";
77

88

@@ -12,7 +12,7 @@ interface IProps {
1212

1313
export const TestResults: React.FC<IProps> = ({testCaseName}) => {
1414

15-
const {data, testFiles} = useAppContext();
15+
const {data, testFiles, lowCodeMode} = useAppContext();
1616

1717
const testCases = data?.testCases || [];
1818
const foundFaults = data?.faults.foundFaults || [];
@@ -42,6 +42,8 @@ export const TestResults: React.FC<IProps> = ({testCaseName}) => {
4242

4343

4444
const extractedCode = currentFile && testCase ? extractCodeLines(currentFile.code, testCase?.startLine, testCase?.endLine) : "";
45+
const displayedCode = lowCodeMode ? extractComments(extractedCode) : extractedCode;
46+
const displayedLanguage = lowCodeMode ? "markdown" : getLanguage(currentFile?.name ?? "");
4547

4648
return (
4749
<div className="border-2 border-black p-6 rounded-none w-[80%] mx-auto">
@@ -97,7 +99,11 @@ export const TestResults: React.FC<IProps> = ({testCaseName}) => {
9799
{
98100
testCase && currentFile && (
99101
<pre className="p-4 overflow-auto max-h-[500px] text-sm text-left font-mono">
100-
<CodeBlock content={extractedCode} language={getLanguage(currentFile?.name)}/>
102+
{lowCodeMode && displayedCode.length === 0 ? (
103+
<div className="text-gray-600 italic">No documentation comments found for this test case.</div>
104+
) : (
105+
<CodeBlock content={displayedCode} language={displayedLanguage}/>
106+
)}
101107
</pre>
102108
)
103109
}

0 commit comments

Comments
 (0)