Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1,316 changes: 889 additions & 427 deletions web-report/package-lock.json

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions web-report/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,26 @@
"generate": "json2ts ../src/main/resources/wfc/schemas/report.yaml src/types/GeneratedTypes.tsx && ts-to-zod src/types/GeneratedTypes.tsx src/types/GeneratedTypesZod.ts",
"build": "tsc -b && vite build",
"installAndBuild": "npm install && npm run generate && vitest --no-watch && tsc -b && vite build && npm run copyRunFiles",
"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'",
"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\"",
"lint": "eslint .",
"preview": "vite preview",
"debug": "vite build && cpx 'src-e2e/static/*' '../target/classes/webreport' && vite preview",
"debug": "vite build && cpx \"src-e2e/static/*\" \"../target/classes/webreport\" && vite preview",
"test": "vitest"
},
"dependencies": {
"@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-progress": "^1.1.3",
"@radix-ui/react-scroll-area": "^1.2.3",
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-tooltip": "^1.2.7",
"@tailwindcss/vite": "^4.0.14",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"json-schema-to-typescript": "^15.0.4",
"lucide-react": "^0.483.0",
"radix-ui": "^1.4.3",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-syntax-highlighter": "^15.6.1",
Expand All @@ -36,13 +38,13 @@
"zod": "^3.25.67"
},
"optionalDependencies": {
"@esbuild/darwin-arm64": "0.19.12",
"@tailwindcss/oxide-linux-arm64-gnu": "^4.0.1",
"@tailwindcss/oxide-linux-arm64-musl": "^4.0.1",
"@tailwindcss/oxide-linux-x64-musl": "^4.0.1",
"lightningcss-linux-arm64-gnu": "^1.29.1",
"lightningcss-linux-arm64-musl": "^1.29.1",
"lightningcss-linux-x64-musl": "^1.29.1",
"@esbuild/darwin-arm64": "0.19.12"
"lightningcss-linux-x64-musl": "^1.29.1"
},
"devDependencies": {
"@eslint/js": "^9.21.0",
Expand Down
7 changes: 6 additions & 1 deletion web-report/src/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type AppContextType = {
filterEndpoints: (activeFilters: Record<number, string>) => ITransformedReport[];
filteredEndpoints: ITransformedReport[];
invalidReportErrors: ZodIssue[] | null;
lowCodeMode: boolean;
setLowCodeMode: (v: boolean) => void;
};

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

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

const initialLowCode = (window as unknown as { __WFC_LOW_CODE__?: boolean }).__WFC_LOW_CODE__ === true;

const [data, setData] = useState<WebFuzzingCommonsReport | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [invalidReportErrors, setInvalidReportErrors] = useState<ZodIssue[] | null>(null);
const [testFiles, setTestFiles] = useState<ITestFiles[]>([]);
const [lowCodeMode, setLowCodeMode] = useState<boolean>(initialLowCode);
const transformedReport = transformWebFuzzingReport(data);

useEffect(() => {
Expand Down Expand Up @@ -170,7 +175,7 @@ export const AppProvider = ({ children }: AppProviderProps) => {
return filtered;
}

const value: AppContextType = { data, loading, error, testFiles, transformedReport, filterEndpoints, filteredEndpoints, invalidReportErrors };
const value: AppContextType = { data, loading, error, testFiles, transformedReport, filterEndpoints, filteredEndpoints, invalidReportErrors, lowCodeMode, setLowCodeMode };

return (
<AppContext.Provider value={value}>
Expand Down
56 changes: 38 additions & 18 deletions web-report/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,48 @@
import type React from "react";
import {ReportTooltip} from "@/components/ui/report-tooltip.tsx";
import {Switch} from "@/components/ui/switch.tsx";
import info from "@/assets/info.json";
import {useAppContext} from "@/AppProvider.tsx";

interface IHeaderProps {
date: string;
toolNameVersion: string;
schemaVersion: string;
}

export const Header: React.FC<IHeaderProps> = ({date, toolNameVersion, schemaVersion}) => (
<>
<div className="justify-between border-b border-black pb-2 mb-4">
<div className="font-extrabold">WEB FUZZING COMMONS</div>
</div>
<div className="flex justify-between border-b border-black pb-2 mb-4">
<ReportTooltip tooltipText={info.creationDate}>
<div className="font-bold" data-testid="header-creation-date">Creation Date: {new Date(date).toUTCString()}</div>
</ReportTooltip>
<ReportTooltip tooltipText={info.toolNameVersion}>
<div className="font-bold text-center" data-testid="header-tool-name-version">Tool: {toolNameVersion}</div>
</ReportTooltip>
<ReportTooltip tooltipText={info.schemaVersion}>
<div className="font-bold text-right" data-testid="header-schema-version">Schema Version: {schemaVersion}</div>
</ReportTooltip>
</div>
</>
)
export const Header: React.FC<IHeaderProps> = ({date, toolNameVersion, schemaVersion}) => {
const {lowCodeMode, setLowCodeMode} = useAppContext();

return (
<>
<div className="flex justify-between items-center border-b border-black pb-2 mb-4">
<div className="font-extrabold">WEB FUZZING COMMONS</div>
<ReportTooltip tooltipText="Show only /** */ documentation comments instead of full test source code.">
<label
htmlFor="low-code-switch"
className="flex items-center gap-2 text-sm font-bold cursor-pointer select-none"
data-testid="header-low-code-toggle"
>
<span>Low-code view</span>
<Switch
id="low-code-switch"
checked={lowCodeMode}
onCheckedChange={setLowCodeMode}
/>
</label>
</ReportTooltip>
</div>
<div className="flex justify-between border-b border-black pb-2 mb-4">
<ReportTooltip tooltipText={info.creationDate}>
<div className="font-bold" data-testid="header-creation-date">Creation Date: {new Date(date).toUTCString()}</div>
</ReportTooltip>
<ReportTooltip tooltipText={info.toolNameVersion}>
<div className="font-bold text-center" data-testid="header-tool-name-version">Tool: {toolNameVersion}</div>
</ReportTooltip>
<ReportTooltip tooltipText={info.schemaVersion}>
<div className="font-bold text-right" data-testid="header-schema-version">Schema Version: {schemaVersion}</div>
</ReportTooltip>
</div>
</>
);
};
29 changes: 29 additions & 0 deletions web-report/src/components/ui/switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from "react"
import { Switch as SwitchPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"

function Switch({
className,
...props
}: React.ComponentProps<typeof SwitchPrimitive.Root>) {
return (
<SwitchPrimitive.Root
data-slot="switch"
className={cn(
"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",
className
)}
{...props}
>
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className={cn(
"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]"
)}
/>
</SwitchPrimitive.Root>
)
}

export { Switch }
20 changes: 20 additions & 0 deletions web-report/src/lib/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,26 @@ export const extractCodeLines = (
return lines.slice(startIndex, endIndex + 2).join('\n');
};

export const extractComments = (code: string): string => {
const blockRegex = /\/\*\*[\s\S]*?\*\//g;
const blocks = code.match(blockRegex);
if (!blocks || blocks.length === 0) {
return "";
}

return blocks
.map(block => {
const inner = block.replace(/^\/\*\*/, "").replace(/\*\/$/, "");
return inner
.split("\n")
.map(line => line.replace(/^\s*\*\s?/, ""))
.join("\n")
.trim();
})
.filter(text => text.length > 0)
.join("\n\n");
};

export const calculateAllStatusCounts = (coveredHttpStatus: CoveredEndpoint[], endpointIds:string[]) => {
const allStatusCounts ={
"NO_RESPONSE": 0,
Expand Down
12 changes: 9 additions & 3 deletions web-report/src/pages/TestResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Card} from "@/components/ui/card.tsx";
import type React from "react";
import {Badge} from "@/components/ui/badge.tsx";
import {CodeBlock} from "@/components/CodeBlock.tsx";
import {extractCodeLines, getColor, getLanguage} from "@/lib/utils";
import {extractCodeLines, extractComments, getColor, getLanguage} from "@/lib/utils";
import {useAppContext} from "@/AppProvider.tsx";


Expand All @@ -12,7 +12,7 @@ interface IProps {

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

const {data, testFiles} = useAppContext();
const {data, testFiles, lowCodeMode} = useAppContext();

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


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

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