Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
emma-sg committed Mar 11, 2024
1 parent e8ba868 commit 197d741
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 157 deletions.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"postinstall-postinstall": "^2.1.0",
"prettier": "^3.2.4",
"pretty-ms": "^7.0.1",
"proxy-memoize": "^2.0.5",
"query-string": "^8.1.0",
"regex-colorize": "^0.0.3",
"slugify": "^1.6.6",
Expand Down
97 changes: 69 additions & 28 deletions frontend/src/features/qa/page-list/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,47 @@
import { tw } from "@/utils/tailwind";
import { html } from "lit";
import { clsx } from "clsx";
import type { ArchivedItemPage } from "@/types/crawler";
import { cached } from "@/utils/weakCache";

export type Severity = "severe" | "moderate" | "good" | null;

export const severityFromMatch = (
match: number | undefined | null,
): Severity => {
if (match == null) return null;
// TODO extract configs for match thresholds
if (match < 50) return "severe";
if (match < 90) return "moderate";
return "good";
export const composeWithRunId = <T>(
fn: (page: ArchivedItemPage, runId: string) => T,
runId: string,
) => {
return (page: ArchivedItemPage) => fn(page, runId);
};

export const severityFromResourceCounts = (
bad: number | undefined,
good: number | undefined,
): Severity => {
if (bad == null || good == null) return null;
// TODO extract configs for resource count thresholds
const total = bad + good;
if (bad > 10 || bad / total > 0.5) return "severe";
if (bad > 0) return "moderate";
return "good";
};
export const severityFromMatch = cached(
(match: number | undefined | null): Severity => {
if (match == null) return null;
// TODO extract configs for match thresholds
if (match < 50) return "severe";
if (match < 90) return "moderate";
return "good";
},
);

export const crawlCounts = (
bad: number | undefined | null,
good: number | undefined | null,
) => {
if (bad == null || good == null) return null;
return `${good}/${good + bad}`;
};
export const severityFromResourceCounts = cached(
(bad: number | undefined, good: number | undefined): Severity => {
if (bad == null || good == null) return null;
// TODO extract configs for resource count thresholds
const total = bad + good;
if (bad > 10 || bad / total > 0.5) return "severe";
if (bad > 0) return "moderate";
return "good";
},
);

export const crawlCounts = cached(
(bad: number | undefined | null, good: number | undefined | null) => {
if (bad == null || good == null) return null;
return `${good}/${good + bad}`;
},
);

export const severityIcon = (severity: Severity, classList?: string) => {
export const severityIcon = cached((severity: Severity, classList?: string) => {
const baseClasses = tw`h-4 w-4`;
switch (severity) {
case "severe":
Expand All @@ -58,4 +65,38 @@ export const severityIcon = (severity: Severity, classList?: string) => {
class=${clsx("text-gray-600", baseClasses, classList)}
></sl-icon>`;
}
};
});

export const issueCounts = cached((page: ArchivedItemPage, runId: string) => {
const severities = [
severityFromMatch(page.screenshotMatch?.[runId]),
severityFromMatch(page.textMatch?.[runId]),
severityFromResourceCounts(
page.resourceCounts?.[runId]?.crawlBad,
page.resourceCounts?.[runId]?.crawlGood,
),
severityFromResourceCounts(
page.resourceCounts?.[runId]?.replayBad,
page.resourceCounts?.[runId]?.replayGood,
),
];
let severe = 0,
moderate = 0;
for (const severity of severities) {
if (severity === "severe") {
severe++;
} else if (severity === "moderate") {
moderate++;
}
}
return { severe, moderate };
});

export const maxSeverity = cached(
(page: ArchivedItemPage, runId: string): NonNullable<Severity> => {
const { severe, moderate } = issueCounts(page, runId);
if (severe > 0) return "severe";
if (moderate > 0) return "moderate";
return "good";
},
);
69 changes: 24 additions & 45 deletions frontend/src/features/qa/page-list/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,15 @@ import { css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
import { GroupedList, remainder } from "../../../components/ui/grouped-list";

import {
calculateSeverityFromDatum,
errorsFromDatum,
testData,
} from "./test-data";
import { testData } from "./test-data";
import { pageDetails } from "./page-details";
import type { SlTreeItem } from "@shoelace-style/shoelace";

// import { setDefaultAnimation } from "@shoelace-style/shoelace/dist/utilities/animation-registry.js";

// // Change the default animation for all dialogs
// setDefaultAnimation("tree-item.collapse", {
// keyframes: [],
// options: {
// duration: 0,
// },
// });
import {
composeWithRunId,
issueCounts,
maxSeverity,
severityIcon,
} from "./helpers";

type SearchFields = "name" | "issues";

Expand Down Expand Up @@ -199,36 +191,23 @@ export class PageList extends TailwindElement {
${items}
</sl-tree-item>`,
renderItem: (datum) =>
html`<sl-tree-item class="is-leaf my-4">
html`<sl-tree-item
class="is-leaf -my-4 py-4 [contain:content] [content-visibility:auto] first-of-type:mt-0 last-of-type:mb-0"
>
<div
class="absolute -left-4 top-[50%] flex w-8 translate-y-[-50%] flex-col place-items-center gap-1 rounded-full border border-gray-300 bg-neutral-0 p-2 shadow-sm"
>
${{
severe: html`<sl-icon
name="exclamation-triangle-fill"
class="text-red-600"
></sl-icon>`,
moderate: html`<sl-icon
name="dash-square-fill"
class="text-yellow-600"
></sl-icon>`,
good: html`<sl-icon
name="check-circle-fill"
class="text-green-600"
></sl-icon>`,
}[calculateSeverityFromDatum(datum, this.qaRunId)]}
${errorsFromDatum(datum, this.qaRunId).severeErrors > 1
${severityIcon(maxSeverity(datum, this.qaRunId))}
${issueCounts(datum, this.qaRunId).severe > 1
? html`<span class="text-[10px] font-semibold text-red-600"
>+${errorsFromDatum(datum, this.qaRunId).severeErrors -
1}</span
>`
: nothing}
${errorsFromDatum(datum, this.qaRunId).moderateErrors > 1
? html`<span class="text-[10px] font-semibold text-yellow-600"
>+${errorsFromDatum(datum, this.qaRunId).moderateErrors -
1}</span
>+${issueCounts(datum, this.qaRunId).severe - 1}</span
>`
: nothing}
: issueCounts(datum, this.qaRunId).moderate > 1
? html`<span
class="text-[10px] font-semibold text-yellow-600"
>+${issueCounts(datum, this.qaRunId).moderate - 1}</span
>`
: nothing}
${datum.notes?.[0] &&
html`<sl-icon
name="chat-square-text-fill"
Expand All @@ -242,12 +221,12 @@ export class PageList extends TailwindElement {
>
</sl-tree-item>`,
sortBy: (a, b) =>
errorsFromDatum(b, this.qaRunId).severeErrors -
errorsFromDatum(a, this.qaRunId).severeErrors ||
errorsFromDatum(b, this.qaRunId).moderateErrors -
errorsFromDatum(a, this.qaRunId).moderateErrors,
issueCounts(b, this.qaRunId).severe -
issueCounts(a, this.qaRunId).severe ||
issueCounts(b, this.qaRunId).moderate -
issueCounts(a, this.qaRunId).moderate,
groupBy: {
value: (d) => calculateSeverityFromDatum(d, this.qaRunId),
value: composeWithRunId(maxSeverity, this.qaRunId),
groups: [
{
value: "severe",
Expand Down
84 changes: 0 additions & 84 deletions frontend/src/features/qa/page-list/test-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,87 +147,3 @@ export const testData = shuffle([
// replayResources: [12, 12],
// },
]);

export function calculateSeverityFromDatum(
datum: ArchivedItemPage,
runId: string,
): "severe" | "moderate" | "good" {
// Severe
if (
(datum.screenshotMatch?.[runId] && datum.screenshotMatch[runId] < 50) ||
(datum.textMatch?.[runId] && datum.textMatch[runId] < 50) ||
(datum.resourceCounts?.[runId]?.crawlBad != null &&
datum.resourceCounts[runId].crawlGood != null &&
datum.resourceCounts[runId].crawlBad! <
datum.resourceCounts[runId].crawlBad! - 2) ||
(datum.resourceCounts?.[runId]?.replayBad != null &&
datum.resourceCounts[runId].replayGood != null &&
datum.resourceCounts[runId].replayBad! <
datum.resourceCounts[runId].replayBad! - 2)
) {
return "severe";
}

// Moderate
if (
(datum.screenshotMatch?.[runId] && datum.screenshotMatch[runId] < 100) ||
(datum.textMatch?.[runId] && datum.textMatch[runId] < 100) ||
(datum.resourceCounts?.[runId]?.crawlBad != null &&
datum.resourceCounts[runId].crawlGood != null &&
datum.resourceCounts[runId].crawlBad! <
datum.resourceCounts[runId].crawlBad!) ||
(datum.resourceCounts?.[runId]?.replayBad != null &&
datum.resourceCounts[runId].replayGood != null &&
datum.resourceCounts[runId].replayBad! <
datum.resourceCounts[runId].replayBad!)
) {
return "moderate";
}

return "good";
}

export function errorsFromDatum(datum: ArchivedItemPage, runId: string) {
let severeErrors = 0,
moderateErrors = 0;
if (datum.screenshotMatch?.[runId] && datum.screenshotMatch[runId] < 50)
severeErrors++;
if (datum.textMatch?.[runId] && datum.textMatch[runId] < 50) severeErrors++;
if (
datum.resourceCounts?.[runId]?.crawlBad != null &&
datum.resourceCounts[runId].crawlGood != null &&
datum.resourceCounts[runId].crawlBad! <
datum.resourceCounts[runId].crawlBad! - 2
)
severeErrors++;
if (
datum.resourceCounts?.[runId]?.replayBad != null &&
datum.resourceCounts[runId].replayGood != null &&
datum.resourceCounts[runId].replayBad! <
datum.resourceCounts[runId].replayBad! - 2
)
severeErrors++;
if (severeErrors > 1) {
return { severeErrors, moderateErrors: 0 };
}
if (datum.screenshotMatch?.[runId] && datum.screenshotMatch[runId] < 100)
moderateErrors++;
if (datum.textMatch?.[runId] && datum.textMatch[runId] < 100)
moderateErrors++;
if (
datum.resourceCounts?.[runId]?.crawlBad != null &&
datum.resourceCounts[runId].crawlGood != null &&
datum.resourceCounts[runId].crawlBad! <
datum.resourceCounts[runId].crawlBad!
)
moderateErrors++;
if (
datum.resourceCounts?.[runId]?.replayBad != null &&
datum.resourceCounts[runId].replayGood != null &&
datum.resourceCounts[runId].replayBad! <
datum.resourceCounts[runId].replayBad!
)
moderateErrors++;

return { moderateErrors, severeErrors: 0 };
}
35 changes: 35 additions & 0 deletions frontend/src/utils/weakCache.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-base-to-string */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
import { fake } from "sinon";
import { expect } from "@esm-bundle/chai";
// import { WeakRefMap, cached, innerCache } from "./weakCache";
import { memoize } from "proxy-memoize";
// describe("WeakRefMap", () => {
// it("allows saving and retrieving from cache", () => {
// const cache = new WeakRefMap<object, object>();
// const objs = { key: { a: 1 }, value: { b: 2 } } as {
// key: { a: 1 };
// value?: { b: 2 };
// };
// cache.add(objs.key, objs.value!);
// expect(cache.get(objs.key) === objs.value);
// delete objs.value;
// expect(cache.get(objs.key) === objs.value);
// });
// });

describe("cached helper function", () => {
it.only("caches the result of a long computation", () => {
let b = 0;
const expensiveCalculation = fake((obj: object) => ({
...obj,
b: ++b,
}));
const cachedFn = memoize(expensiveCalculation);
const key = { a: 1 };
const res = [cachedFn(key), cachedFn(key), cachedFn(key)];
console.log(res);
expect(expensiveCalculation.callCount).to.equal(1);
});
});
Loading

0 comments on commit 197d741

Please sign in to comment.