From 5923f63fd4a8f9148932b78ece9a15b6b3ffffe7 Mon Sep 17 00:00:00 2001 From: Dmitrii Evreinov Date: Tue, 1 Sep 2026 12:47:54 +0400 Subject: [PATCH 1/8] resolutions ui --- packages/core-api/src/model.ts | 1 + packages/core/src/store/store.ts | 1 + packages/core/test/store/store.test.ts | 14 +- packages/plugin-api/src/report.ts | 44 ++++- packages/plugin-awesome/src/converters.ts | 2 + packages/plugin-awesome/src/generators.ts | 81 +++++++- packages/plugin-awesome/src/plugin.ts | 27 ++- .../plugin-awesome/test/generators.test.ts | 177 +++++++++++++++++- packages/plugin-awesome/test/plugin.test.ts | 114 +++++++++++ .../Categories/CategoryTreeItem/index.tsx | 1 + .../src/components/HotkeysProvider/index.tsx | 20 +- .../KeyboardShortcuts/shortcutsConfig.ts | 10 +- .../src/components/MainReport/index.tsx | 21 +++ .../ReportFilters/ResolutionFilter.tsx | 54 ++++++ .../src/components/ReportFilters/index.tsx | 6 + .../ReportResolutionCategories/index.tsx | 29 +++ .../ReportResolutionCategories/styles.scss | 6 + .../ResolutionCategoriesList/index.tsx | 146 +++++++++++++++ .../ResolutionCategoriesList/styles.scss | 82 ++++++++ .../TestResult/TrInfo/TrInfoStatuses.tsx | 1 - .../components/TestResult/TrInfo/index.tsx | 12 +- .../TestResult/TrNavigation/index.tsx | 5 +- .../TrResolutionCategories/index.tsx | 24 +++ .../components/TestResult/TrTabs/index.tsx | 5 +- .../src/components/TestResult/index.tsx | 7 +- packages/web-awesome/src/index.tsx | 3 + packages/web-awesome/src/locales/ar.json | 33 +++- packages/web-awesome/src/locales/az.json | 33 +++- packages/web-awesome/src/locales/de.json | 33 +++- packages/web-awesome/src/locales/en.json | 33 +++- packages/web-awesome/src/locales/es.json | 33 +++- packages/web-awesome/src/locales/fr.json | 33 +++- packages/web-awesome/src/locales/he.json | 33 +++- packages/web-awesome/src/locales/hy.json | 33 +++- packages/web-awesome/src/locales/it.json | 33 +++- packages/web-awesome/src/locales/ja.json | 33 +++- packages/web-awesome/src/locales/ka.json | 33 +++- packages/web-awesome/src/locales/kr.json | 33 +++- packages/web-awesome/src/locales/nl.json | 33 +++- packages/web-awesome/src/locales/pl.json | 33 +++- packages/web-awesome/src/locales/pt.json | 33 +++- packages/web-awesome/src/locales/ru.json | 33 +++- packages/web-awesome/src/locales/sv.json | 33 +++- packages/web-awesome/src/locales/tr.json | 33 +++- packages/web-awesome/src/locales/uk.json | 33 +++- packages/web-awesome/src/locales/zh-TW.json | 33 +++- packages/web-awesome/src/locales/zh.json | 33 +++- packages/web-awesome/src/stores/chart.ts | 14 +- .../web-awesome/src/stores/keyboardActions.ts | 13 +- .../web-awesome/src/stores/reportRootTabs.ts | 19 +- .../src/stores/resolutionCategories.ts | 62 ++++++ packages/web-awesome/src/stores/router.ts | 2 +- .../web-awesome/src/stores/testResultTabs.ts | 88 ++++++++- .../src/stores/treeFilters/actions.ts | 10 +- .../src/stores/treeFilters/constants.ts | 4 +- .../src/stores/treeFilters/model.ts | 3 +- .../src/stores/treeFilters/store.ts | 79 ++++++-- .../src/stores/treeFilters/utils.ts | 19 +- packages/web-awesome/src/utils/tree.ts | 1 + .../test/components/ReportFilters.test.tsx | 5 + .../components/ResolutionCategories.test.tsx | 163 ++++++++++++++++ .../test/components/TrNavigation.test.tsx | 49 +++++ packages/web-awesome/test/index.test.tsx | 7 + .../stores/keyboard/keyboardActions.test.ts | 127 ++++++++++++- .../test/stores/treeFilters/actions.test.ts | 3 +- .../test/stores/treeFilters/store.test.ts | 69 +++++++ .../test/stores/treeFilters/utils.test.ts | 12 +- packages/web-awesome/test/utils/tree.test.ts | 19 ++ packages/web-awesome/types.d.ts | 7 +- packages/web-components/global.d.ts | 18 +- .../assets/svg/line-general-check-circle.svg | 2 +- .../src/assets/svg/line-general-eye.svg | 4 +- .../src/components/SvgIcon/SvgIcon.test.tsx | 20 +- .../src/components/Tree/Tree.tsx | 1 + .../src/components/Tree/TreeItem.test.tsx | 22 +++ .../src/components/Tree/TreeItem.tsx | 13 +- .../Tree/TreeItemInfo/TreeItemInfo.test.tsx | 16 ++ .../components/Tree/TreeItemInfo/index.tsx | 15 +- .../src/components/Tree/styles.scss | 6 + 79 files changed, 2249 insertions(+), 229 deletions(-) create mode 100644 packages/web-awesome/src/components/ReportFilters/ResolutionFilter.tsx create mode 100644 packages/web-awesome/src/components/ReportResolutionCategories/index.tsx create mode 100644 packages/web-awesome/src/components/ReportResolutionCategories/styles.scss create mode 100644 packages/web-awesome/src/components/ResolutionCategoriesList/index.tsx create mode 100644 packages/web-awesome/src/components/ResolutionCategoriesList/styles.scss create mode 100644 packages/web-awesome/src/components/TestResult/TrResolutionCategories/index.tsx create mode 100644 packages/web-awesome/src/stores/resolutionCategories.ts create mode 100644 packages/web-awesome/test/components/ResolutionCategories.test.tsx create mode 100644 packages/web-awesome/test/stores/treeFilters/store.test.ts create mode 100644 packages/web-awesome/test/utils/tree.test.ts create mode 100644 packages/web-components/src/components/Tree/TreeItem.test.tsx create mode 100644 packages/web-components/src/components/Tree/TreeItemInfo/TreeItemInfo.test.tsx diff --git a/packages/core-api/src/model.ts b/packages/core-api/src/model.ts index d5966f604ec..7d43dd185ff 100644 --- a/packages/core-api/src/model.ts +++ b/packages/core-api/src/model.ts @@ -61,6 +61,7 @@ export interface TestResult { flaky: boolean; muted: boolean; resolution?: ResolutionCategory; + resolutionComment?: string; transition?: TestStatusTransition; diff --git a/packages/core/src/store/store.ts b/packages/core/src/store/store.ts index 62f904f9dfa..468700d2c9b 100644 --- a/packages/core/src/store/store.ts +++ b/packages/core/src/store/store.ts @@ -473,6 +473,7 @@ export class DefaultAllureStore implements AllureStore, ResultsVisitor { const rule = getResolutionByRules(testResult, this.#resolutionsConfig); testResult.resolution = rule?.resolution; + testResult.resolutionComment = rule?.comment; this.#removeResolutionIssueAssociation(testResult.id); diff --git a/packages/core/test/store/store.test.ts b/packages/core/test/store/store.test.ts index 443b8134898..5bf9d59ef32 100644 --- a/packages/core/test/store/store.test.ts +++ b/packages/core/test/store/store.test.ts @@ -275,6 +275,7 @@ describe("test results", () => { { resolution: "issue", issue: { id: "SHOP-1", type: "jira" }, + comment: "Tracked defect", testCaseId: [md5("tc-1")], messageRegexp: "tracked defect", }, @@ -308,12 +309,19 @@ describe("test results", () => { const issueResult = testResults.find((tr) => tr.name === "issue by rule")!; expect(issueResult.resolution).toBe("issue"); + expect(issueResult.resolutionComment).toBe("Tracked defect"); expect(issueResult.links).toEqual([]); - expect(testResults.find((tr) => tr.name === "muted by rule")?.resolution).toBe("muted"); - expect(testResults.find((tr) => tr.name === "accepted by rule")?.resolution).toBe("accepted"); + expect(testResults.find((tr) => tr.name === "muted by rule")).toMatchObject({ + resolution: "muted", + resolutionComment: "noise", + }); + expect(testResults.find((tr) => tr.name === "accepted by rule")).toMatchObject({ + resolution: "accepted", + resolutionComment: "Accepted risk", + }); expect(testResults.find((tr) => tr.name === "passed")?.resolution).toBeUndefined(); expect(blockingFailed).toEqual([issueResult]); - expect(resolutionIssues).toEqual([{ id: "SHOP-1", type: "jira" }]); + expect(resolutionIssues).toEqual([{ id: "SHOP-1", type: "jira", comment: "Tracked defect" }]); await expect(store.resolutionIssueByTestResultId(issueResult.id)).resolves.toEqual(resolutionIssues[0]); await expect(store.testResultsByResolutionIssueId("SHOP-1")).resolves.toEqual([issueResult]); }); diff --git a/packages/plugin-api/src/report.ts b/packages/plugin-api/src/report.ts index 552a83b67c2..2cfec224ec6 100644 --- a/packages/plugin-api/src/report.ts +++ b/packages/plugin-api/src/report.ts @@ -3,6 +3,8 @@ import type { CiDescriptor, DefaultTreeGroup, HistoryTestResult, + ResolutionCategory, + ResolutionIssue, TestFixtureResult, TestResult, TestStatus, @@ -107,6 +109,7 @@ export type ReportTestResult = Omit< retry: boolean; categories?: ReportCategory[]; environment?: string | "default"; + resolutionIssue?: ResolutionIssue; tooltips?: Record; time?: Record; extra?: { severity: string }; @@ -114,7 +117,16 @@ export type ReportTestResult = Omit< export type ReportTreeLeaf = Pick< ReportTestResult, - "duration" | "name" | "start" | "status" | "groupOrder" | "flaky" | "transition" | "retry" | "retriesCount" + | "duration" + | "name" + | "start" + | "status" + | "groupOrder" + | "flaky" + | "transition" + | "retry" + | "retriesCount" + | "resolution" > & { nodeId: string; id?: string; @@ -149,6 +161,36 @@ export type ReportSearchDocument = { links?: string; }; +export type ReportResolutionTestResult = Pick< + ReportTreeLeaf, + | "nodeId" + | "id" + | "name" + | "status" + | "duration" + | "flaky" + | "transition" + | "retry" + | "retriesCount" + | "resolution" + | "tooltips" +> & { + groupOrder?: number; +}; + +export type ReportResolutionGroup = { + id: string; + resolution: ResolutionCategory; + name: string; + comment?: string; + issue?: ResolutionIssue; + testResults: ReportResolutionTestResult[]; +}; + +export type ReportResolutionCategories = { + groups: ReportResolutionGroup[]; +}; + /** * Tree which contains tree leaves instead of their IDs and recursive trees structure instead of groups. */ diff --git a/packages/plugin-awesome/src/converters.ts b/packages/plugin-awesome/src/converters.ts index 435b18bebf4..83dd23858a5 100644 --- a/packages/plugin-awesome/src/converters.ts +++ b/packages/plugin-awesome/src/converters.ts @@ -45,6 +45,8 @@ export const convertTestResult = ( historyId: tr.historyId, flaky: tr.flaky, muted: tr.muted, + resolution: tr.resolution, + resolutionComment: tr.resolutionComment, isRetry: tr.isRetry, labels, groupedLabels: mapLabelsByName(labels), diff --git a/packages/plugin-awesome/src/generators.ts b/packages/plugin-awesome/src/generators.ts index c810c7c6f92..1d185c7d971 100644 --- a/packages/plugin-awesome/src/generators.ts +++ b/packages/plugin-awesome/src/generators.ts @@ -6,6 +6,7 @@ import { type EnvironmentIdentity, type EnvironmentItem, type MetricSample, + type ResolutionCategory, type Statistic, type TestEnvGroup, type TestLabel, @@ -46,6 +47,9 @@ import type { QualityGateValidationResult, ReportFiles, ResultFile, + ReportResolutionCategories, + ReportResolutionGroup, + ReportResolutionTestResult, } from "@allurereport/plugin-api"; import { collapseTreeGroups, @@ -170,6 +174,7 @@ export const generateTestResults = async ( const convertedTr: ReportTestResult = convertTestResult(tr, { hideLabels: options.hideLabels, }); + const resolutionIssue = await store.resolutionIssueByTestResultId(tr.id); convertedTr.history = related.historyByTrId.get(tr.id) ?? []; convertedTr.retries = related.retriesByTrId.get(tr.id) ?? []; @@ -185,6 +190,7 @@ export const generateTestResults = async ( type: "attachment", })); convertedTr.breadcrumbs = createBreadcrumbs(convertedTr); + convertedTr.resolutionIssue = resolutionIssue; convertedTrs.push(convertedTr); } @@ -454,6 +460,7 @@ const leafFactory = ({ start, retry, retriesCount, + resolution, transition, tooltips, historyId, @@ -470,6 +477,7 @@ const leafFactory = ({ start, retry, retriesCount, + resolution, transition, tooltips, }; @@ -485,6 +493,68 @@ const leafFactory = ({ return leaf; }; +const resolutionOrder: ResolutionCategory[] = ["issue", "muted", "accepted"]; + +const getResolutionGroupName = (test: ReportTestResult): string => { + if (test.resolution === "issue") { + return test.resolutionIssue?.id ?? test.resolution; + } + + return test.resolutionComment ?? test.resolution ?? ""; +}; + +const resolutionTestResultFactory = (test: ReportTestResult, index: number): ReportResolutionTestResult => ({ + nodeId: test.id, + id: test.historyId ?? test.id, + name: test.name, + status: test.status, + duration: test.duration, + flaky: test.flaky, + transition: test.transition, + retry: test.retry, + retriesCount: test.retriesCount, + resolution: test.resolution, + groupOrder: index + 1, + tooltips: test.tooltips, +}); + +export const generateResolutionCategories = async ( + writer: AwesomeDataWriter, + tests: ReportTestResult[], + filename = "resolution-categories.json", +) => { + const groupsById = new Map(); + + tests + .filter((test) => !test.isRetry && test.resolution) + .forEach((test) => { + const resolution = test.resolution!; + const groupId = + resolution === "issue" + ? `${resolution}:${test.resolutionIssue?.id ?? test.id}` + : `${resolution}:${test.resolutionComment ?? test.id}`; + const group = groupsById.get(groupId) ?? { + id: groupId, + resolution, + name: getResolutionGroupName(test), + comment: test.resolutionComment ?? test.resolutionIssue?.comment, + issue: test.resolutionIssue, + testResults: [], + }; + + group.testResults.push(resolutionTestResultFactory(test, group.testResults.length)); + groupsById.set(groupId, group); + }); + + const groups = [...groupsById.values()].sort((a, b) => { + const resolutionDiff = resolutionOrder.indexOf(a.resolution) - resolutionOrder.indexOf(b.resolution); + + return resolutionDiff || a.name.localeCompare(b.name); + }); + + await writer.writeWidget(filename, { groups } satisfies ReportResolutionCategories); +}; + export const generateEnvironmentJson = async (writer: AwesomeDataWriter, env: EnvironmentItem[]) => { await writer.writeWidget("allure_environment.json", env); }; @@ -513,13 +583,15 @@ export const generateStatistic = async ( data: { stats: Statistic; statsByEnv: Map; + pieStats?: Statistic; + pieStatsByEnv?: Map; envs: EnvironmentIdentity[]; }, ) => { - const { stats, statsByEnv, envs } = data; + const { stats, statsByEnv, pieStats = stats, pieStatsByEnv, envs } = data; await writer.writeWidget("statistic.json", stats); - await writer.writeWidget("pie_chart.json", getPieChartValues(stats)); + await writer.writeWidget("pie_chart.json", getPieChartValues(pieStats)); for (const env of envs) { const envStats = statsByEnv.get(env.id); @@ -529,7 +601,10 @@ export const generateStatistic = async ( } await writer.writeWidget(joinPosixPath(env.id, "statistic.json"), envStats); - await writer.writeWidget(joinPosixPath(env.id, "pie_chart.json"), envStats); + await writer.writeWidget( + joinPosixPath(env.id, "pie_chart.json"), + getPieChartValues(pieStatsByEnv?.get(env.id) ?? envStats), + ); } }; diff --git a/packages/plugin-awesome/src/plugin.ts b/packages/plugin-awesome/src/plugin.ts index 8fb7a3bb356..f9246e0a174 100644 --- a/packages/plugin-awesome/src/plugin.ts +++ b/packages/plugin-awesome/src/plugin.ts @@ -1,4 +1,10 @@ -import { incrementStatistic, type EnvironmentItem, type Statistic, joinPosixPath } from "@allurereport/core-api"; +import { + incrementStatistic, + type EnvironmentItem, + type Statistic, + type TestResult, + joinPosixPath, +} from "@allurereport/core-api"; import { type AllureStore, type ReportExecutorInfo, @@ -21,6 +27,7 @@ import { generateMetricsWidget, generateNav, generateQualityGateResults, + generateResolutionCategories, generateSearchIndex, generateStaticFiles, generateStatistic, @@ -65,6 +72,9 @@ const statisticByTestResults = async ( return statistic; }; +const isActiveStatisticTestResult = (testResult: TestResult) => + testResult.resolution !== "muted" && testResult.resolution !== "accepted"; + export class AwesomePlugin implements Plugin { #writer: AwesomeDataWriter | undefined; @@ -90,6 +100,8 @@ export class AwesomePlugin implements Plugin { const statistics = await store.testsStatistic(filter); const environments = await store.allEnvironmentIdentities(); const envStatistics = new Map(); + const pieStatistics = await statisticByTestResults(store, allTrs.filter(isActiveStatisticTestResult)); + const pieEnvStatistics = new Map(); const allTestEnvGroups = await store.allTestEnvGroups(); const globalAttachments = await store.allGlobalAttachments(); const globalAttachmentsByEnv = await store.allGlobalAttachmentsByEnv(); @@ -131,13 +143,18 @@ export class AwesomePlugin implements Plugin { await Promise.all( environments.map(async ({ id }) => { - envStatistics.set(id, await statisticByTestResults(store, trsByEnvId.get(id) ?? [])); + const envTrs = trsByEnvId.get(id) ?? []; + + envStatistics.set(id, await statisticByTestResults(store, envTrs)); + pieEnvStatistics.set(id, await statisticByTestResults(store, envTrs.filter(isActiveStatisticTestResult))); }), ); await generateStatistic(this.#writer!, { stats: statistics, statsByEnv: envStatistics, + pieStats: pieStatistics, + pieStatsByEnv: pieEnvStatistics, envs: environments, }); await generateAllCharts(this.#writer!, store, this.options, context); @@ -154,6 +171,7 @@ export class AwesomePlugin implements Plugin { defaultEnvironment: "default", selectedEnvironmentCount: environments.length, }); + await generateResolutionCategories(this.#writer!, convertedTrs); const hasGroupBy = groupBy.length > 0; await generateTimeline(this.#writer!, allTrs, this.options, envIdByTrId); @@ -194,6 +212,11 @@ export class AwesomePlugin implements Plugin { selectedEnvironmentCount: 1, filename: joinPosixPath(reportEnvironment.id, "categories.json"), }); + await generateResolutionCategories( + this.#writer!, + envConvertedTrs, + joinPosixPath(reportEnvironment.id, "resolution-categories.json"), + ); } await generateTreeFilters(this.#writer!, convertedTrs); diff --git a/packages/plugin-awesome/test/generators.test.ts b/packages/plugin-awesome/test/generators.test.ts index 4ef5798fdac..7c8b770a8f2 100644 --- a/packages/plugin-awesome/test/generators.test.ts +++ b/packages/plugin-awesome/test/generators.test.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/unbound-method */ import { ChartType } from "@allurereport/charts-api"; -import type { AttachmentLink, EnvironmentIdentity, TestFixtureResult, TestResult } from "@allurereport/core-api"; +import type { AttachmentLink, EnvironmentIdentity, Statistic, TestFixtureResult, TestResult } from "@allurereport/core-api"; import type { AllureStore, ReportQualityGateResults, @@ -18,8 +18,11 @@ import { generateGlobals, generateMetricsWidget, generateQualityGateResults, + generateResolutionCategories, generateSearchIndex, + generateStatistic, generateTestResults, + generateTree, getRunSummary, } from "../src/generators.js"; @@ -83,7 +86,6 @@ const mockTestResult = (id: string, name: string, status: TestResult["status"]): labels: [], flaky: false, muted: false, - known: false, isRetry: false, sourceMetadata: { readerId: "system", metadata: {} }, parameters: [], @@ -91,6 +93,20 @@ const mockTestResult = (id: string, name: string, status: TestResult["status"]): steps: [], }) as TestResult; +const createWriter = () => { + const writtenWidgets = new Map(); + const writer: AwesomeDataWriter = { + writeData: vi.fn().mockResolvedValue(undefined), + writeWidget: vi.fn(async (fileName: string, data: unknown) => { + writtenWidgets.set(fileName, data); + }), + writeTestCase: vi.fn().mockResolvedValue(undefined), + writeAttachment: vi.fn().mockResolvedValue(undefined), + }; + + return { writer, writtenWidgets }; +}; + const mockFixtureResult = ( id: string, type: TestFixtureResult["type"], @@ -418,6 +434,7 @@ describe("generateTestResults", () => { historyByTrId: new Map([["tr-1", []]]), retriesByTrId: new Map([["tr-1", []]]), }), + resolutionIssueByTestResultId: vi.fn().mockResolvedValue(undefined), } as unknown as AllureStore; const [converted] = await generateTestResults(writer, store, [testResult]); @@ -425,6 +442,161 @@ describe("generateTestResults", () => { expect(converted?.setup.map(({ name }) => name)).toEqual(["beforeAll", "beforeEach"]); expect(converted?.teardown.map(({ name }) => name)).toEqual(["afterEach", "afterAll"]); }); + + it("should include the matched resolution issue in generated test result JSON", async () => { + const testResult = { + ...mockTestResult("tr-1", "failed test", "failed"), + resolution: "issue", + resolutionComment: "BUG-1 still fails in checkout", + } satisfies TestResult; + const { writer } = createWriter(); + const store = { + relatedByTestResultIds: vi.fn().mockResolvedValue({ + attachmentsByTrId: new Map([["tr-1", []]]), + fixturesByTrId: new Map([["tr-1", []]]), + historyByTrId: new Map([["tr-1", []]]), + retriesByTrId: new Map([["tr-1", []]]), + }), + resolutionIssueByTestResultId: vi.fn().mockResolvedValue({ + id: "BUG-1", + type: "jira", + comment: "BUG-1 still fails in checkout", + }), + } as unknown as AllureStore; + + const [converted] = await generateTestResults(writer, store, [testResult]); + + expect(converted).toMatchObject({ + resolution: "issue", + resolutionComment: "BUG-1 still fails in checkout", + resolutionIssue: { + id: "BUG-1", + type: "jira", + comment: "BUG-1 still fails in checkout", + }, + }); + }); +}); + +describe("generateTree", () => { + it("should include resolution category in tree leaves", async () => { + const { writer, writtenWidgets } = createWriter(); + const tests = [ + { + ...mockTestResult("tr-issue", "issue test", "failed"), + groupedLabels: {}, + resolution: "issue", + } as ReportTestResult, + { + ...mockTestResult("tr-clean", "clean test", "passed"), + groupedLabels: {}, + } as ReportTestResult, + ]; + + await generateTree(writer, "tree.json", [], tests); + + const tree = writtenWidgets.get("tree.json") as { leavesById: Record }; + + expect(tree.leavesById["tr-issue"]).toMatchObject({ resolution: "issue" }); + expect(tree.leavesById["tr-clean"]?.resolution).toBeUndefined(); + }); +}); + +describe("generateResolutionCategories", () => { + it("should write resolution groups with related non-retry test results", async () => { + const { writer, writtenWidgets } = createWriter(); + const tests = [ + { + ...mockTestResult("tr-issue-1", "checkout fails", "failed"), + historyId: "history-1", + resolution: "issue", + resolutionComment: "Checkout discount is not applied", + resolutionIssue: { id: "BUG-1", type: "jira", comment: "Checkout discount is not applied" }, + } as ReportTestResult, + { + ...mockTestResult("tr-issue-2", "checkout fails again", "failed"), + historyId: "history-2", + resolution: "issue", + resolutionComment: "Checkout discount is not applied", + resolutionIssue: { id: "BUG-1", type: "jira", comment: "Checkout discount is not applied" }, + } as ReportTestResult, + { + ...mockTestResult("tr-muted", "muted failure", "broken"), + resolution: "muted", + resolutionComment: "Muted while infra is unstable", + } as ReportTestResult, + { + ...mockTestResult("tr-accepted", "accepted failure", "failed"), + resolution: "accepted", + resolutionComment: "Accepted risk for the release", + } as ReportTestResult, + { + ...mockTestResult("tr-retry", "retry issue", "failed"), + isRetry: true, + resolution: "issue", + resolutionIssue: { id: "BUG-2", type: "jira" }, + } as ReportTestResult, + mockTestResult("tr-clean", "clean test", "passed") as ReportTestResult, + ]; + + await generateResolutionCategories(writer, tests); + + expect(writtenWidgets.get("resolution-categories.json")).toEqual({ + groups: [ + { + id: "issue:BUG-1", + resolution: "issue", + name: "BUG-1", + comment: "Checkout discount is not applied", + issue: { id: "BUG-1", type: "jira", comment: "Checkout discount is not applied" }, + testResults: [ + expect.objectContaining({ nodeId: "tr-issue-1", id: "history-1", resolution: "issue", groupOrder: 1 }), + expect.objectContaining({ nodeId: "tr-issue-2", id: "history-2", resolution: "issue", groupOrder: 2 }), + ], + }, + { + id: "muted:Muted while infra is unstable", + resolution: "muted", + name: "Muted while infra is unstable", + comment: "Muted while infra is unstable", + issue: undefined, + testResults: [expect.objectContaining({ nodeId: "tr-muted", resolution: "muted" })], + }, + { + id: "accepted:Accepted risk for the release", + resolution: "accepted", + name: "Accepted risk for the release", + comment: "Accepted risk for the release", + issue: undefined, + testResults: [expect.objectContaining({ nodeId: "tr-accepted", resolution: "accepted" })], + }, + ], + }); + }); +}); + +describe("generateStatistic", () => { + it("should write pie chart data from active statistics without changing raw statistics", async () => { + const { writer, writtenWidgets } = createWriter(); + const stats: Statistic = { total: 3, passed: 1, failed: 2 }; + const activeStats: Statistic = { total: 2, passed: 1, failed: 1 }; + + await generateStatistic(writer, { + stats, + statsByEnv: new Map(), + pieStats: activeStats, + envs: [], + }); + + expect(writtenWidgets.get("statistic.json")).toEqual(stats); + expect(writtenWidgets.get("pie_chart.json")).toMatchObject({ + percentage: 50, + slices: [ + expect.objectContaining({ status: "failed", count: 1 }), + expect.objectContaining({ status: "passed", count: 1 }), + ], + }); + }); }); describe("generateGlobals", () => { @@ -526,7 +698,6 @@ describe("generateSearchIndex", () => { isRetry: false, flaky: false, muted: false, - known: false, labels: [ { name: "owner", value: "Igor Martynov" }, { name: "feature", value: "Checkout" }, diff --git a/packages/plugin-awesome/test/plugin.test.ts b/packages/plugin-awesome/test/plugin.test.ts index a8b5af900e5..2b8b40f078e 100644 --- a/packages/plugin-awesome/test/plugin.test.ts +++ b/packages/plugin-awesome/test/plugin.test.ts @@ -282,6 +282,7 @@ describe("plugin", () => { allHistoryDataPointsByEnvironment: vi.fn().mockResolvedValue([]), allHistoryDataPointsByEnvironmentId: vi.fn().mockResolvedValue([]), allNewTestResults: vi.fn().mockResolvedValue([]), + resolutionIssueByTestResultId: vi.fn().mockResolvedValue(undefined), attachmentContentById: vi.fn().mockResolvedValue(undefined), } as unknown as AllureStore; @@ -317,6 +318,114 @@ describe("plugin", () => { }); describe("generated widget files", () => { + it("should write pie chart statistics without muted and accepted failures", async () => { + const testResults: TestResult[] = [ + { + id: "tr-passed", + name: "passed test", + status: "passed", + labels: [], + }, + { + id: "tr-issue", + name: "issue test", + status: "failed", + resolution: "issue", + labels: [], + }, + { + id: "tr-muted", + name: "muted test", + status: "failed", + resolution: "muted", + labels: [], + }, + { + id: "tr-accepted", + name: "accepted test", + status: "broken", + resolution: "accepted", + labels: [], + }, + ] as unknown as TestResult[]; + + const addedFiles = new Map(); + const reportFiles: ReportFiles = { + addFile: vi.fn(async (path: string, data: Buffer) => { + addedFiles.set(path, data); + return path; + }), + }; + + const store: AllureStore = { + metadataByKey: vi.fn().mockResolvedValue(undefined), + allEnvironments: vi.fn().mockResolvedValue([]), + allEnvironmentIdentities: vi.fn().mockResolvedValue([]), + allAttachments: vi.fn().mockResolvedValue([]), + allTestResults: vi.fn(async (options?: { includeRetries?: boolean; filter?: (tr: TestResult) => boolean }) => { + const trs = options?.filter ? testResults.filter(options.filter) : testResults; + return trs; + }), + testResultsByEnvironment: vi.fn().mockResolvedValue([]), + testResultsByEnvironmentId: vi.fn().mockResolvedValue([]), + environmentIdByTrId: vi.fn().mockResolvedValue(undefined), + testsStatistic: vi.fn(async (filter: (tr: TestResult) => boolean) => getTestResultsStats(testResults, filter)), + allTestEnvGroups: vi.fn().mockResolvedValue([]), + allGlobalAttachments: vi.fn().mockResolvedValue([]), + allGlobalAttachmentsByEnv: vi.fn().mockResolvedValue({}), + globalExitCode: vi.fn().mockResolvedValue(undefined), + allGlobalErrors: vi.fn().mockResolvedValue([]), + allGlobalErrorsByEnv: vi.fn().mockResolvedValue({}), + qualityGateResults: vi.fn().mockResolvedValue([]), + qualityGateResultsByEnv: vi.fn().mockResolvedValue({}), + qualityGateResultsByEnvironmentId: vi.fn().mockResolvedValue({}), + fixturesByTrId: vi.fn().mockResolvedValue([]), + historyByTrId: vi.fn().mockResolvedValue([]), + retriesByTrId: vi.fn().mockResolvedValue([]), + attachmentsByTrId: vi.fn().mockResolvedValue([]), + relatedByTestResultIds: createRelatedByTestResultIdsMock(), + allVariables: vi.fn().mockResolvedValue([]), + envVariables: vi.fn().mockResolvedValue([]), + envVariablesByEnvironmentId: vi.fn().mockResolvedValue([]), + allHistoryDataPoints: vi.fn().mockResolvedValue([]), + allHistoryDataPointsByEnvironment: vi.fn().mockResolvedValue([]), + allHistoryDataPointsByEnvironmentId: vi.fn().mockResolvedValue([]), + allNewTestResults: vi.fn().mockResolvedValue([]), + resolutionIssueByTestResultId: vi.fn().mockResolvedValue(undefined), + attachmentContentById: vi.fn().mockResolvedValue(undefined), + } as unknown as AllureStore; + + const context: PluginContext = { + id: "Awesome", + publish: true, + state: {} as PluginContext["state"], + allureVersion: "3.0.0", + reportUuid: "report-uuid", + reportName: "Test report", + reportFiles, + output: "/tmp/out", + }; + + const plugin = new AwesomePlugin({ charts: [] }); + + await plugin.start(context); + await plugin.update(context, store); + + expect(JSON.parse(addedFiles.get("widgets/statistic.json")!.toString("utf-8"))).toEqual({ + total: 4, + passed: 1, + failed: 2, + broken: 1, + }); + expect(JSON.parse(addedFiles.get("widgets/pie_chart.json")!.toString("utf-8"))).toMatchObject({ + percentage: 50, + slices: [ + expect.objectContaining({ status: "failed", count: 1 }), + expect.objectContaining({ status: "passed", count: 1 }), + ], + }); + }); + it("always writes widgets/allure_environment.json (and environments.json) in multi-file mode when metadata is absent", async () => { const testResults: TestResult[] = [ { @@ -372,6 +481,7 @@ describe("plugin", () => { allHistoryDataPointsByEnvironment: vi.fn().mockResolvedValue([]), allHistoryDataPointsByEnvironmentId: vi.fn().mockResolvedValue([]), allNewTestResults: vi.fn().mockResolvedValue([]), + resolutionIssueByTestResultId: vi.fn().mockResolvedValue(undefined), attachmentContentById: vi.fn().mockResolvedValue(undefined), } as unknown as AllureStore; @@ -469,6 +579,7 @@ describe("plugin", () => { allHistoryDataPointsByEnvironment: vi.fn().mockResolvedValue([]), allHistoryDataPointsByEnvironmentId: vi.fn().mockResolvedValue([]), allNewTestResults: vi.fn().mockResolvedValue([]), + resolutionIssueByTestResultId: vi.fn().mockResolvedValue(undefined), attachmentContentById: vi.fn().mockResolvedValue(undefined), } as unknown as AllureStore; @@ -588,6 +699,7 @@ describe("plugin", () => { allHistoryDataPointsByEnvironment: vi.fn().mockResolvedValue([]), allHistoryDataPointsByEnvironmentId: vi.fn().mockResolvedValue([]), allNewTestResults: vi.fn().mockResolvedValue([]), + resolutionIssueByTestResultId: vi.fn().mockResolvedValue(undefined), attachmentContentById: vi.fn().mockResolvedValue(undefined), } as unknown as AllureStore; @@ -714,6 +826,7 @@ describe("plugin", () => { allHistoryDataPointsByEnvironment: vi.fn().mockResolvedValue([]), allHistoryDataPointsByEnvironmentId: vi.fn().mockResolvedValue([]), allNewTestResults: vi.fn().mockResolvedValue([]), + resolutionIssueByTestResultId: vi.fn().mockResolvedValue(undefined), attachmentContentById: vi.fn().mockResolvedValue(undefined), } as unknown as AllureStore; @@ -790,6 +903,7 @@ describe("plugin", () => { allHistoryDataPointsByEnvironment: vi.fn().mockResolvedValue([]), allHistoryDataPointsByEnvironmentId: vi.fn().mockResolvedValue([]), allNewTestResults: vi.fn().mockResolvedValue([]), + resolutionIssueByTestResultId: vi.fn().mockResolvedValue(undefined), attachmentContentById: vi.fn().mockResolvedValue(undefined), }) as unknown as AllureStore; diff --git a/packages/web-awesome/src/components/Categories/CategoryTreeItem/index.tsx b/packages/web-awesome/src/components/Categories/CategoryTreeItem/index.tsx index 0db41658abb..c59a9e84aaa 100644 --- a/packages/web-awesome/src/components/Categories/CategoryTreeItem/index.tsx +++ b/packages/web-awesome/src/components/Categories/CategoryTreeItem/index.tsx @@ -293,6 +293,7 @@ export const CategoryTreeItem: FC = ({ nodeId, store, ord retries: node.tooltips?.retries ?? (node.retriesCount ? tTransitions("description.retries", { count: node.retriesCount }) : undefined), + resolution: node.resolution ? tTransitions(`description.resolution.${node.resolution}`) : undefined, } : node.tooltips; return ( diff --git a/packages/web-awesome/src/components/HotkeysProvider/index.tsx b/packages/web-awesome/src/components/HotkeysProvider/index.tsx index fb798d41fc2..d13ac523b70 100644 --- a/packages/web-awesome/src/components/HotkeysProvider/index.tsx +++ b/packages/web-awesome/src/components/HotkeysProvider/index.tsx @@ -193,6 +193,12 @@ const createBindings = (): HotkeyBinding[] => [ key: "5", handler: () => goToReportRootTab(REPORT_ROOT_TAB.GlobalErrors), }, + { + id: "report-tab-resolution-categories", + scope: "global", + key: "6", + handler: () => goToReportRootTab(REPORT_ROOT_TAB.ResolutionCategories), + }, { id: "report-tab-next", scope: "global", @@ -452,27 +458,33 @@ const createBindings = (): HotkeyBinding[] => [ handler: () => goToTestResultTab(TEST_RESULT_TAB.Overview), }, { - id: "test-result-tab-history", + id: "test-result-tab-resolution-categories", scope: "testResult", key: "2", + handler: () => goToTestResultTab(TEST_RESULT_TAB.ResolutionCategories), + }, + { + id: "test-result-tab-history", + scope: "testResult", + key: "3", handler: () => goToTestResultTab(TEST_RESULT_TAB.History), }, { id: "test-result-tab-retries", scope: "testResult", - key: "3", + key: "4", handler: () => goToTestResultTab(TEST_RESULT_TAB.Retries), }, { id: "test-result-tab-attachments", scope: "testResult", - key: "4", + key: "5", handler: () => goToTestResultTab(TEST_RESULT_TAB.Attachments), }, { id: "test-result-tab-environments", scope: "testResult", - key: "5", + key: "6", handler: () => goToTestResultTab(TEST_RESULT_TAB.Environments), }, { diff --git a/packages/web-awesome/src/components/KeyboardShortcuts/shortcutsConfig.ts b/packages/web-awesome/src/components/KeyboardShortcuts/shortcutsConfig.ts index fda129f7c11..e0cce4033dc 100644 --- a/packages/web-awesome/src/components/KeyboardShortcuts/shortcutsConfig.ts +++ b/packages/web-awesome/src/components/KeyboardShortcuts/shortcutsConfig.ts @@ -30,6 +30,7 @@ export const shortcutGroups: ShortcutGroup[] = [ { binding: { key: "3" }, labelKey: "items.reportTabQualityGate" }, { binding: { key: "4" }, labelKey: "items.reportTabGlobalAttachments" }, { binding: { key: "5" }, labelKey: "items.reportTabGlobalErrors" }, + { binding: { key: "6" }, labelKey: "items.reportTabResolutionCategories" }, { binding: { key: "Tab" }, labelKey: "items.reportTabNext" }, { binding: { key: "Tab", modifiers: { shift: true } }, labelKey: "items.reportTabPrev" }, ], @@ -76,10 +77,11 @@ export const shortcutGroups: ShortcutGroup[] = [ { binding: { key: "Tab" }, labelKey: "items.testTabNext" }, { binding: { key: "Tab", modifiers: { shift: true } }, labelKey: "items.testTabPrev" }, { binding: { key: "1" }, labelKey: "items.tabOverview" }, - { binding: { key: "2" }, labelKey: "items.tabHistory" }, - { binding: { key: "3" }, labelKey: "items.tabRetries" }, - { binding: { key: "4" }, labelKey: "items.tabAttachments" }, - { binding: { key: "5" }, labelKey: "items.tabEnvironments" }, + { binding: { key: "2" }, labelKey: "items.tabResolutionCategories" }, + { binding: { key: "3" }, labelKey: "items.tabHistory" }, + { binding: { key: "4" }, labelKey: "items.tabRetries" }, + { binding: { key: "5" }, labelKey: "items.tabAttachments" }, + { binding: { key: "6" }, labelKey: "items.tabEnvironments" }, { binding: { key: "l", code: "KeyL" }, labelKey: "items.toggleLabels" }, { binding: { key: "p", code: "KeyP" }, labelKey: "items.toggleParameters" }, { binding: { key: "i", code: "KeyI" }, labelKey: "items.toggleLinks" }, diff --git a/packages/web-awesome/src/components/MainReport/index.tsx b/packages/web-awesome/src/components/MainReport/index.tsx index 217d855ff5a..e0c119998f2 100644 --- a/packages/web-awesome/src/components/MainReport/index.tsx +++ b/packages/web-awesome/src/components/MainReport/index.tsx @@ -9,6 +9,7 @@ import { ReportGlobalAttachments } from "@/components/ReportGlobalAttachments"; import { ReportGlobalErrors } from "@/components/ReportGlobalErrors"; import { ReportHeader } from "@/components/ReportHeader"; import { ReportMetadata } from "@/components/ReportMetadata"; +import { ReportResolutionCategories } from "@/components/ReportResolutionCategories"; import { reportStatsStore, useI18n } from "@/stores"; import { categoriesStore } from "@/stores/categories"; import { currentEnvironment } from "@/stores/env"; @@ -16,6 +17,7 @@ import { globalsStore } from "@/stores/globals"; import { focusTreePane } from "@/stores/keyboard"; import { isSplitMode } from "@/stores/layout"; import { qualityGateStore } from "@/stores/qualityGate"; +import { resolutionCategoriesStore } from "@/stores/resolutionCategories"; import { navigateToPlainTestResult, navigateToRoot, @@ -35,6 +37,7 @@ export enum ReportRootTab { GlobalAttachments = "globalAttachments", GlobalErrors = "globalErrors", Categories = "categories", + ResolutionCategories = "resolutionCategories", } const viewsByTab = { @@ -48,6 +51,7 @@ const viewsByTab = { [ReportRootTab.GlobalErrors]: () => , [ReportRootTab.QualityGate]: () => , [ReportRootTab.Categories]: () => , + [ReportRootTab.ResolutionCategories]: () => , }; const MainReportContent = () => { @@ -65,12 +69,14 @@ const MainReport = () => { qualityGate: ReportRootTab.QualityGate, globalAttachments: ReportRootTab.GlobalAttachments, globalErrors: ReportRootTab.GlobalErrors, + resolutionCategories: ReportRootTab.ResolutionCategories, }; const reportTabToRootTab: Partial> = { [ReportRootTab.Categories]: "categories", [ReportRootTab.QualityGate]: "qualityGate", [ReportRootTab.GlobalAttachments]: "globalAttachments", [ReportRootTab.GlobalErrors]: "globalErrors", + [ReportRootTab.ResolutionCategories]: "resolutionCategories", }; const initialTab = rootTabRoute.value.matches ? (rootTabToReportTab[rootTabRoute.value.params.rootTab] ?? ReportRootTab.Results) @@ -133,6 +139,7 @@ const MainReport = () => {
focusTreePane()} + role="presentation" >
@@ -210,6 +217,20 @@ const MainReport = () => { ); }} /> + { + if (!resolutionCategories?.groups.length) { + return null; + } + + return ( + + {t("resolutionCategories")} + + ); + }} + />
diff --git a/packages/web-awesome/src/components/ReportFilters/ResolutionFilter.tsx b/packages/web-awesome/src/components/ReportFilters/ResolutionFilter.tsx new file mode 100644 index 00000000000..84f5cb4ff69 --- /dev/null +++ b/packages/web-awesome/src/components/ReportFilters/ResolutionFilter.tsx @@ -0,0 +1,54 @@ +import { allureIcons } from "@allurereport/web-components"; +import { useMemo } from "preact/hooks"; + +import { useI18n } from "@/stores"; +import { RESOLUTIONS } from "@/stores/treeFilters/constants"; +import type { AwesomeFilterGroupSimple } from "@/stores/treeFilters/model"; + +import { MultipleChoiceFieldFilter } from "./BaseFilters"; + +const resolutionOptions = [ + { key: "issue", icon: allureIcons.lineDevBug2 }, + { key: "muted", icon: allureIcons.lineGeneralEye }, + { key: "accepted", icon: allureIcons.lineGeneralCheckCircle }, +]; + +export const ResolutionFilter = (props: { + group: AwesomeFilterGroupSimple; + onChange: (group: AwesomeFilterGroupSimple) => void; +}) => { + const { group, onChange } = props; + const { t } = useI18n("filters"); + const options = useMemo( + () => + resolutionOptions + .filter(({ key }) => RESOLUTIONS.includes(key as (typeof RESOLUTIONS)[number])) + .map((option) => ({ + ...option, + label: t(`resolutions.${option.key}`), + description: t(`description.resolution.${option.key}`), + })), + [t], + ); + + return ( + + onChange({ + ...group, + value: [], + }) + } + /> + ); +}; diff --git a/packages/web-awesome/src/components/ReportFilters/index.tsx b/packages/web-awesome/src/components/ReportFilters/index.tsx index 09108d9d2ae..3fb2522a842 100644 --- a/packages/web-awesome/src/components/ReportFilters/index.tsx +++ b/packages/web-awesome/src/components/ReportFilters/index.tsx @@ -7,6 +7,7 @@ import { clearTreeFilters, hasActiveTreeFilters, setTreeFilter, treeQuickFilters import { isCategoryFilter, isFlakyFilter, + isResolutionFilter, isRetryFilter, isTagFilter, isTransitionFilter, @@ -14,6 +15,7 @@ import { import { BooleanFieldFilter } from "./BaseFilters"; import { CategoriesFilter } from "./CategoriesFilter"; +import { ResolutionFilter } from "./ResolutionFilter"; import { RetryFlakyFilter } from "./RetryFlaky"; import { TagsFilter } from "./TagsFilter"; import { TransitionFilter } from "./TransitionFilter"; @@ -32,6 +34,10 @@ const Filter = (props: { filter: AwesomeFilter; onChange: (filter: AwesomeFilter return ; } + if (isResolutionFilter(filter)) { + return ; + } + if (type === "field" && field.type === "boolean") { return onChange({ ...filter, value })} />; } diff --git a/packages/web-awesome/src/components/ReportResolutionCategories/index.tsx b/packages/web-awesome/src/components/ReportResolutionCategories/index.tsx new file mode 100644 index 00000000000..b5b96585fd0 --- /dev/null +++ b/packages/web-awesome/src/components/ReportResolutionCategories/index.tsx @@ -0,0 +1,29 @@ +import { Loadable, PageLoader } from "@allurereport/web-components"; + +import { ResolutionCategoriesList } from "@/components/ResolutionCategoriesList"; +import { useI18n } from "@/stores"; +import { resolutionCategoriesStore } from "@/stores/resolutionCategories"; + +import * as styles from "./styles.scss"; + +export const ReportResolutionCategories = () => { + const { t } = useI18n("empty"); + + return ( + ( +
+ +
+ )} + renderData={(resolutionCategories) => ( + + )} + /> + ); +}; diff --git a/packages/web-awesome/src/components/ReportResolutionCategories/styles.scss b/packages/web-awesome/src/components/ReportResolutionCategories/styles.scss new file mode 100644 index 00000000000..172c44a47b2 --- /dev/null +++ b/packages/web-awesome/src/components/ReportResolutionCategories/styles.scss @@ -0,0 +1,6 @@ +.report-resolution-categories-loader { + display: flex; + justify-content: center; + width: 100%; + padding: 48px 0; +} diff --git a/packages/web-awesome/src/components/ResolutionCategoriesList/index.tsx b/packages/web-awesome/src/components/ResolutionCategoriesList/index.tsx new file mode 100644 index 00000000000..83fc91d3719 --- /dev/null +++ b/packages/web-awesome/src/components/ResolutionCategoriesList/index.tsx @@ -0,0 +1,146 @@ +import { type ResolutionCategory } from "@allurereport/core-api"; +import { ArrowButton, SvgIcon, Text, TreeItem, allureIcons } from "@allurereport/web-components"; +import type { FunctionalComponent } from "preact"; +import { useState } from "preact/hooks"; +import type { AwesomeResolutionGroup, AwesomeResolutionTestResult } from "types"; + +import { useI18n } from "@/stores/locale"; +import { navigateToTestResult } from "@/stores/router"; + +import * as styles from "./styles.scss"; + +export type ResolutionCategoriesListProps = { + groups: AwesomeResolutionGroup[]; + showTests?: boolean; + emptyText: string; +}; + +const resolutionIcons: Record = { + issue: allureIcons.lineDevBug2, + muted: allureIcons.lineGeneralEye, + accepted: allureIcons.lineGeneralCheckCircle, +}; + +const getResolutionTitle = ( + group: AwesomeResolutionGroup, + t: (key: string, options?: Record) => string, +) => { + if (group.resolution === "issue") { + return group.issue?.id ?? group.name; + } + + return t(`resolutions.${group.resolution}`); +}; + +export const ResolutionCategoriesList: FunctionalComponent = ({ + groups, + showTests = false, + emptyText, +}) => { + if (!groups.length) { + return
{emptyText}
; + } + + return ( +
    + {groups.map((group) => ( + + ))} +
+ ); +}; + +const ResolutionCategoriesItem: FunctionalComponent<{ + group: AwesomeResolutionGroup; + showTests: boolean; +}> = ({ group, showTests }) => { + const hasTests = showTests && Boolean(group.testResults.length); + const [isOpened, setIsOpened] = useState(true); + const { t } = useI18n("filters"); + const title = getResolutionTitle(group, t); + const subtitle = group.comment ?? group.issue?.comment; + const toggle = () => setIsOpened((value) => !value); + + return ( +
  • +
    + {hasTests ? ( + + ) : ( + + )} + +
    + {hasTests ? ( + + ) : ( + + {title} + + )} + {group.issue?.type && ( + + {group.issue.type} + + )} + {subtitle && ( + + {subtitle} + + )} +
    +
    + {hasTests && isOpened && ( +
      + {group.testResults.map((testResult, index) => ( + + ))} +
    + )} +
  • + ); +}; + +const ResolutionCategoriesTestResult: FunctionalComponent<{ + testResult: AwesomeResolutionTestResult; + index: number; +}> = ({ testResult, index }) => { + const { t: tTransitions } = useI18n("transitions"); + const tooltips = { + transition: + testResult.tooltips?.transition ?? + (testResult.transition ? tTransitions(`description.${testResult.transition}`) : undefined), + flaky: testResult.tooltips?.flaky ?? (testResult.flaky ? tTransitions("description.flaky") : undefined), + retries: + testResult.tooltips?.retries ?? + (testResult.retriesCount ? tTransitions("description.retries", { count: testResult.retriesCount }) : undefined), + resolution: testResult.resolution ? tTransitions(`description.resolution.${testResult.resolution}`) : undefined, + }; + + return ( +
  • + navigateToTestResult({ testResultId: testResult.nodeId })} + tooltips={tooltips} + /> +
  • + ); +}; diff --git a/packages/web-awesome/src/components/ResolutionCategoriesList/styles.scss b/packages/web-awesome/src/components/ResolutionCategoriesList/styles.scss new file mode 100644 index 00000000000..f7e9449b034 --- /dev/null +++ b/packages/web-awesome/src/components/ResolutionCategoriesList/styles.scss @@ -0,0 +1,82 @@ +.resolution-categories-list { + min-height: 480px; + padding: 16px 0 48px; +} + +.resolution-categories-item { + list-style: none; + + &:not(:last-child) { + border-bottom: 1px solid var(--color-border-subtle); + } +} + +.resolution-categories-header { + display: flex; + align-items: flex-start; + gap: 8px; + padding: 12px 8px; + transition: background-color 300ms; + + &:hover { + background: var(--color-control-bg-ghost-hover); + } +} + +.resolution-categories-arrow { + flex: 0 0 auto; +} + +.resolution-categories-arrow-spacer { + flex: 0 0 auto; + width: 24px; + height: 24px; +} + +.resolution-categories-icon { + flex: 0 0 auto; + margin-top: 2px; + color: var(--color-icon-secondary); +} + +.resolution-categories-content { + min-width: 0; +} + +.resolution-categories-title { + display: block; + width: 100%; + margin: 0; + padding: 0; + border: 0; + background: transparent; + color: var(--color-text-primary); + cursor: pointer; + text-align: left; +} + +.resolution-categories-name, +.resolution-categories-comment { + overflow-wrap: anywhere; +} + +.resolution-categories-type, +.resolution-categories-comment { + margin-top: 4px; + color: var(--color-text-secondary); +} + +.resolution-categories-tests { + padding-left: 56px; +} + +.resolution-categories-tests > li { + list-style: none; +} + +.resolution-categories-empty { + display: flex; + justify-content: center; + width: 100%; + padding: 48px 0; +} diff --git a/packages/web-awesome/src/components/TestResult/TrInfo/TrInfoStatuses.tsx b/packages/web-awesome/src/components/TestResult/TrInfo/TrInfoStatuses.tsx index 52bc5876322..5d0bbbeeacf 100644 --- a/packages/web-awesome/src/components/TestResult/TrInfo/TrInfoStatuses.tsx +++ b/packages/web-awesome/src/components/TestResult/TrInfo/TrInfoStatuses.tsx @@ -8,7 +8,6 @@ import * as styles from "./styles.scss"; const icons: Record = { flaky: allureIcons.lineIconBomb2, - known: allureIcons.lineAlertsAlertCircle, muted: allureIcons.lineGeneralEye, }; diff --git a/packages/web-awesome/src/components/TestResult/TrInfo/index.tsx b/packages/web-awesome/src/components/TestResult/TrInfo/index.tsx index e68878a09fb..4afa5a744dc 100644 --- a/packages/web-awesome/src/components/TestResult/TrInfo/index.tsx +++ b/packages/web-awesome/src/components/TestResult/TrInfo/index.tsx @@ -23,14 +23,14 @@ export type TrInfoProps = { }; export const TrInfo: FunctionalComponent = ({ testResult }) => { - const { name, status, muted, flaky, known, duration, labels, history, retries, attachments, stop, categories } = + const { name, status, muted, flaky, resolution, duration, labels, history, retries, attachments, stop, categories } = testResult ?? {}; const formattedDuration = formatDuration(duration as number); const fullDate = stop && timestampToDate(stop); const severity = labels?.find((label) => label.name === "severity")?.value ?? "normal"; const categoryName = categories?.[0]?.name; const { t } = useI18n("ui"); - const statuses = Object.entries({ flaky, muted, known }).filter(([, value]) => value); + const statuses = Object.entries({ flaky, muted }).filter(([, value]) => value); const Content = () => { return ( @@ -59,6 +59,14 @@ export const TrInfo: FunctionalComponent = ({ testResult }) => {
    {t("overview")} + {resolution && ( + +
    + {t("resolutionCategories")} + +
    +
    + )}
    {t("history")} diff --git a/packages/web-awesome/src/components/TestResult/TrNavigation/index.tsx b/packages/web-awesome/src/components/TestResult/TrNavigation/index.tsx index 30fadd29806..64df4e91f85 100644 --- a/packages/web-awesome/src/components/TestResult/TrNavigation/index.tsx +++ b/packages/web-awesome/src/components/TestResult/TrNavigation/index.tsx @@ -1,13 +1,12 @@ import { Code, IconButton, Menu, TooltipWrapper, allureIcons } from "@allurereport/web-components"; import { computed, useComputed } from "@preact/signals"; import { useEffect, useRef, useState } from "preact/hooks"; -import { highlightAllUnder } from "prismjs"; import type { ReportTestResult } from "types"; import { useI18n } from "@/stores"; import { navigateToTestResult } from "@/stores/router"; -import { trCurrentTab } from "@/stores/testResult"; import { testResultNavStore } from "@/stores/testResults"; +import { getTestResultTabForTestResultId } from "@/stores/testResultTabs"; import { copyToClipboard } from "@/utils/copyToClipboard"; import * as styles from "./styles.scss"; @@ -36,7 +35,7 @@ const NavArrow = (props: { trId: string | undefined; type: "prev" | "next" }) => icon={icon} style="ghost" data-testid={testId} - onClick={() => navigateToTestResult({ testResultId: trId, tab: trCurrentTab.value })} + onClick={() => navigateToTestResult({ testResultId: trId, tab: getTestResultTabForTestResultId(trId) })} /> ); diff --git a/packages/web-awesome/src/components/TestResult/TrResolutionCategories/index.tsx b/packages/web-awesome/src/components/TestResult/TrResolutionCategories/index.tsx new file mode 100644 index 00000000000..ece09e2cb6f --- /dev/null +++ b/packages/web-awesome/src/components/TestResult/TrResolutionCategories/index.tsx @@ -0,0 +1,24 @@ +import type { FunctionalComponent } from "preact"; +import type { AwesomeResolutionGroup } from "types"; + +import { ResolutionCategoriesList } from "@/components/ResolutionCategoriesList"; +import type { TrViewProps } from "@/components/TestResult"; +import { useI18n } from "@/stores"; + +export const TrResolutionCategoriesView: FunctionalComponent = ({ testResult }) => { + const { t } = useI18n("empty"); + const groups: AwesomeResolutionGroup[] = testResult?.resolution + ? [ + { + id: `${testResult.resolution}:${testResult.resolutionIssue?.id ?? testResult.id}`, + resolution: testResult.resolution, + name: testResult.resolutionIssue?.id ?? testResult.resolution, + comment: testResult.resolutionComment ?? testResult.resolutionIssue?.comment, + issue: testResult.resolutionIssue, + testResults: [], + }, + ] + : []; + + return ; +}; diff --git a/packages/web-awesome/src/components/TestResult/TrTabs/index.tsx b/packages/web-awesome/src/components/TestResult/TrTabs/index.tsx index bc2426549fe..2f01143dea9 100644 --- a/packages/web-awesome/src/components/TestResult/TrTabs/index.tsx +++ b/packages/web-awesome/src/components/TestResult/TrTabs/index.tsx @@ -2,14 +2,15 @@ import { type ComponentChildren } from "preact"; import { NavTab, NavTabs, NavTabsList } from "@/components/NavTabs"; import { navigateToTestResultTab } from "@/stores/router"; -import { currentTrId, trCurrentTab } from "@/stores/testResult"; +import { currentTrId } from "@/stores/testResult"; +import { getCurrentTestResultTab } from "@/stores/testResultTabs"; export const TrTabs = NavTabs; export const TrTabsList = NavTabsList; export const TrTab = (props: { id: string; children: ComponentChildren }) => { const { id, children } = props; - const isCurrentTab = trCurrentTab.value === id; + const isCurrentTab = getCurrentTestResultTab() === id; const handleTabClick = () => { if (isCurrentTab) { diff --git a/packages/web-awesome/src/components/TestResult/index.tsx b/packages/web-awesome/src/components/TestResult/index.tsx index c9acdb7bd5f..c8027c546db 100644 --- a/packages/web-awesome/src/components/TestResult/index.tsx +++ b/packages/web-awesome/src/components/TestResult/index.tsx @@ -10,12 +10,13 @@ import { TrEnvironmentsView } from "@/components/TestResult/TrEnvironmentsView"; import TrHistoryView from "@/components/TestResult/TrHistory"; import { TrInfo } from "@/components/TestResult/TrInfo"; import { TrOverview } from "@/components/TestResult/TrOverview"; +import { TrResolutionCategoriesView } from "@/components/TestResult/TrResolutionCategories"; import { TrRetriesView } from "@/components/TestResult/TrRetriesView"; import { TrTabs } from "@/components/TestResult/TrTabs"; import { fetchTestEnvGroup } from "@/stores/env"; import { focusTestResultPane } from "@/stores/keyboard"; import { isSplitMode } from "@/stores/layout"; -import { trCurrentTab } from "@/stores/testResult"; +import { getCurrentTestResultTab } from "@/stores/testResultTabs"; import * as styles from "./styles.scss"; @@ -34,12 +35,13 @@ export type TrProps = { const view = computed(() => { const viewMap: Record = { overview: TrOverview, + resolutionCategories: TrResolutionCategoriesView, history: TrHistoryView, attachments: TrAttachmentView, retries: TrRetriesView, environments: TrEnvironmentsView, }; - return viewMap[trCurrentTab.value]; + return viewMap[getCurrentTestResultTab()]; }); const TrView: FunctionalComponent = ({ testResult }) => { @@ -74,6 +76,7 @@ const TestResult: FunctionComponent = ({ testResult }) => { className={clsx(styles.content, split && styles["scroll-inside"])} data-tr-scroll-container onMouseDown={() => focusTestResultPane()} + role="presentation" > {testResult ? : }
    diff --git a/packages/web-awesome/src/index.tsx b/packages/web-awesome/src/index.tsx index 935a9a16a1b..b0bad3cd1a7 100644 --- a/packages/web-awesome/src/index.tsx +++ b/packages/web-awesome/src/index.tsx @@ -27,6 +27,7 @@ import { fetchEnvTreesData } from "@/stores/tree"; import { isMac } from "@/utils/isMac"; import { fetchQualityGateResults } from "./stores/qualityGate"; +import { fetchResolutionCategoriesData } from "./stores/resolutionCategories"; import { rootTabRoute, testResultRoute } from "./stores/router"; import { currentSection } from "./stores/sections"; import { currentTrId } from "./stores/testResult"; @@ -68,6 +69,7 @@ const App = () => { fetchQualityGateResults, fetchCategoriesData, fetchMetricsData, + fetchResolutionCategoriesData, ]; if (globalThis) { @@ -107,6 +109,7 @@ const App = () => { fetchPieChartData(envId); fetchCategoriesData(envId); + fetchResolutionCategoriesData(envId); if (!envId) { return; diff --git a/packages/web-awesome/src/locales/ar.json b/packages/web-awesome/src/locales/ar.json index 4af9603ea6a..2f7900c3fd0 100644 --- a/packages/web-awesome/src/locales/ar.json +++ b/packages/web-awesome/src/locales/ar.json @@ -22,7 +22,8 @@ "globalAttachments": "المرفقات العامة", "globalErrors": "الأخطاء العامة", "qualityGates": "بوابات الجودة", - "categories": "الفئات" + "categories": "الفئات", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "بحث", @@ -56,7 +57,18 @@ "regressed": "عرض نتائج الاختبارات التي تغيرت إلى حالة \"فشل\" من حالة \"ناجح\" أو \"معطل\"", "malfunctioned": "عرض نتائج الاختبارات التي تغيرت إلى حالة \"معطل\" من حالة \"ناجح\" أو \"فشل\"", "tags": "عرض نتائج الاختبارات التي تحتوي على الوسوم المحددة", - "categories": "عرض نتائج الاختبارات التي تحتوي على الفئات المحددة" + "categories": "عرض نتائج الاختبارات التي تحتوي على الفئات المحددة", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "لا توجد نتائج حالات اختبار", "no-environments-results": "لا تتوفر معلومات عن البيئات", "no-categories-results": "لا تتوفر نتائج الفئات", - "no-metrics-results": "لا توجد مقاييس متاحة" + "no-metrics-results": "لا توجد مقاييس متاحة", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "مانع", @@ -158,7 +171,8 @@ "variables": "المتغيرات", "openPwTrace": "فتح تتبع Playwright", "finishedAtOriginal": "{{formattedCreatedAt}}، برمز خروج {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}، برمز خروج {{actual}} (الأصلي {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}، برمز خروج {{actual}} (الأصلي {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "فتح المرفق في علامة تبويب جديدة", @@ -427,7 +441,12 @@ "regressed": "اختبار كان \"ناجح\" أو \"معطل\" سابقاً وأصبح الآن \"فشل\"", "malfunctioned": "اختبار كان \"ناجح\" أو \"فشل\" سابقاً وأصبح الآن \"معطل\"", "retries": "{{count}} محاولات إعادة", - "flaky": "غير مستقر عبر التشغيلات" + "flaky": "غير مستقر عبر التشغيلات", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "جديد", "fixed": "تم الإصلاح", @@ -506,6 +525,7 @@ "testTabNext": "تبويب الاختبار التالي", "testTabPrev": "تبويب الاختبار السابق", "tabOverview": "تبويب النظرة العامة", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "تبويب السجل", "tabRetries": "تبويب إعادة المحاولات", "tabAttachments": "تبويب المرفقات", @@ -513,7 +533,8 @@ "toggleLabels": "إظهار/إخفاء التسميات", "toggleParameters": "إظهار/إخفاء المعاملات", "toggleLinks": "إظهار/إخفاء الروابط", - "backToTree": "العودة إلى الشجرة" + "backToTree": "العودة إلى الشجرة", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/az.json b/packages/web-awesome/src/locales/az.json index 87f0e3c4c5e..991237ce68d 100644 --- a/packages/web-awesome/src/locales/az.json +++ b/packages/web-awesome/src/locales/az.json @@ -22,7 +22,8 @@ "globalAttachments": "Qlobal qoşmalar", "globalErrors": "Qlobal xətalar", "qualityGates": "Keyfiyyət meyarları", - "categories": "Kateqoriyalar" + "categories": "Kateqoriyalar", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Axtar", @@ -56,7 +57,18 @@ "regressed": "Statusu \"uğurlu\" və ya \"sınıq\"dan \"uğursuz\"a dəyişən test nəticələrini göstər", "malfunctioned": "Statusu \"uğurlu\" və ya \"uğursuz\"dan \"sınıq\"a dəyişən test nəticələrini göstər", "tags": "Göstərilən teqləri olan test nəticələrini göstər", - "categories": "Göstərilən kateqoriyaları olan test nəticələrini göstər" + "categories": "Göstərilən kateqoriyaları olan test nəticələrini göstər", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Test halları üzrə nəticə yoxdur", "no-environments-results": "Mühitlər haqqında məlumat yoxdur", "no-categories-results": "Kateqoriyalar üzrə nəticə yoxdur", - "no-metrics-results": "Metrik yoxdur" + "no-metrics-results": "Metrik yoxdur", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "bloklayıcı", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Brauzer Playwright Trace Viewer-i açmağı blokladı.", "pwTracePopupBlockedHint": "Pop-uplara icazə verin və yenidən cəhd edin.", "finishedAtOriginal": "{{formattedCreatedAt}}, çıxış kodu {{original}} ilə", - "finishedAtBoth": "{{formattedCreatedAt}}, çıxış kodu {{actual}} ilə (ilkin {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, çıxış kodu {{actual}} ilə (ilkin {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Qoşmanı yeni tabda aç", @@ -432,7 +446,12 @@ "regressed": "Əvvəl \"uğurlu\" və ya \"sınıq\" olan, indi \"uğursuz\" olan test", "malfunctioned": "Əvvəl \"uğurlu\" və ya \"uğursuz\" olan, indi \"sınıq\" olan test", "retries": "{{count}} təkrar cəhd", - "flaky": "İşəsalınmalar arasında qeyri-sabitdir" + "flaky": "İşəsalınmalar arasında qeyri-sabitdir", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Yeni", "fixed": "Düzəldilmiş", @@ -511,6 +530,7 @@ "testTabNext": "Növbəti test nişanı", "testTabPrev": "Əvvəlki test nişanı", "tabOverview": "İcmal nişanı", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Tarixçə nişanı", "tabRetries": "Yenidən cəhdlər nişanı", "tabAttachments": "Əlavələr nişanı", @@ -518,7 +538,8 @@ "toggleLabels": "Etiketləri göstər/gizlət", "toggleParameters": "Parametrləri göstər/gizlət", "toggleLinks": "Bağlantıları göstər/gizlət", - "backToTree": "Ağaca qayıt" + "backToTree": "Ağaca qayıt", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/de.json b/packages/web-awesome/src/locales/de.json index 3ac9dda4c52..bc7cef79357 100644 --- a/packages/web-awesome/src/locales/de.json +++ b/packages/web-awesome/src/locales/de.json @@ -22,7 +22,8 @@ "globalAttachments": "Globale Anhänge", "globalErrors": "Globale Fehler", "qualityGates": "Qualitätstore", - "categories": "Kategorien" + "categories": "Kategorien", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Suchen", @@ -56,7 +57,18 @@ "regressed": "Testergebnisse anzeigen, die den Status von \"erfolgreich\" oder \"defekt\" zu \"fehlgeschlagen\" geändert haben", "malfunctioned": "Testergebnisse anzeigen, die den Status von \"erfolgreich\" oder \"fehlgeschlagen\" zu \"defekt\" geändert haben", "tags": "Testergebnisse anzeigen, die die angegebenen Tags haben", - "categories": "Testergebnisse anzeigen, die die angegebenen Kategorien haben" + "categories": "Testergebnisse anzeigen, die die angegebenen Kategorien haben", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Keine Testergebnisse verfügbar", "no-environments-results": "Keine Umgebungsinformationen verfügbar", "no-categories-results": "Keine Kategorien verfügbar", - "no-metrics-results": "Keine Metriken verfügbar" + "no-metrics-results": "Keine Metriken verfügbar", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "Blocker", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Der Browser hat das Öffnen des Playwright Trace Viewer blockiert.", "pwTracePopupBlockedHint": "Erlaube Pop-ups und versuche es erneut.", "finishedAtOriginal": "{{formattedCreatedAt}}, mit Exit-Code {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, mit Exit-Code {{actual}} (ursprünglich {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, mit Exit-Code {{actual}} (ursprünglich {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Anhang in neuem Tab öffnen", @@ -432,7 +446,12 @@ "regressed": "Zuvor \"erfolgreich\" oder \"defekt\" gewesener Test, der jetzt \"fehlgeschlagen\" ist", "malfunctioned": "Zuvor \"erfolgreich\" oder \"fehlgeschlagen\" gewesener Test, der jetzt \"defekt\" ist", "retries": "{{count}} Wiederholungen", - "flaky": "Inkonsistent über mehrere Läufe" + "flaky": "Inkonsistent über mehrere Läufe", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Neu", "fixed": "Behoben", @@ -511,6 +530,7 @@ "testTabNext": "Nächster Test-Tab", "testTabPrev": "Vorheriger Test-Tab", "tabOverview": "Tab Übersicht", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Tab Verlauf", "tabRetries": "Tab Wiederholungen", "tabAttachments": "Tab Anhänge", @@ -518,7 +538,8 @@ "toggleLabels": "Labels ein-/ausblenden", "toggleParameters": "Parameter ein-/ausblenden", "toggleLinks": "Links ein-/ausblenden", - "backToTree": "Zurück zum Baum" + "backToTree": "Zurück zum Baum", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/en.json b/packages/web-awesome/src/locales/en.json index 7f97e1f0c03..f2430ef0c9d 100644 --- a/packages/web-awesome/src/locales/en.json +++ b/packages/web-awesome/src/locales/en.json @@ -22,7 +22,8 @@ "globalAttachments": "Global Attachments", "globalErrors": "Global Errors", "qualityGates": "Quality Gates", - "categories": "Categories" + "categories": "Categories", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Search", @@ -56,7 +57,18 @@ "regressed": "Show test results that changed to \"failed\" status from \"passed\" or \"broken\" status", "malfunctioned": "Show test results that changed to \"broken\" status from \"passed\" or \"failed\" status", "tags": "Show test results that have the specified tags", - "categories": "Show test results that have the specified categories" + "categories": "Show test results that have the specified categories", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "No test case results", "no-environments-results": "No environments information available", "no-categories-results": "No categories results available", - "no-metrics-results": "No metrics available" + "no-metrics-results": "No metrics available", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "blocker", @@ -163,7 +176,8 @@ "pwTracePopupBlocked": "Browser blocked opening Playwright Trace Viewer.", "pwTracePopupBlockedHint": "Allow popups and retry.", "finishedAtOriginal": "{{formattedCreatedAt}}, with exit code {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, with exit code {{actual}} (original {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, with exit code {{actual}} (original {{original}})", + "resolutionCategories": "Resolution Categories" }, "shortcuts": { "title": "Keyboard shortcuts", @@ -215,6 +229,7 @@ "testTabNext": "Next test tab", "testTabPrev": "Previous test tab", "tabOverview": "Overview tab", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "History tab", "tabRetries": "Retries tab", "tabAttachments": "Attachments tab", @@ -222,7 +237,8 @@ "toggleLabels": "Toggle labels", "toggleParameters": "Toggle parameters", "toggleLinks": "Toggle links", - "backToTree": "Back to tree" + "backToTree": "Back to tree", + "reportTabResolutionCategories": "Report tab: Resolution categories" } }, "controls": { @@ -495,7 +511,12 @@ "regressed": "A previously \"passed\" or \"broken\" test that is now \"failed\"", "malfunctioned": "A previously \"passed\" or \"failed\" test that is now \"broken\"", "retries": "{{count}} retries", - "flaky": "Inconsistent across runs" + "flaky": "Inconsistent across runs", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "new", "fixed": "fixed", diff --git a/packages/web-awesome/src/locales/es.json b/packages/web-awesome/src/locales/es.json index 92821d0b924..bda3429ca05 100644 --- a/packages/web-awesome/src/locales/es.json +++ b/packages/web-awesome/src/locales/es.json @@ -22,7 +22,8 @@ "globalAttachments": "Adjuntos Globales", "globalErrors": "Errores Globales", "qualityGates": "Puertas de Calidad", - "categories": "Categorías" + "categories": "Categorías", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Buscar", @@ -56,7 +57,18 @@ "regressed": "Mostrar resultados de pruebas que cambiaron de estado \"aprobado\" o \"roto\" a \"fallido\"", "malfunctioned": "Mostrar resultados de pruebas que cambiaron de estado \"aprobado\" o \"fallido\" a \"roto\"", "tags": "Mostrar resultados de pruebas que tienen las etiquetas especificadas", - "categories": "Mostrar resultados de pruebas que tienen las categorías especificadas" + "categories": "Mostrar resultados de pruebas que tienen las categorías especificadas", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "No hay resultados de casos de prueba", "no-environments-results": "No hay información de entornos disponible", "no-categories-results": "No hay categorías disponibles", - "no-metrics-results": "No hay métricas disponibles" + "no-metrics-results": "No hay métricas disponibles", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "bloqueante", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "El navegador bloqueó la apertura de Playwright Trace Viewer.", "pwTracePopupBlockedHint": "Permite las ventanas emergentes y vuelve a intentarlo.", "finishedAtOriginal": "{{formattedCreatedAt}}, con código de salida {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, con código de salida {{actual}} (original {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, con código de salida {{actual}} (original {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Abrir adjunto en nueva pestaña", @@ -432,7 +446,12 @@ "regressed": "Prueba que anteriormente estaba \"aprobada\" o \"rota\" y ahora \"falló\"", "malfunctioned": "Prueba que anteriormente estaba \"aprobada\" o \"falló\" y ahora está \"rota\"", "retries": "{{count}} reintentos", - "flaky": "Resultados inconsistentes entre ejecuciones" + "flaky": "Resultados inconsistentes entre ejecuciones", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Nuevo", "fixed": "Corregido", @@ -511,6 +530,7 @@ "testTabNext": "Siguiente pestaña de prueba", "testTabPrev": "Pestaña de prueba anterior", "tabOverview": "Pestaña resumen", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Pestaña historial", "tabRetries": "Pestaña reintentos", "tabAttachments": "Pestaña archivos adjuntos", @@ -518,7 +538,8 @@ "toggleLabels": "Mostrar/ocultar etiquetas", "toggleParameters": "Mostrar/ocultar parámetros", "toggleLinks": "Mostrar/ocultar enlaces", - "backToTree": "Volver al árbol" + "backToTree": "Volver al árbol", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/fr.json b/packages/web-awesome/src/locales/fr.json index 8f844bdcb8d..2f08de74d35 100644 --- a/packages/web-awesome/src/locales/fr.json +++ b/packages/web-awesome/src/locales/fr.json @@ -22,7 +22,8 @@ "globalAttachments": "Pièces jointes globales", "globalErrors": "Erreurs globales", "qualityGates": "Portails de Qualité", - "categories": "Catégories" + "categories": "Catégories", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Recherche", @@ -56,7 +57,18 @@ "regressed": "Afficher les résultats des tests qui sont passés du statut \"réussi\" ou \"cassé\" à \"échoué\"", "malfunctioned": "Afficher les résultats des tests qui sont passés du statut \"réussi\" ou \"échoué\" à \"cassé\"", "tags": "Afficher les résultats des tests qui ont les tags spécifiés", - "categories": "Afficher les résultats des tests qui ont les catégories spécifiées" + "categories": "Afficher les résultats des tests qui ont les catégories spécifiées", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Aucun résultat de cas de test", "no-environments-results": "Aucune information sur les environnements disponible", "no-categories-results": "Aucune catégorie disponible", - "no-metrics-results": "Aucune métrique disponible" + "no-metrics-results": "Aucune métrique disponible", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "bloquant", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Le navigateur a bloqué l’ouverture de Playwright Trace Viewer.", "pwTracePopupBlockedHint": "Autorisez les pop-ups et réessayez.", "finishedAtOriginal": "{{formattedCreatedAt}}, avec le code de sortie {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, avec le code de sortie {{actual}} (original {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, avec le code de sortie {{actual}} (original {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Ouvrir dans un nouvel onglet", @@ -432,7 +446,12 @@ "regressed": "Test précédemment \"réussi\" ou \"cassé\" qui est maintenant \"échoué\"", "malfunctioned": "Test précédemment \"réussi\" ou \"échoué\" qui est maintenant \"cassé\"", "retries": "{{count}} tentatives", - "flaky": "Incohérent entre les exécutions" + "flaky": "Incohérent entre les exécutions", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Nouveaux", "fixed": "Corrigés", @@ -511,6 +530,7 @@ "testTabNext": "Onglet test suivant", "testTabPrev": "Onglet test précédent", "tabOverview": "Onglet aperçu", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Onglet historique", "tabRetries": "Onglet tentatives", "tabAttachments": "Onglet pièces jointes", @@ -518,7 +538,8 @@ "toggleLabels": "Afficher/masquer les étiquettes", "toggleParameters": "Afficher/masquer les paramètres", "toggleLinks": "Afficher/masquer les liens", - "backToTree": "Retour à l'arborescence" + "backToTree": "Retour à l'arborescence", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/he.json b/packages/web-awesome/src/locales/he.json index 2206a73fa4e..dd8ff79778e 100644 --- a/packages/web-awesome/src/locales/he.json +++ b/packages/web-awesome/src/locales/he.json @@ -22,7 +22,8 @@ "globalAttachments": "קבצים מצורפים גלובליים", "globalErrors": "שגיאות גלובליות", "qualityGates": "שערי איכות", - "categories": "קטגוריות" + "categories": "קטגוריות", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "חפש", @@ -56,7 +57,18 @@ "regressed": "הצג תוצאות בדיקות ששינו סטטוס מ-\"עבר\" או \"שבור\" ל-\"נכשל\"", "malfunctioned": "הצג תוצאות בדיקות ששינו סטטוס מ-\"עבר\" או \"נכשל\" ל-\"שבור\"", "tags": "הצג תוצאות בדיקות שיש להן את התגים שצוינו", - "categories": "הצג תוצאות בדיקות שיש להן את הקטגוריות שצוינו" + "categories": "הצג תוצאות בדיקות שיש להן את הקטגוריות שצוינו", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "אין תוצאות של מקרי בדיקה", "no-environments-results": "לא נמצא מידע על סביבות", "no-categories-results": "אין קטגוריות זמינות", - "no-metrics-results": "אין מדדים זמינים" + "no-metrics-results": "אין מדדים זמינים", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "חוסם", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "הדפדפן חסם את פתיחת Playwright Trace Viewer.", "pwTracePopupBlockedHint": "אפשר חלונות קופצים ונסה שוב.", "finishedAtOriginal": "{{formattedCreatedAt}}, עם קוד יציאה {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, עם קוד יציאה {{actual}} (מקורי {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, עם קוד יציאה {{actual}} (מקורי {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "פתח קובץ מצורף בלשונית חדשה", @@ -432,7 +446,12 @@ "regressed": "בדיקה שהייתה קודם \"עברה\" או \"שבורה\" ועכשיו \"נכשלה\"", "malfunctioned": "בדיקה שהייתה קודם \"עברה\" או \"נכשלה\" ועכשיו \"שבורה\"", "retries": "{{count}} ניסיונות חוזרים", - "flaky": "לא עקבי בין הרצות" + "flaky": "לא עקבי בין הרצות", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "חדש", "fixed": "מתוקן", @@ -511,6 +530,7 @@ "testTabNext": "לשונית בדיקה הבאה", "testTabPrev": "לשונית בדיקה הקודמת", "tabOverview": "לשונית סקירה", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "לשונית היסטוריה", "tabRetries": "לשונית ניסיונות חוזרים", "tabAttachments": "לשונית קבצים מצורפים", @@ -518,7 +538,8 @@ "toggleLabels": "הצג/הסתר תוויות", "toggleParameters": "הצג/הסתר פרמטרים", "toggleLinks": "הצג/הסתר קישורים", - "backToTree": "חזור לעץ" + "backToTree": "חזור לעץ", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/hy.json b/packages/web-awesome/src/locales/hy.json index 4542f483290..41af70b3edf 100644 --- a/packages/web-awesome/src/locales/hy.json +++ b/packages/web-awesome/src/locales/hy.json @@ -22,7 +22,8 @@ "globalAttachments": "Գլոբալ կցորդներ", "globalErrors": "Գլոբալ սխալներ", "qualityGates": "Որակի դարպասներ", - "categories": "Կատեգորիաներ" + "categories": "Կատեգորիաներ", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Որոնում", @@ -56,7 +57,18 @@ "regressed": "Ցուցադրում է թեստերի արդյունքները, որոնք փոխել են կարգավիճակը \"անցած\" կամ \"կոտրված\"-ից \"ձախողված\"-ի", "malfunctioned": "Ցուցադրում է թեստերի արդյունքները, որոնք փոխել են կարգավիճակը \"անցած\" կամ \"ձախողված\"-ից \"կոտրված\"-ի", "tags": "Ցուցադրում է թեստերի արդյունքները, որոնք ունեն նշված պիտակները", - "categories": "Ցուցադրել թեստերի արդյունքները, որոնք ունեն նշված կատեգորիաները" + "categories": "Ցուցադրել թեստերի արդյունքները, որոնք ունեն նշված կատեգորիաները", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Թեստի դեպքերի արդյունքներ չկան։", "no-environments-results": "Համակարգչային միջավայրի մասին տեղեկություններ չկան", "no-categories-results": "Կատեգորիաներ հասանելի չեն", - "no-metrics-results": "Մետրիկաներ չկան" + "no-metrics-results": "Մետրիկաներ չկան", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "արգելափակում", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Բրաուզերը արգելափակեց Playwright Trace Viewer-ի բացումը։", "pwTracePopupBlockedHint": "Թույլատրեք բացվող պատուհանները և կրկին փորձեք։", "finishedAtOriginal": "{{formattedCreatedAt}}, ելքի կոդ {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, ելքի կոդ {{actual}} (սկզբնական {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, ելքի կոդ {{actual}} (սկզբնական {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Բացել նոր ներդիրում", @@ -432,7 +446,12 @@ "regressed": "Նախկինում \"անցած\" կամ \"կոտրված\" թեստ, որը այժմ \"ձախողվել\" է", "malfunctioned": "Նախկինում \"անցած\" կամ \"ձախողված\" թեստ, որը այժմ \"կոտրված\" է", "retries": "{{count}} կրկնափորձ", - "flaky": "Անհետևողական տարբեր գործարկումների ընթացքում" + "flaky": "Անհետևողական տարբեր գործարկումների ընթացքում", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Նոր", "fixed": "Ուղղված", @@ -511,6 +530,7 @@ "testTabNext": "Հաջորդ թեստի ներդիր", "testTabPrev": "Նախորդ թեստի ներդիր", "tabOverview": "Ակնարկի ներդիր", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Պատմության ներդիր", "tabRetries": "Կրկնությունների ներդիր", "tabAttachments": "Կցորդների ներդիր", @@ -518,7 +538,8 @@ "toggleLabels": "Ցուցադրել/թաքցնել պիտակները", "toggleParameters": "Ցուցադրել/թաքցնել պարամետրերը", "toggleLinks": "Ցուցադրել/թաքցնել հղումները", - "backToTree": "Վերադառնալ ծառ" + "backToTree": "Վերադառնալ ծառ", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/it.json b/packages/web-awesome/src/locales/it.json index 624bdaf2642..9828abce7e6 100644 --- a/packages/web-awesome/src/locales/it.json +++ b/packages/web-awesome/src/locales/it.json @@ -22,7 +22,8 @@ "globalAttachments": "Allegati Globali", "globalErrors": "Errori Globali", "qualityGates": "Porte di Qualità", - "categories": "Categorie" + "categories": "Categorie", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Cerca", @@ -56,7 +57,18 @@ "regressed": "Mostra i risultati dei test che sono passati dallo stato \"superato\" o \"danneggiato\" a \"fallito\"", "malfunctioned": "Mostra i risultati dei test che sono passati dallo stato \"superato\" o \"fallito\" a \"danneggiato\"", "tags": "Mostra i risultati dei test che hanno i tag specificati", - "categories": "Mostra i risultati dei test che hanno le categorie specificate" + "categories": "Mostra i risultati dei test che hanno le categorie specificate", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Nessun risultato dei casi di test", "no-environments-results": "Nessuna informazione sugli ambienti disponibile", "no-categories-results": "Nessuna categoria disponibile", - "no-metrics-results": "Nessuna metrica disponibile" + "no-metrics-results": "Nessuna metrica disponibile", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "bloccante", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Il browser ha bloccato l'apertura di Playwright Trace Viewer.", "pwTracePopupBlockedHint": "Consenti i popup e riprova.", "finishedAtOriginal": "{{formattedCreatedAt}}, con codice di uscita {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, con codice di uscita {{actual}} (originale {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, con codice di uscita {{actual}} (originale {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Apri in una nuova scheda", @@ -432,7 +446,12 @@ "regressed": "Test precedentemente \"superato\" o \"danneggiato\" che ora è \"fallito\"", "malfunctioned": "Test precedentemente \"superato\" o \"fallito\" che ora è \"danneggiato\"", "retries": "{{count}} tentativi", - "flaky": "Incoerente tra le esecuzioni" + "flaky": "Incoerente tra le esecuzioni", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Nuovi", "fixed": "Corretti", @@ -511,6 +530,7 @@ "testTabNext": "Tab test successivo", "testTabPrev": "Tab test precedente", "tabOverview": "Tab panoramica", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Tab cronologia", "tabRetries": "Tab nuovi tentativi", "tabAttachments": "Tab allegati", @@ -518,7 +538,8 @@ "toggleLabels": "Mostra/nascondi etichette", "toggleParameters": "Mostra/nascondi parametri", "toggleLinks": "Mostra/nascondi link", - "backToTree": "Torna all'albero" + "backToTree": "Torna all'albero", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/ja.json b/packages/web-awesome/src/locales/ja.json index 17cfb90f8af..295aab8fff1 100644 --- a/packages/web-awesome/src/locales/ja.json +++ b/packages/web-awesome/src/locales/ja.json @@ -22,7 +22,8 @@ "globalAttachments": "グローバル添付ファイル", "globalErrors": "グローバルエラー", "qualityGates": "品質ゲート", - "categories": "カテゴリ" + "categories": "カテゴリ", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "検索", @@ -56,7 +57,18 @@ "regressed": "ステータスが「成功」または「破損」から「失敗」に変更されたテスト結果を表示します", "malfunctioned": "ステータスが「成功」または「失敗」から「破損」に変更されたテスト結果を表示します", "tags": "指定されたタグを持つテスト結果を表示します", - "categories": "指定したカテゴリを持つテスト結果を表示します" + "categories": "指定したカテゴリを持つテスト結果を表示します", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "テストケースの結果がありません", "no-environments-results": "環境情報が利用できません", "no-categories-results": "利用可能なカテゴリはありません", - "no-metrics-results": "利用できるメトリクスはありません" + "no-metrics-results": "利用できるメトリクスはありません", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "ブロッカー", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "ブラウザーが Playwright Trace Viewer の表示をブロックしました。", "pwTracePopupBlockedHint": "ポップアップを許可して再試行してください。", "finishedAtOriginal": "{{formattedCreatedAt}}、終了コード{{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}、終了コード{{actual}}(元{{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}、終了コード{{actual}}(元{{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "新しいタブで開く", @@ -432,7 +446,12 @@ "regressed": "以前「成功」または「破損」だったテストが「失敗」になった", "malfunctioned": "以前「成功」または「失敗」だったテストが「破損」になった", "retries": "{{count}} 回の再試行", - "flaky": "実行ごとに結果が不安定" + "flaky": "実行ごとに結果が不安定", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "新規", "fixed": "修正済み", @@ -511,6 +530,7 @@ "testTabNext": "次のテストタブ", "testTabPrev": "前のテストタブ", "tabOverview": "概要タブ", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "履歴タブ", "tabRetries": "リトライタブ", "tabAttachments": "添付ファイルタブ", @@ -518,7 +538,8 @@ "toggleLabels": "ラベルを表示/非表示", "toggleParameters": "パラメータを表示/非表示", "toggleLinks": "リンクを表示/非表示", - "backToTree": "ツリーに戻る" + "backToTree": "ツリーに戻る", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/ka.json b/packages/web-awesome/src/locales/ka.json index 8f1f4e21a0c..2be0e282f25 100644 --- a/packages/web-awesome/src/locales/ka.json +++ b/packages/web-awesome/src/locales/ka.json @@ -22,7 +22,8 @@ "globalAttachments": "გლობალური დანართები", "globalErrors": "გლობალური შეცდომები", "qualityGates": "ხარისხის კარიბჭეები", - "categories": "კატეგორიები" + "categories": "კატეგორიები", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "ძებნა", @@ -56,7 +57,18 @@ "regressed": "აჩვენებს ტესტების შედეგებს, რომლებმაც შეცვალეს სტატუსი \"წარმატებული\" ან \"დამტვრეული\"-დან \"წარუმატებელი\"-ზე", "malfunctioned": "აჩვენებს ტესტების შედეგებს, რომლებმაც შეცვალეს სტატუსი \"წარმატებული\" ან \"წარუმატებელი\"-დან \"დამტვრეული\"-ზე", "tags": "აჩვენებს ტესტების შედეგებს, რომლებსაც აქვთ მითითებული ტეგები", - "categories": "აჩვენებს ტესტების შედეგებს, რომლებსაც აქვთ მითითებული კატეგორიები" + "categories": "აჩვენებს ტესტების შედეგებს, რომლებსაც აქვთ მითითებული კატეგორიები", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "ტესტის შემთხვევის შედეგები არ არის", "no-environments-results": "გარემობის ინფორმაცია არ არის ხელმისაწვდომი", "no-categories-results": "კატეგორიები ხელმისაწვდომი არ არის", - "no-metrics-results": "მეტრიკები ხელმისაწვდომი არ არის" + "no-metrics-results": "მეტრიკები ხელმისაწვდომი არ არის", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "ბლოკერი", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "ბრაუზერმა დაბლოკა Playwright Trace Viewer-ის გახსნა.", "pwTracePopupBlockedHint": "დაუშვით ამომხტარი ფანჯრები და ხელახლა სცადეთ.", "finishedAtOriginal": "{{formattedCreatedAt}}, გამოსვლის კოდით {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, გამოსვლის კოდით {{actual}} (თავდაპირველი {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, გამოსვლის კოდით {{actual}} (თავდაპირველი {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "დანართის გახსნა ახალ ჩანართში", @@ -432,7 +446,12 @@ "regressed": "ადრე \"წარმატებული\" ან \"დამტვრეული\" ტესტი, რომელიც ახლა \"წარუმატებელი\"ა", "malfunctioned": "ადრე \"წარმატებული\" ან \"წარუმატებელი\" ტესტი, რომელიც ახლა \"დამტვრეული\"ა", "retries": "{{count}} ხელახალი ცდა", - "flaky": "შედეგები არასტაბილურია გაშვებებს შორის" + "flaky": "შედეგები არასტაბილურია გაშვებებს შორის", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "ახალი", "fixed": "გასწორებული", @@ -511,6 +530,7 @@ "testTabNext": "შემდეგი ტესტის ჩანართი", "testTabPrev": "წინა ტესტის ჩანართი", "tabOverview": "მიმოხილვის ჩანართი", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "ისტორიის ჩანართი", "tabRetries": "გამეორებების ჩანართი", "tabAttachments": "დანართების ჩანართი", @@ -518,7 +538,8 @@ "toggleLabels": "ლეიბლების ჩვენება/დამალვა", "toggleParameters": "პარამეტრების ჩვენება/დამალვა", "toggleLinks": "ბმულების ჩვენება/დამალვა", - "backToTree": "ხეზე დაბრუნება" + "backToTree": "ხეზე დაბრუნება", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/kr.json b/packages/web-awesome/src/locales/kr.json index 8642eca8bc4..9dd46f5aa7f 100644 --- a/packages/web-awesome/src/locales/kr.json +++ b/packages/web-awesome/src/locales/kr.json @@ -22,7 +22,8 @@ "globalAttachments": "전역 첨부파일", "globalErrors": "전역 오류", "qualityGates": "품질 게이트", - "categories": "카테고리" + "categories": "카테고리", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "검색", @@ -56,7 +57,18 @@ "regressed": "\"통과\" 또는 \"손상됨\" 상태에서 \"실패\" 상태로 변경된 테스트 결과를 표시합니다", "malfunctioned": "\"통과\" 또는 \"실패\" 상태에서 \"손상됨\" 상태로 변경된 테스트 결과를 표시합니다", "tags": "지정된 태그가 있는 테스트 결과를 표시합니다", - "categories": "지정된 카테고리가 있는 테스트 결과를 표시합니다" + "categories": "지정된 카테고리가 있는 테스트 결과를 표시합니다", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "테스트 케이스 결과가 없습니다", "no-environments-results": "환경 정보를 사용할 수 없습니다", "no-categories-results": "사용 가능한 카테고리가 없습니다", - "no-metrics-results": "사용 가능한 메트릭이 없습니다" + "no-metrics-results": "사용 가능한 메트릭이 없습니다", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "차단자", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "브라우저가 Playwright Trace Viewer 열기를 차단했습니다.", "pwTracePopupBlockedHint": "팝업을 허용한 뒤 다시 시도하세요.", "finishedAtOriginal": "{{formattedCreatedAt}}, 종료 코드 {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, 종료 코드 {{actual}} (원본 {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, 종료 코드 {{actual}} (원본 {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "첨부파일을 새 탭에서 열기", @@ -432,7 +446,12 @@ "regressed": "이전에 \"통과\" 또는 \"손상됨\"이었던 테스트가 이제 \"실패\"됨", "malfunctioned": "이전에 \"통과\" 또는 \"실패\"였던 테스트가 이제 \"손상됨\"됨", "retries": "{{count}}회 재시도", - "flaky": "실행마다 결과가 불안정함" + "flaky": "실행마다 결과가 불안정함", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "새로운", "fixed": "수정됨", @@ -511,6 +530,7 @@ "testTabNext": "다음 테스트 탭", "testTabPrev": "이전 테스트 탭", "tabOverview": "개요 탭", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "기록 탭", "tabRetries": "재시도 탭", "tabAttachments": "첨부 파일 탭", @@ -518,7 +538,8 @@ "toggleLabels": "레이블 표시/숨기기", "toggleParameters": "파라미터 표시/숨기기", "toggleLinks": "링크 표시/숨기기", - "backToTree": "트리로 돌아가기" + "backToTree": "트리로 돌아가기", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/nl.json b/packages/web-awesome/src/locales/nl.json index 52c14da623b..795eff6706e 100644 --- a/packages/web-awesome/src/locales/nl.json +++ b/packages/web-awesome/src/locales/nl.json @@ -22,7 +22,8 @@ "globalAttachments": "Globale Bijlagen", "globalErrors": "Globale Fouten", "qualityGates": "Kwaliteitspoorten", - "categories": "Categorieën" + "categories": "Categorieën", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Zoeken", @@ -56,7 +57,18 @@ "regressed": "Toont testresultaten die zijn gewijzigd van \"geslaagd\" of \"gebroken\" naar \"mislukt\" status", "malfunctioned": "Toont testresultaten die zijn gewijzigd van \"geslaagd\" of \"mislukt\" naar \"gebroken\" status", "tags": "Toont testresultaten die de opgegeven tags hebben", - "categories": "Toont testresultaten die de opgegeven categorieën hebben" + "categories": "Toont testresultaten die de opgegeven categorieën hebben", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Geen testresultaten", "no-environments-results": "Geen informatie over omgevingen beschikbaar", "no-categories-results": "Geen categorieresultaten beschikbaar", - "no-metrics-results": "Geen metrieken beschikbaar" + "no-metrics-results": "Geen metrieken beschikbaar", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "blokkerend", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "De browser heeft het openen van Playwright Trace Viewer geblokkeerd.", "pwTracePopupBlockedHint": "Sta pop-ups toe en probeer het opnieuw.", "finishedAtOriginal": "{{formattedCreatedAt}}, met exitcode {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, met exitcode {{actual}} (oorspronkelijk {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, met exitcode {{actual}} (oorspronkelijk {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Bijlage openen in nieuw tabblad", @@ -432,7 +446,12 @@ "regressed": "Eerder \"geslaagd\" of \"gebroken\" test die nu \"mislukt\" is", "malfunctioned": "Eerder \"geslaagd\" of \"mislukt\" test die nu \"gebroken\" is", "retries": "{{count}} pogingen", - "flaky": "Inconsistent tussen runs" + "flaky": "Inconsistent tussen runs", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Nieuw", "fixed": "Opgelost", @@ -511,6 +530,7 @@ "testTabNext": "Volgende testtab", "testTabPrev": "Vorige testtab", "tabOverview": "Tab overzicht", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Tab geschiedenis", "tabRetries": "Tab nieuwe pogingen", "tabAttachments": "Tab bijlagen", @@ -518,7 +538,8 @@ "toggleLabels": "Labels tonen/verbergen", "toggleParameters": "Parameters tonen/verbergen", "toggleLinks": "Links tonen/verbergen", - "backToTree": "Terug naar boom" + "backToTree": "Terug naar boom", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/pl.json b/packages/web-awesome/src/locales/pl.json index f8d7e6378dd..171e5e57acb 100644 --- a/packages/web-awesome/src/locales/pl.json +++ b/packages/web-awesome/src/locales/pl.json @@ -22,7 +22,8 @@ "globalAttachments": "Globalne Załączniki", "globalErrors": "Globalne Błędy", "qualityGates": "Bramy Jakości", - "categories": "Kategorie" + "categories": "Kategorie", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Poszukiwanie", @@ -56,7 +57,18 @@ "regressed": "Pokaż wyniki testów, które zmieniły status z \"udany\" lub \"uszkodzony\" na \"nieudany\"", "malfunctioned": "Pokaż wyniki testów, które zmieniły status z \"udany\" lub \"nieudany\" na \"uszkodzony\"", "tags": "Pokaż wyniki testów, które mają określone tagi", - "categories": "Pokaż wyniki testów, które mają określone kategorie" + "categories": "Pokaż wyniki testów, które mają określone kategorie", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Brak wyników przypadków testowych", "no-environments-results": "Brak dostępnych informacji o środowiskach", "no-categories-results": "Brak dostępnych wyników kategorii", - "no-metrics-results": "Brak dostępnych metryk" + "no-metrics-results": "Brak dostępnych metryk", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "bloker", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Przeglądarka zablokowała otwarcie Playwright Trace Viewer.", "pwTracePopupBlockedHint": "Zezwól na wyskakujące okna i spróbuj ponownie.", "finishedAtOriginal": "{{formattedCreatedAt}}, z kodem wyjścia {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, z kodem wyjścia {{actual}} (oryginalny {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, z kodem wyjścia {{actual}} (oryginalny {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Otwórz w nowej zakładce", @@ -440,7 +454,12 @@ "regressed": "Wcześniej \"udany\" lub \"uszkodzony\" test, który teraz jest \"nieudany\"", "malfunctioned": "Wcześniej \"udany\" lub \"nieudany\" test, który teraz jest \"uszkodzony\"", "retries": "{{count}} ponowień", - "flaky": "Niespójny pomiędzy uruchomieniami" + "flaky": "Niespójny pomiędzy uruchomieniami", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Nowe", "fixed": "Naprawione", @@ -519,6 +538,7 @@ "testTabNext": "Następna zakładka testu", "testTabPrev": "Poprzednia zakładka testu", "tabOverview": "Zakładka przegląd", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Zakładka historia", "tabRetries": "Zakładka ponowienia", "tabAttachments": "Zakładka załączniki", @@ -526,7 +546,8 @@ "toggleLabels": "Pokaż/ukryj etykiety", "toggleParameters": "Pokaż/ukryj parametry", "toggleLinks": "Pokaż/ukryj łącza", - "backToTree": "Powrót do drzewa" + "backToTree": "Powrót do drzewa", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/pt.json b/packages/web-awesome/src/locales/pt.json index 35cbb4d7855..fa980141ea3 100644 --- a/packages/web-awesome/src/locales/pt.json +++ b/packages/web-awesome/src/locales/pt.json @@ -22,7 +22,8 @@ "globalAttachments": "Anexos Globais", "globalErrors": "Erros Globais", "qualityGates": "Portões de Qualidade", - "categories": "Categorias" + "categories": "Categorias", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Pesquisar", @@ -56,7 +57,18 @@ "regressed": "Mostra resultados de testes que mudaram de status \"aprovado\" ou \"quebrado\" para \"falhou\"", "malfunctioned": "Mostra resultados de testes que mudaram de status \"aprovado\" ou \"falhou\" para \"quebrado\"", "tags": "Mostra resultados de testes que têm as tags especificadas", - "categories": "Mostra resultados de testes que têm as categorias especificadas" + "categories": "Mostra resultados de testes que têm as categorias especificadas", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Nenhum resultado de caso de teste", "no-environments-results": "Nenhuma informação de ambiente disponível", "no-categories-results": "Nenhum resultado de categorias disponível", - "no-metrics-results": "Nenhuma métrica disponível" + "no-metrics-results": "Nenhuma métrica disponível", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "bloqueador", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "O navegador bloqueou a abertura do Playwright Trace Viewer.", "pwTracePopupBlockedHint": "Permita pop-ups e tente novamente.", "finishedAtOriginal": "{{formattedCreatedAt}}, com código de saída {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, com código de saída {{actual}} (original {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, com código de saída {{actual}} (original {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Abrir anexo em nova aba", @@ -432,7 +446,12 @@ "regressed": "Teste anteriormente \"aprovado\" ou \"quebrado\" que agora está \"falhou\"", "malfunctioned": "Teste anteriormente \"aprovado\" ou \"falhou\" que agora está \"quebrado\"", "retries": "{{count}} tentativas", - "flaky": "Inconsistente entre execuções" + "flaky": "Inconsistente entre execuções", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Novo", "fixed": "Corrigido", @@ -511,6 +530,7 @@ "testTabNext": "Próxima aba de teste", "testTabPrev": "Aba de teste anterior", "tabOverview": "Aba visão geral", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Aba histórico", "tabRetries": "Aba tentativas", "tabAttachments": "Aba anexos", @@ -518,7 +538,8 @@ "toggleLabels": "Mostrar/ocultar etiquetas", "toggleParameters": "Mostrar/ocultar parâmetros", "toggleLinks": "Mostrar/ocultar links", - "backToTree": "Voltar à árvore" + "backToTree": "Voltar à árvore", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/ru.json b/packages/web-awesome/src/locales/ru.json index f0c4c5ab8ea..674de48d94e 100644 --- a/packages/web-awesome/src/locales/ru.json +++ b/packages/web-awesome/src/locales/ru.json @@ -22,7 +22,8 @@ "globalAttachments": "Глобальные Вложения", "globalErrors": "Глобальные Ошибки", "qualityGates": "Ворота Качества", - "categories": "Категории" + "categories": "Категории", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Поиск", @@ -56,7 +57,18 @@ "regressed": "Показать результаты тестов, которые изменили статус на \"неуспешный\" с \"успешный\" или \"сломанный\"", "malfunctioned": "Показать результаты тестов, которые изменили статус на \"сломанный\" с \"успешный\" или \"неуспешный\"", "tags": "Показать результаты тестов, которые имеют указанные теги", - "categories": "Показать результаты тестов, которые имеют указанные категории" + "categories": "Показать результаты тестов, которые имеют указанные категории", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Нет результатов тест-кейсов", "no-environments-results": "Информация об окружениях отсутствует", "no-categories-results": "Нет доступных результатов по категориям", - "no-metrics-results": "Метрики отсутствуют" + "no-metrics-results": "Метрики отсутствуют", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "блокер", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Браузер заблокировал открытие Playwright Trace Viewer.", "pwTracePopupBlockedHint": "Разрешите всплывающие окна и повторите попытку.", "finishedAtOriginal": "{{formattedCreatedAt}}, с кодом выхода {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, с кодом выхода {{actual}} (первоначальный {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, с кодом выхода {{actual}} (первоначальный {{original}})", + "resolutionCategories": "Resolution Categories" }, "shortcuts": { "title": "Горячие клавиши", @@ -212,6 +226,7 @@ "testTabNext": "Следующая вкладка теста", "testTabPrev": "Предыдущая вкладка теста", "tabOverview": "Вкладка обзор", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Вкладка история", "tabRetries": "Вкладка перезапуски", "tabAttachments": "Вкладка вложения", @@ -219,7 +234,8 @@ "toggleLabels": "Показать/скрыть лейблы", "toggleParameters": "Показать/скрыть параметры", "toggleLinks": "Показать/скрыть ссылки", - "backToTree": "Назад к дереву" + "backToTree": "Назад к дереву", + "reportTabResolutionCategories": "Report tab: Resolution categories" } }, "controls": { @@ -500,7 +516,12 @@ "regressed": "Ранее \"успешный\" или \"сломанный\" тест, который теперь \"неуспешный\"", "malfunctioned": "Ранее \"успешный\" или \"неуспешный\" тест, который теперь \"сломанный\"", "retries": "{{count}} повторов", - "flaky": "Нестабилен между запусками" + "flaky": "Нестабилен между запусками", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Новые", "fixed": "Исправленные", diff --git a/packages/web-awesome/src/locales/sv.json b/packages/web-awesome/src/locales/sv.json index 64a49c6b06d..d9300f06207 100644 --- a/packages/web-awesome/src/locales/sv.json +++ b/packages/web-awesome/src/locales/sv.json @@ -22,7 +22,8 @@ "globalAttachments": "Globala Bilagor", "globalErrors": "Globala Fel", "qualityGates": "Kvalitetsportar", - "categories": "Kategorier" + "categories": "Kategorier", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Sök", @@ -56,7 +57,18 @@ "regressed": "Visa testresultat som ändrades från \"godkänd\" eller \"trasig\" till \"misslyckad\" status", "malfunctioned": "Visa testresultat som ändrades från \"godkänd\" eller \"misslyckad\" till \"trasig\" status", "tags": "Visa testresultat som har de angivna taggarna", - "categories": "Visa testresultat som har de angivna kategorierna" + "categories": "Visa testresultat som har de angivna kategorierna", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Inga testfallresultat", "no-environments-results": "Ingen miljöinformation tillgänglig", "no-categories-results": "Inga kategoriresultat tillgängliga", - "no-metrics-results": "Inga mått tillgängliga" + "no-metrics-results": "Inga mått tillgängliga", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "blockerare", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Webbläsaren blockerade öppning av Playwright Trace Viewer.", "pwTracePopupBlockedHint": "Tillåt popup-fönster och försök igen.", "finishedAtOriginal": "{{formattedCreatedAt}}, med avslutningskod {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, med avslutningskod {{actual}} (ursprunglig {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, med avslutningskod {{actual}} (ursprunglig {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Öppna bilaga i ny flik", @@ -432,7 +446,12 @@ "regressed": "Tidigare \"godkänd\" eller \"trasig\" test som nu är \"misslyckad\"", "malfunctioned": "Tidigare \"godkänd\" eller \"misslyckad\" test som nu är \"trasig\"", "retries": "{{count}} omkörningar", - "flaky": "Inkonsekvent mellan körningar" + "flaky": "Inkonsekvent mellan körningar", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Ny", "fixed": "Åtgärdad", @@ -511,6 +530,7 @@ "testTabNext": "Nästa testflik", "testTabPrev": "Föregående testflik", "tabOverview": "Flik översikt", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Flik historik", "tabRetries": "Flik omförsök", "tabAttachments": "Flik bilagor", @@ -518,7 +538,8 @@ "toggleLabels": "Visa/dölj etiketter", "toggleParameters": "Visa/dölj parametrar", "toggleLinks": "Visa/dölj länkar", - "backToTree": "Tillbaka till trädet" + "backToTree": "Tillbaka till trädet", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/tr.json b/packages/web-awesome/src/locales/tr.json index abfc2dceddd..33b5c5c114e 100644 --- a/packages/web-awesome/src/locales/tr.json +++ b/packages/web-awesome/src/locales/tr.json @@ -22,7 +22,8 @@ "globalAttachments": "Küresel Ekler", "globalErrors": "Küresel Hatalar", "qualityGates": "Kalite Kapıları", - "categories": "Kategoriler" + "categories": "Kategoriler", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Ara", @@ -56,7 +57,18 @@ "regressed": "\"başarılı\" veya \"bozuk\" durumundan \"başarısız\" durumuna değişen test sonuçlarını göster", "malfunctioned": "\"başarılı\" veya \"başarısız\" durumundan \"bozuk\" durumuna değişen test sonuçlarını göster", "tags": "Belirtilen etiketlere sahip test sonuçlarını göster", - "categories": "Belirtilen kategorilere sahip test sonuçlarını göster" + "categories": "Belirtilen kategorilere sahip test sonuçlarını göster", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Test vakası sonuçları yok", "no-environments-results": "Ortam bilgisi mevcut değil", "no-categories-results": "Kategoriler için sonuç bulunamadı", - "no-metrics-results": "Kullanılabilir metrik yok" + "no-metrics-results": "Kullanılabilir metrik yok", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "engelleyici", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Tarayıcı Playwright Trace Viewer’ın açılmasını engelledi.", "pwTracePopupBlockedHint": "Açılır pencerelere izin verip tekrar deneyin.", "finishedAtOriginal": "{{formattedCreatedAt}}, çıkış kodu {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, çıkış kodu {{actual}} (orijinal {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, çıkış kodu {{actual}} (orijinal {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Eki yeni sekmede aç", @@ -432,7 +446,12 @@ "regressed": "Daha önce \"başarılı\" veya \"bozuk\" olan test artık \"başarısız\"", "malfunctioned": "Daha önce \"başarılı\" veya \"başarısız\" olan test artık \"bozuk\"", "retries": "{{count}} yeniden deneme", - "flaky": "Çalıştırmalar arasında tutarsız" + "flaky": "Çalıştırmalar arasında tutarsız", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Yeni", "fixed": "Düzeltildi", @@ -511,6 +530,7 @@ "testTabNext": "Sonraki test sekmesi", "testTabPrev": "Önceki test sekmesi", "tabOverview": "Genel bakış sekmesi", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Geçmiş sekmesi", "tabRetries": "Yeniden denemeler sekmesi", "tabAttachments": "Ekler sekmesi", @@ -518,7 +538,8 @@ "toggleLabels": "Etiketleri göster/gizle", "toggleParameters": "Parametreleri göster/gizle", "toggleLinks": "Bağlantıları göster/gizle", - "backToTree": "Ağaca geri dön" + "backToTree": "Ağaca geri dön", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/uk.json b/packages/web-awesome/src/locales/uk.json index cdd4692c8a0..d26ac51a963 100644 --- a/packages/web-awesome/src/locales/uk.json +++ b/packages/web-awesome/src/locales/uk.json @@ -22,7 +22,8 @@ "globalAttachments": "Глобальні Вкладення", "globalErrors": "Глобальні Помилки", "qualityGates": "Ворота Якості", - "categories": "Категорії" + "categories": "Категорії", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "Пошук", @@ -56,7 +57,18 @@ "regressed": "Показати результати тестів, які змінили статус на \"неуспішний\" з \"успішний\" або \"зламаний\"", "malfunctioned": "Показати результати тестів, які змінили статус на \"зламаний\" з \"успішний\" або \"неуспішний\"", "tags": "Показати результати тестів, які мають вказані теги", - "categories": "Показати результати тестів, які мають зазначені категорії" + "categories": "Показати результати тестів, які мають зазначені категорії", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "Немає результатів тест-кейсів", "no-environments-results": "Інформація про оточення відсутня", "no-categories-results": "Немає доступних результатів за категоріями", - "no-metrics-results": "Немає доступних метрик" + "no-metrics-results": "Немає доступних метрик", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "блокер", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "Браузер заблокував відкриття Playwright Trace Viewer.", "pwTracePopupBlockedHint": "Дозвольте спливні вікна та повторіть спробу.", "finishedAtOriginal": "{{formattedCreatedAt}}, з кодом виходу {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}}, з кодом виходу {{actual}} (первісний {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}}, з кодом виходу {{actual}} (первісний {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "Відкрити в новій вкладці", @@ -383,7 +397,12 @@ "regressed": "Раніше \"успішний\" або \"зламаний\" тест, який тепер \"неуспішний\"", "malfunctioned": "Раніше \"успішний\" або \"неуспішний\" тест, який тепер \"зламаний\"", "retries": "{{count}} повторних спроб", - "flaky": "Нестабільний між запусками" + "flaky": "Нестабільний між запусками", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "Нові", "fixed": "Виправлені", @@ -462,6 +481,7 @@ "testTabNext": "Наступна вкладка тесту", "testTabPrev": "Попередня вкладка тесту", "tabOverview": "Вкладка огляд", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "Вкладка історія", "tabRetries": "Вкладка повтори", "tabAttachments": "Вкладка вкладення", @@ -469,7 +489,8 @@ "toggleLabels": "Показати/приховати мітки", "toggleParameters": "Показати/приховати параметри", "toggleLinks": "Показати/приховати посилання", - "backToTree": "Назад до дерева" + "backToTree": "Назад до дерева", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/zh-TW.json b/packages/web-awesome/src/locales/zh-TW.json index 062b593c934..a3e28a830d6 100644 --- a/packages/web-awesome/src/locales/zh-TW.json +++ b/packages/web-awesome/src/locales/zh-TW.json @@ -22,7 +22,8 @@ "globalAttachments": "全域附件", "globalErrors": "全域錯誤", "qualityGates": "品質卡點", - "categories": "分類" + "categories": "分類", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "搜尋", @@ -56,7 +57,18 @@ "regressed": "顯示從「通過」或「損壞」狀態變為「失敗」狀態的測試結果", "malfunctioned": "顯示從「通過」或「失敗」狀態變為「損壞」狀態的測試結果", "tags": "顯示具有指定標籤的測試結果", - "categories": "顯示具有指定分類的測試結果" + "categories": "顯示具有指定分類的測試結果", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "沒有測試案例結果", "no-environments-results": "沒有環境資訊", "no-categories-results": "暫無可用的分類結果", - "no-metrics-results": "沒有可用指標" + "no-metrics-results": "沒有可用指標", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "阻礙", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "瀏覽器封鎖了開啟 Playwright Trace Viewer。", "pwTracePopupBlockedHint": "請允許彈出視窗後重試。", "finishedAtOriginal": "{{formattedCreatedAt}},結束代碼 {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}},結束代號 {{actual}}(原始 {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}},結束代號 {{actual}}(原始 {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "在新分頁中開啟附件", @@ -432,7 +446,12 @@ "regressed": "之前「通過」或「損壞」的測試現在「失敗」了", "malfunctioned": "之前「通過」或「失敗」的測試現在「損壞」了", "retries": "{{count}} 次重試", - "flaky": "多次執行結果不一致" + "flaky": "多次執行結果不一致", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "新的", "fixed": "已修復", @@ -511,6 +530,7 @@ "testTabNext": "下一個測試標籤", "testTabPrev": "上一個測試標籤", "tabOverview": "概覽標籤", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "歷史標籤", "tabRetries": "重試標籤", "tabAttachments": "附件標籤", @@ -518,7 +538,8 @@ "toggleLabels": "顯示/隱藏標籤", "toggleParameters": "顯示/隱藏參數", "toggleLinks": "顯示/隱藏連結", - "backToTree": "返回樹狀結構" + "backToTree": "返回樹狀結構", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/locales/zh.json b/packages/web-awesome/src/locales/zh.json index f29f0e94e7e..b7150542a7f 100644 --- a/packages/web-awesome/src/locales/zh.json +++ b/packages/web-awesome/src/locales/zh.json @@ -22,7 +22,8 @@ "globalAttachments": "全局附件", "globalErrors": "全局错误", "qualityGates": "质量门", - "categories": "分类" + "categories": "分类", + "resolutionCategories": "Resolution Categories" }, "search": { "search": "搜索", @@ -56,7 +57,18 @@ "regressed": "显示从\"通过\"或\"损坏\"状态变为\"失败\"状态的测试结果", "malfunctioned": "显示从\"通过\"或\"失败\"状态变为\"损坏\"状态的测试结果", "tags": "显示具有指定标签的测试结果", - "categories": "显示具有指定分类的测试结果" + "categories": "显示具有指定分类的测试结果", + "resolution": { + "issue": "Show issue-linked test results", + "muted": "Show muted test results", + "accepted": "Show accepted test results" + } + }, + "resolution": "Resolution", + "resolutions": { + "issue": "Issue", + "muted": "Muted", + "accepted": "Accepted" } }, "sort-by": { @@ -112,7 +124,8 @@ "no-test-case-results": "没有测试用例结果", "no-environments-results": "没有环境信息", "no-categories-results": "暂无可用的分类结果", - "no-metrics-results": "没有可用指标" + "no-metrics-results": "没有可用指标", + "no-resolution-categories-results": "No resolution categories available" }, "severity": { "blocker": "阻断", @@ -160,7 +173,8 @@ "pwTracePopupBlocked": "浏览器阻止了打开 Playwright Trace Viewer。", "pwTracePopupBlockedHint": "请允许弹出窗口后重试。", "finishedAtOriginal": "{{formattedCreatedAt}},退出代码 {{original}}", - "finishedAtBoth": "{{formattedCreatedAt}},退出代码 {{actual}}(原始 {{original}})" + "finishedAtBoth": "{{formattedCreatedAt}},退出代码 {{actual}}(原始 {{original}})", + "resolutionCategories": "Resolution Categories" }, "controls": { "newTabAttachment": "在新标签页中打开附件", @@ -432,7 +446,12 @@ "regressed": "之前\"通过\"或\"损坏\"的测试现在\"失败\"了", "malfunctioned": "之前\"通过\"或\"失败\"的测试现在\"损坏\"了", "retries": "{{count}} 次重试", - "flaky": "多次运行结果不一致" + "flaky": "多次运行结果不一致", + "resolution": { + "issue": "Linked to an issue", + "muted": "Muted test result", + "accepted": "Accepted test result" + } }, "new": "新的", "fixed": "已修复", @@ -511,6 +530,7 @@ "testTabNext": "下一个测试标签页", "testTabPrev": "上一个测试标签页", "tabOverview": "概览标签页", + "tabResolutionCategories": "Resolution Categories tab", "tabHistory": "历史标签页", "tabRetries": "重试标签页", "tabAttachments": "附件标签页", @@ -518,7 +538,8 @@ "toggleLabels": "显示/隐藏标签", "toggleParameters": "显示/隐藏参数", "toggleLinks": "显示/隐藏链接", - "backToTree": "返回树形结构" + "backToTree": "返回树形结构", + "reportTabResolutionCategories": "Report tab: Resolution categories" } } } diff --git a/packages/web-awesome/src/stores/chart.ts b/packages/web-awesome/src/stores/chart.ts index 495a760989c..bc58fc2ccae 100644 --- a/packages/web-awesome/src/stores/chart.ts +++ b/packages/web-awesome/src/stores/chart.ts @@ -1,7 +1,6 @@ import type { PieChartValues } from "@allurereport/charts-api"; -import { type Statistic } from "@allurereport/core-api"; import type { ChartsResponse, UIChartsDataWithEnvs } from "@allurereport/web-commons"; -import { createChartsWithEnvs, fetchReportJsonData, getPieChartValues } from "@allurereport/web-commons"; +import { createChartsWithEnvs, fetchReportJsonData } from "@allurereport/web-commons"; import { signal } from "@preact/signals"; import type { StoreSignalState } from "@/stores/types"; @@ -20,12 +19,15 @@ export const fetchPieChartData = async (env: string) => { }; try { - const res = await fetchReportJsonData(env ? `widgets/${env}/statistic.json` : "widgets/statistic.json", { - bustCache: true, - }); + const res = await fetchReportJsonData( + env ? `widgets/${env}/pie_chart.json` : "widgets/pie_chart.json", + { + bustCache: true, + }, + ); pieChartStore.value = { - data: getPieChartValues(res), + data: res, error: undefined, loading: false, }; diff --git a/packages/web-awesome/src/stores/keyboardActions.ts b/packages/web-awesome/src/stores/keyboardActions.ts index 4adcb1f65fe..ae1c38a9789 100644 --- a/packages/web-awesome/src/stores/keyboardActions.ts +++ b/packages/web-awesome/src/stores/keyboardActions.ts @@ -52,7 +52,12 @@ import { toggleTestResultFocusNode, } from "@/stores/testResultOverviewNav"; import { testResultNavStore, testResultStore } from "@/stores/testResults"; -import { cycleTestResultTab, navigateToTestResultTabById, TEST_RESULT_TAB } from "@/stores/testResultTabs"; +import { + cycleTestResultTab, + getTestResultTabForTestResultId, + navigateToTestResultTabById, + TEST_RESULT_TAB, +} from "@/stores/testResultTabs"; import { filteredTree, isTreeOpened, setTreeOpened, toggleTree } from "@/stores/tree"; const isTestResultRoute = computed( @@ -551,7 +556,7 @@ export const openTestResultFromTree = () => { return; } - navigateToTestResult({ testResultId: node.testResultId, tab: trCurrentTab.value }); + navigateToTestResult({ testResultId: node.testResultId, tab: getTestResultTabForTestResultId(node.testResultId) }); if (isSplitMode.value) { focusTestResultPane(); @@ -634,7 +639,7 @@ export const goToPrevTestResult = () => { return; } - navigateToTestResult({ testResultId: prevId, tab: trCurrentTab.value }); + navigateToTestResult({ testResultId: prevId, tab: getTestResultTabForTestResultId(prevId) }); setTreeFocusId(undefined); }; @@ -662,7 +667,7 @@ export const goToNextTestResult = () => { return; } - navigateToTestResult({ testResultId: nextId, tab: trCurrentTab.value }); + navigateToTestResult({ testResultId: nextId, tab: getTestResultTabForTestResultId(nextId) }); setTreeFocusId(undefined); }; diff --git a/packages/web-awesome/src/stores/reportRootTabs.ts b/packages/web-awesome/src/stores/reportRootTabs.ts index aea0686e4b3..96e09864969 100644 --- a/packages/web-awesome/src/stores/reportRootTabs.ts +++ b/packages/web-awesome/src/stores/reportRootTabs.ts @@ -1,4 +1,5 @@ import { categoriesStore } from "@/stores/categories"; +import { resolutionCategoriesStore } from "@/stores/resolutionCategories"; import { navigateToPlainTestResult, navigateToRoot, @@ -14,6 +15,7 @@ export const REPORT_ROOT_TAB = { QualityGate: "qualityGate", GlobalAttachments: "globalAttachments", GlobalErrors: "globalErrors", + ResolutionCategories: "resolutionCategories", } as const; export type ReportRootTabId = (typeof REPORT_ROOT_TAB)[keyof typeof REPORT_ROOT_TAB]; @@ -21,24 +23,27 @@ export type ReportRootTabId = (typeof REPORT_ROOT_TAB)[keyof typeof REPORT_ROOT_ const REPORT_ROOT_TAB_ORDER: ReportRootTabId[] = [ REPORT_ROOT_TAB.Results, REPORT_ROOT_TAB.Categories, + REPORT_ROOT_TAB.ResolutionCategories, REPORT_ROOT_TAB.QualityGate, REPORT_ROOT_TAB.GlobalAttachments, REPORT_ROOT_TAB.GlobalErrors, ]; export const getAvailableReportRootTabs = (): ReportRootTabId[] => { - const tabs: ReportRootTabId[] = [ - REPORT_ROOT_TAB.Results, - REPORT_ROOT_TAB.QualityGate, - REPORT_ROOT_TAB.GlobalAttachments, - REPORT_ROOT_TAB.GlobalErrors, - ]; + const tabs: ReportRootTabId[] = [REPORT_ROOT_TAB.Results]; const categories = categoriesStore.value.data; + const resolutionCategories = resolutionCategoriesStore.value.data; if (categories?.roots?.length) { - tabs.splice(1, 0, REPORT_ROOT_TAB.Categories); + tabs.push(REPORT_ROOT_TAB.Categories); } + if (resolutionCategories?.groups.length) { + tabs.push(REPORT_ROOT_TAB.ResolutionCategories); + } + + tabs.push(REPORT_ROOT_TAB.QualityGate, REPORT_ROOT_TAB.GlobalAttachments, REPORT_ROOT_TAB.GlobalErrors); + return tabs; }; diff --git a/packages/web-awesome/src/stores/resolutionCategories.ts b/packages/web-awesome/src/stores/resolutionCategories.ts new file mode 100644 index 00000000000..1a8f51691e3 --- /dev/null +++ b/packages/web-awesome/src/stores/resolutionCategories.ts @@ -0,0 +1,62 @@ +import { ReportFetchError, errorMessageFromUnknown, fetchReportJsonData } from "@allurereport/web-commons"; +import { signal } from "@preact/signals"; +import type { AwesomeResolutionCategories } from "types"; + +import type { StoreSignalState } from "@/stores/types"; + +export const resolutionCategoriesStore = signal>({ + loading: true, + error: undefined, + data: undefined, +}); + +let lastResolutionCategoriesEnv: string | undefined; + +const emptyResolutionCategories: AwesomeResolutionCategories = { + groups: [], +}; + +const resolveResolutionCategoriesPath = (env?: string) => + env ? `widgets/${env}/resolution-categories.json` : "widgets/resolution-categories.json"; + +const isMissingResolutionCategoriesError = (error: unknown) => + error instanceof ReportFetchError && error.response.status === 404; + +export const fetchResolutionCategoriesData = async (env?: string) => { + if (lastResolutionCategoriesEnv === env && resolutionCategoriesStore.peek().data) { + return; + } + + lastResolutionCategoriesEnv = env; + resolutionCategoriesStore.value = { + ...resolutionCategoriesStore.value, + loading: true, + error: undefined, + }; + + try { + const data = await fetchReportJsonData(resolveResolutionCategoriesPath(env)); + + resolutionCategoriesStore.value = { + data, + error: undefined, + loading: false, + }; + } catch (error) { + if (isMissingResolutionCategoriesError(error)) { + resolutionCategoriesStore.value = { + data: emptyResolutionCategories, + error: undefined, + loading: false, + }; + return; + } + + resolutionCategoriesStore.value = { + data: undefined, + error: errorMessageFromUnknown(error), + loading: false, + }; + lastResolutionCategoriesEnv = undefined; + } +}; diff --git a/packages/web-awesome/src/stores/router.ts b/packages/web-awesome/src/stores/router.ts index a0c2ecaab02..4666a656087 100644 --- a/packages/web-awesome/src/stores/router.ts +++ b/packages/web-awesome/src/stores/router.ts @@ -56,7 +56,7 @@ export const navigateToSection = (params: { section: SectionRouteName }) => { routerNavigateTo({ path: "/:section", params, keepSearchParams: true, replace: false }); }; -const rootTabs = ["categories", "qualityGate", "globalAttachments", "globalErrors"]; +const rootTabs = ["categories", "qualityGate", "globalAttachments", "globalErrors", "resolutionCategories"]; export const rootTabRoute = computed(() => createRoute<{ rootTab: string; testResultId?: string; tab?: string }>( diff --git a/packages/web-awesome/src/stores/testResultTabs.ts b/packages/web-awesome/src/stores/testResultTabs.ts index 412e1c06654..36df8009040 100644 --- a/packages/web-awesome/src/stores/testResultTabs.ts +++ b/packages/web-awesome/src/stores/testResultTabs.ts @@ -1,8 +1,12 @@ +import { currentEnvironment } from "@/stores/env"; import { navigateToTestResultTab } from "@/stores/router"; import { currentTrId, trCurrentTab } from "@/stores/testResult"; +import { testResultStore } from "@/stores/testResults"; +import { treeStore } from "@/stores/tree"; export const TEST_RESULT_TAB = { Overview: "overview", + ResolutionCategories: "resolutionCategories", History: "history", Retries: "retries", Attachments: "attachments", @@ -13,22 +17,84 @@ export type TestResultTabId = (typeof TEST_RESULT_TAB)[keyof typeof TEST_RESULT_ const TEST_RESULT_TAB_ORDER: TestResultTabId[] = [ TEST_RESULT_TAB.Overview, + TEST_RESULT_TAB.ResolutionCategories, TEST_RESULT_TAB.History, TEST_RESULT_TAB.Retries, TEST_RESULT_TAB.Attachments, TEST_RESULT_TAB.Environments, ]; -export const getCurrentTestResultTab = (): TestResultTabId => { - const tab = trCurrentTab.value as TestResultTabId; +const TEST_RESULT_TABS_WITHOUT_RESOLUTION = TEST_RESULT_TAB_ORDER.filter( + (tab) => tab !== TEST_RESULT_TAB.ResolutionCategories, +); + +const getTreeLeafByTestResultId = (testResultId: string | undefined) => { + if (!testResultId) { + return undefined; + } + + const trees = treeStore.value.data; + + if (!trees) { + return undefined; + } + + const envIds = currentEnvironment.value ? [currentEnvironment.value] : Object.keys(trees); - if (TEST_RESULT_TAB_ORDER.includes(tab)) { - return tab; + for (const envId of envIds) { + const leavesById = trees[envId]?.leavesById; + + if (!leavesById) { + continue; + } + + const directLeaf = leavesById[testResultId]; + + if (directLeaf) { + return directLeaf; + } + + const leaf = Object.values(leavesById).find((item) => item.nodeId === testResultId); + + if (leaf) { + return leaf; + } + } + + return undefined; +}; + +const getAvailableTestResultTabs = (testResultId = currentTrId.value): TestResultTabId[] => { + const testResult = testResultId ? testResultStore.value.data?.[testResultId] : undefined; + + if (testResult) { + return testResult.resolution ? TEST_RESULT_TAB_ORDER : TEST_RESULT_TABS_WITHOUT_RESOLUTION; + } + + if (getTreeLeafByTestResultId(testResultId)?.resolution) { + return TEST_RESULT_TAB_ORDER; + } + + return TEST_RESULT_TABS_WITHOUT_RESOLUTION; +}; + +export const getTestResultTabForTestResultId = ( + testResultId: string | undefined, + tab = trCurrentTab.value, +): TestResultTabId => { + const nextTab = tab as TestResultTabId; + + if (getAvailableTestResultTabs(testResultId).includes(nextTab)) { + return nextTab; } return TEST_RESULT_TAB.Overview; }; +export const getCurrentTestResultTab = (): TestResultTabId => { + return getTestResultTabForTestResultId(currentTrId.value); +}; + export const navigateToTestResultTabById = (tab: TestResultTabId) => { const testResultId = currentTrId.value; @@ -36,6 +102,10 @@ export const navigateToTestResultTabById = (tab: TestResultTabId) => { return; } + if (!getAvailableTestResultTabs().includes(tab)) { + return; + } + if (tab === TEST_RESULT_TAB.Overview) { navigateToTestResultTab({ testResultId, tab: "" }); return; @@ -52,11 +122,9 @@ export const cycleTestResultTab = (direction: "next" | "prev") => { } const current = getCurrentTestResultTab(); - const index = TEST_RESULT_TAB_ORDER.indexOf(current); - const nextIndex = - direction === "next" - ? (index + 1) % TEST_RESULT_TAB_ORDER.length - : (index - 1 + TEST_RESULT_TAB_ORDER.length) % TEST_RESULT_TAB_ORDER.length; + const tabs = getAvailableTestResultTabs(); + const index = tabs.indexOf(current); + const nextIndex = direction === "next" ? (index + 1) % tabs.length : (index - 1 + tabs.length) % tabs.length; - navigateToTestResultTabById(TEST_RESULT_TAB_ORDER[nextIndex]!); + navigateToTestResultTabById(tabs[nextIndex]!); }; diff --git a/packages/web-awesome/src/stores/treeFilters/actions.ts b/packages/web-awesome/src/stores/treeFilters/actions.ts index 2762717682e..a393b5acd4e 100644 --- a/packages/web-awesome/src/stores/treeFilters/actions.ts +++ b/packages/web-awesome/src/stores/treeFilters/actions.ts @@ -1,4 +1,4 @@ -import type { TestStatus, TestStatusTransition } from "@allurereport/core-api"; +import type { ResolutionCategory, TestStatus, TestStatusTransition } from "@allurereport/core-api"; import { ReportFetchError, fetchReportJsonData, setParams } from "@allurereport/web-commons"; import { PARAMS } from "./constants"; @@ -33,6 +33,13 @@ export const setRetryFilter = (retry?: boolean) => { }); }; +export const setResolutionFilter = (resolution: ResolutionCategory[]) => { + setParams({ + key: PARAMS.RESOLUTION, + value: resolution, + }); +}; + export const setTransitionFilter = (transitions: TestStatusTransition[]) => { setParams({ key: PARAMS.TRANSITION, @@ -59,6 +66,7 @@ export const clearTreeFilterParams = () => { { key: PARAMS.QUERY, value: undefined }, { key: PARAMS.RETRY, value: undefined }, { key: PARAMS.FLAKY, value: undefined }, + { key: PARAMS.RESOLUTION, value: [] }, { key: PARAMS.TRANSITION, value: [] }, { key: PARAMS.TAGS, value: [] }, { key: PARAMS.CATEGORIES, value: [] }, diff --git a/packages/web-awesome/src/stores/treeFilters/constants.ts b/packages/web-awesome/src/stores/treeFilters/constants.ts index 21a2e820305..c5cb83b6ecb 100644 --- a/packages/web-awesome/src/stores/treeFilters/constants.ts +++ b/packages/web-awesome/src/stores/treeFilters/constants.ts @@ -1,13 +1,15 @@ -import type { TestStatus, TestStatusTransition } from "@allurereport/core-api"; +import type { ResolutionCategory, TestStatus, TestStatusTransition } from "@allurereport/core-api"; export const TRANSITIONS: TestStatusTransition[] = ["new", "fixed", "regressed", "malfunctioned"]; export const STATUSES: TestStatus[] = ["passed", "failed", "skipped", "broken", "unknown"]; +export const RESOLUTIONS: ResolutionCategory[] = ["issue", "muted", "accepted"]; export const PARAMS = { QUERY: "query", STATUS: "status", FLAKY: "flaky", RETRY: "retry", + RESOLUTION: "resolution", TRANSITION: "transition", TAGS: "tags", CATEGORIES: "categories", diff --git a/packages/web-awesome/src/stores/treeFilters/model.ts b/packages/web-awesome/src/stores/treeFilters/model.ts index 0c972fb0a22..8ad1a0572d4 100644 --- a/packages/web-awesome/src/stores/treeFilters/model.ts +++ b/packages/web-awesome/src/stores/treeFilters/model.ts @@ -1,4 +1,4 @@ -import type { TestStatus, TestStatusTransition } from "@allurereport/core-api"; +import type { ResolutionCategory, TestStatus, TestStatusTransition } from "@allurereport/core-api"; import type { ArrayField, BooleanField, @@ -14,6 +14,7 @@ export type Filters = { status?: TestStatus; flaky?: boolean; retry?: boolean; + resolution?: ResolutionCategory[]; transition?: TestStatusTransition[]; tags?: string[]; categories?: string[]; diff --git a/packages/web-awesome/src/stores/treeFilters/store.ts b/packages/web-awesome/src/stores/treeFilters/store.ts index ef26180857a..8c649c26143 100644 --- a/packages/web-awesome/src/stores/treeFilters/store.ts +++ b/packages/web-awesome/src/stores/treeFilters/store.ts @@ -1,4 +1,4 @@ -import type { TestStatus, TestStatusTransition } from "@allurereport/core-api"; +import type { ResolutionCategory, TestStatus, TestStatusTransition } from "@allurereport/core-api"; import { getParamValue, getParamValues } from "@allurereport/web-commons"; import { computed, signal } from "@preact/signals"; import type { ReportStatus } from "types"; @@ -8,6 +8,7 @@ import { setCategoriesFilter, setFlakyFilter, setQueryFilter, + setResolutionFilter, setRetryFilter, setStatusFilter, setTagsFilter, @@ -25,11 +26,13 @@ import { hasActiveFilters, isCategoryFilter, isFlakyFilter, + isResolutionFilter, isRetryFilter, isTagFilter, isTransitionFilter, validateStatus, validateTransition, + validateResolution, } from "./utils"; export const treeTags = signal([]); @@ -62,6 +65,18 @@ const urlStatusFilter = computed(() => { const urlFlakyFilter = computed(() => getParamValue(PARAMS.FLAKY) === "true"); const urlRetryFilter = computed(() => getParamValue(PARAMS.RETRY) === "true"); +const EMPTY_RESOLUTIONS: ResolutionCategory[] = []; + +const urlResolutionFilter = computed(() => { + const resolutions = getParamValues(PARAMS.RESOLUTION) ?? EMPTY_RESOLUTIONS; + + if (resolutions.length === 0) { + return EMPTY_RESOLUTIONS; + } + + return resolutions.filter((resolution) => validateResolution(resolution)); +}); + const EMPTY_TRANSITIONS: TestStatusTransition[] = []; const urlTransitionFilter = computed(() => { @@ -145,6 +160,22 @@ const treeFlakyFilter = computed(() => ({ }, })); +const treeResolutionFilter = computed(() => ({ + type: "group", + logicalOperator: "AND", + fieldKey: "resolution", + value: urlResolutionFilter.value.map((resolution) => ({ + type: "field", + logicalOperator: "OR", + value: { + key: "resolution", + value: resolution, + type: "string", + strict: true, + }, + })), +})); + const treeTransitionFilter = computed(() => ({ type: "group", logicalOperator: "AND", @@ -186,6 +217,7 @@ const treeCategoriesFilter = computed(() => ({ export const treeQuickFilters = computed(() => [ treeRetryFilter.value, treeFlakyFilter.value, + treeResolutionFilter.value, treeTransitionFilter.value, treeTagsFilter.value, treeCategoriesFilter.value, @@ -197,6 +229,7 @@ export const hasActiveTreeFilters = computed(() => status: urlStatusFilter.value, flaky: urlFlakyFilter.value, retry: urlRetryFilter.value, + resolution: urlResolutionFilter.value, transition: urlTransitionFilter.value, tags: urlTagsFilter.value, categories: urlCategoriesFilter.value, @@ -205,26 +238,30 @@ export const hasActiveTreeFilters = computed(() => export const treeNonQueryFilters = computed(() => { const filters: AwesomeFilter[] = []; + const markerFilters: AwesomeFilter[] = []; - const hasBothRetryAndFlaky = urlRetryFilter.value && urlFlakyFilter.value; + if (urlRetryFilter.value) { + markerFilters.push(treeRetryFilter.value); + } - if (hasBothRetryAndFlaky) { - filters.push({ - type: "group", - logicalOperator: "AND", - value: [ - { ...treeRetryFilter.value, logicalOperator: "OR" }, - { ...treeFlakyFilter.value, logicalOperator: "OR" }, - ], - }); + if (urlFlakyFilter.value) { + markerFilters.push(treeFlakyFilter.value); } - if (!hasBothRetryAndFlaky && urlRetryFilter.value) { - filters.push({ ...treeRetryFilter.value, logicalOperator: "AND" }); + if (urlResolutionFilter.value.length > 0) { + markerFilters.push(...treeResolutionFilter.value.value); } - if (!hasBothRetryAndFlaky && urlFlakyFilter.value) { - filters.push({ ...treeFlakyFilter.value, logicalOperator: "AND" }); + if (markerFilters.length === 1) { + filters.push({ ...markerFilters[0], logicalOperator: "AND" }); + } + + if (markerFilters.length > 1) { + filters.push({ + type: "group", + logicalOperator: "AND", + value: markerFilters.map((filter) => ({ ...filter, logicalOperator: "OR" })), + }); } if (urlTransitionFilter.value.length > 0) { @@ -267,6 +304,18 @@ export const setTreeFilter = (filter: AwesomeFilter) => { setFlakyFilter(filter.value.value); } + if (isResolutionFilter(filter)) { + const resolutions: ResolutionCategory[] = []; + + for (const v of filter.value) { + if (v.type === "field" && v.value.type === "string" && v.value.key === "resolution") { + resolutions.push(v.value.value as ResolutionCategory); + } + } + + setResolutionFilter(resolutions); + } + if ( isTagFilter(filter) && // Apply tags filter only if there are tags to filter by diff --git a/packages/web-awesome/src/stores/treeFilters/utils.ts b/packages/web-awesome/src/stores/treeFilters/utils.ts index 73c0e7fd51c..1f554221a23 100644 --- a/packages/web-awesome/src/stores/treeFilters/utils.ts +++ b/packages/web-awesome/src/stores/treeFilters/utils.ts @@ -1,7 +1,7 @@ -import type { TestStatus, TestStatusTransition } from "@allurereport/core-api"; +import type { ResolutionCategory, TestStatus, TestStatusTransition } from "@allurereport/core-api"; import { MAX_ARRAY_FIELD_VALUES, getCurrentUrl, goTo } from "@allurereport/web-commons"; -import { PARAMS, STATUSES, TRANSITIONS } from "./constants"; +import { PARAMS, RESOLUTIONS, STATUSES, TRANSITIONS } from "./constants"; import type { AwesomeArrayFieldFilter, AwesomeBooleanFieldFilter, @@ -35,6 +35,10 @@ export const validateStatus = (status: string): status is TestStatus => { return STATUSES.includes(status as TestStatus); }; +export const validateResolution = (resolution: string): resolution is ResolutionCategory => { + return RESOLUTIONS.includes(resolution as ResolutionCategory); +}; + export const migrateFilterParam = () => { if (typeof window === "undefined") { return; @@ -86,6 +90,7 @@ export const hasActiveFilters = (filters: Filters): boolean => { filters.status || filters.flaky || filters.retry || + (filters.resolution && filters.resolution.length > 0) || (filters.transition && filters.transition.length > 0) || (filters.tags && filters.tags.length > 0) || (filters.categories && filters.categories.length > 0) @@ -111,6 +116,12 @@ export const constructFilterParams = (filters: Filters) => { params.set(PARAMS.RETRY, "true"); } + if (filters.resolution) { + filters.resolution.forEach((resolution) => { + params.append(PARAMS.RESOLUTION, resolution); + }); + } + if (filters.transition) { filters.transition.forEach((transition) => { params.set(PARAMS.TRANSITION, transition); @@ -144,6 +155,10 @@ export const isFlakyFilter = (filter: AwesomeFilter): filter is AwesomeBooleanFi return filter.type === "field" && filter.value.type === "boolean" && filter.value.key === "flaky"; }; +export const isResolutionFilter = (filter: AwesomeFilter): filter is AwesomeFilterGroupSimple => { + return filter.type === "group" && filter.fieldKey === "resolution"; +}; + export const isTagFilter = (filter: AwesomeFilter): filter is AwesomeArrayFieldFilter => { return filter.type === "field" && filter.value.type === "array" && filter.value.key === "tags"; }; diff --git a/packages/web-awesome/src/utils/tree.ts b/packages/web-awesome/src/utils/tree.ts index f4dc8b59df0..99cdfeefe59 100644 --- a/packages/web-awesome/src/utils/tree.ts +++ b/packages/web-awesome/src/utils/tree.ts @@ -14,6 +14,7 @@ export const createLeafLocalizer = transition: t.tooltip(leaf.transition), flaky: leaf.flaky && t.tooltip("flaky"), retries: leaf.retriesCount && t.tooltip("retries", { count: leaf.retriesCount }), + resolution: leaf.resolution && t.tooltip(`resolution.${leaf.resolution}`), }; return { ...leaf, diff --git a/packages/web-awesome/test/components/ReportFilters.test.tsx b/packages/web-awesome/test/components/ReportFilters.test.tsx index 30415582c76..8fde8a98637 100644 --- a/packages/web-awesome/test/components/ReportFilters.test.tsx +++ b/packages/web-awesome/test/components/ReportFilters.test.tsx @@ -17,6 +17,7 @@ vi.mock("@/stores/treeFilters/store", () => ({ vi.mock("@/stores/treeFilters/utils", () => ({ isCategoryFilter: () => false, isFlakyFilter: () => false, + isResolutionFilter: () => false, isRetryFilter: () => false, isTagFilter: () => false, isTransitionFilter: () => false, @@ -36,6 +37,10 @@ vi.mock("@/components/ReportFilters/TransitionFilter", () => ({ TransitionFilter: () => null, })); +vi.mock("@/components/ReportFilters/ResolutionFilter", () => ({ + ResolutionFilter: () => null, +})); + vi.mock("@/components/ReportFilters/TagsFilter", () => ({ TagsFilter: () => null, })); diff --git a/packages/web-awesome/test/components/ResolutionCategories.test.tsx b/packages/web-awesome/test/components/ResolutionCategories.test.tsx new file mode 100644 index 00000000000..5acfacfa89e --- /dev/null +++ b/packages/web-awesome/test/components/ResolutionCategories.test.tsx @@ -0,0 +1,163 @@ +import { cleanup, fireEvent, render, screen } from "@testing-library/preact"; +import type { ComponentChildren } from "preact"; +import type { AwesomeResolutionCategories, AwesomeTestResult } from "types"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { ReportResolutionCategories } from "@/components/ReportResolutionCategories"; +import { TrResolutionCategoriesView } from "@/components/TestResult/TrResolutionCategories"; + +afterEach(() => { + cleanup(); +}); + +const navigateToTestResultMock = vi.hoisted(() => vi.fn()); +const treeItemMock = vi.hoisted(() => vi.fn()); +const resolutionCategoriesStoreMock = vi.hoisted(() => ({ + value: { + loading: false, + error: undefined, + data: { + groups: [], + }, + }, +})); + +vi.mock("@allurereport/web-components", () => ({ + ArrowButton: ({ isOpened, onClick }: { isOpened: boolean; onClick: () => void }) => ( + + ); + }, + allureIcons: { + lineDevBug2: "issue-icon", + lineGeneralCheckCircle: "accepted-icon", + lineGeneralEye: "muted-icon", + }, +})); + +vi.mock("@/stores", () => ({ + useI18n: () => ({ + t: (key: string) => key, + }), +})); + +vi.mock("@/stores/locale", () => ({ + useI18n: () => ({ + t: (key: string) => key, + }), +})); + +vi.mock("@/stores/resolutionCategories", () => ({ + resolutionCategoriesStore: resolutionCategoriesStoreMock, +})); + +vi.mock("@/stores/router", () => ({ + navigateToTestResult: navigateToTestResultMock, +})); + +beforeEach(() => { + navigateToTestResultMock.mockClear(); + treeItemMock.mockClear(); + resolutionCategoriesStoreMock.value = { + loading: false, + error: undefined, + data: { + groups: [], + }, + }; +}); + +describe("components > ResolutionCategories", () => { + it("should render report-level resolution categories and navigate to linked test result", () => { + const resolutionCategoriesData: AwesomeResolutionCategories = { + groups: [ + { + id: "issue:BUG-1", + resolution: "issue", + name: "BUG-1", + comment: "Checkout discount is not applied", + issue: { + id: "BUG-1", + type: "jira", + comment: "Checkout discount is not applied", + }, + testResults: [ + { + nodeId: "tr-1", + id: "history-1", + name: "checkout fails", + status: "failed", + duration: 123, + flaky: false, + retry: false, + resolution: "issue", + }, + ], + }, + ], + }; + + resolutionCategoriesStoreMock.value = { + loading: false, + error: undefined, + data: resolutionCategoriesData, + }; + + render(); + + expect(screen.getByText("BUG-1")).toBeInTheDocument(); + expect(screen.getByText("jira")).toBeInTheDocument(); + expect(screen.getByText("Checkout discount is not applied")).toBeInTheDocument(); + expect(screen.getByTestId("resolution-icon-issue-icon")).toBeInTheDocument(); + expect(screen.getByTestId("status-icon-failed")).toBeInTheDocument(); + expect(screen.getByTestId("resolution-marker-issue")).toBeInTheDocument(); + expect(screen.getByText("123")).toBeInTheDocument(); + expect(treeItemMock.mock.calls[0]?.[0]).not.toHaveProperty("nodeId"); + expect(treeItemMock.mock.calls[0]?.[0]).not.toHaveProperty("retry"); + expect(treeItemMock.mock.calls[0]?.[0]).not.toHaveProperty("fullName"); + + fireEvent.click(screen.getByRole("button", { name: "collapse" })); + + expect(screen.queryByRole("button", { name: /checkout fails/i })).not.toBeInTheDocument(); + + fireEvent.click(screen.getByRole("button", { name: "expand" })); + fireEvent.click(screen.getByRole("button", { name: /checkout fails/i })); + + expect(navigateToTestResultMock).toHaveBeenCalledWith({ testResultId: "tr-1" }); + }); + + it("should render resolution category tab content for a test result", () => { + const testResult = { + id: "tr-1", + name: "checkout fails", + status: "failed", + resolution: "muted", + resolutionComment: "Muted while infra is unstable", + } as AwesomeTestResult; + + render(); + + expect(screen.getByText("resolutions.muted")).toBeInTheDocument(); + expect(screen.getByText("Muted while infra is unstable")).toBeInTheDocument(); + expect(screen.getByTestId("resolution-icon-muted-icon")).toBeInTheDocument(); + }); +}); diff --git a/packages/web-awesome/test/components/TrNavigation.test.tsx b/packages/web-awesome/test/components/TrNavigation.test.tsx index d9efdaf375e..a321fa8a586 100644 --- a/packages/web-awesome/test/components/TrNavigation.test.tsx +++ b/packages/web-awesome/test/components/TrNavigation.test.tsx @@ -21,6 +21,40 @@ vi.hoisted(() => { import { TrNavigation } from "@/components/TestResult/TrNavigation"; import { waitForI18next } from "@/stores/locale"; +import { testResultNavStore, testResultStore } from "@/stores/testResults"; + +const setHash = (hash: string) => { + window.history.pushState(null, "", hash ? `#${hash}` : "/"); + window.dispatchEvent(new Event("pushState")); +}; + +const setTestResults = (results: Record>) => { + testResultStore.value = { + loading: false, + error: undefined, + data: Object.fromEntries( + Object.entries(results).map(([id, result]) => [ + id, + { + id, + nodeId: id, + name: `Test ${id}`, + status: "passed", + setup: [], + teardown: [], + steps: [], + labels: [], + groupedLabels: {}, + links: [], + parameters: [], + breadcrumbs: [], + history: [], + ...result, + } as AwesomeTestResult, + ]), + ), + }; +}; beforeEach(async () => { vi.stubGlobal( @@ -41,6 +75,9 @@ beforeEach(async () => { await story("copy-identifiers"); await label("coverage", "ui-components"); await waitForI18next; + setHash(""); + testResultNavStore.value = { loading: true, error: undefined, data: undefined }; + testResultStore.value = { loading: true, error: undefined, data: undefined }; }); afterEach(() => { @@ -99,4 +136,16 @@ describe("components > TestResult > TrNavigation", () => { await act(() => vi.advanceTimersByTimeAsync(300)); expect(screen.queryByTestId("test-result-copy-fullname")).not.toBeInTheDocument(); }); + + it("opens overview when navigating to a result without the current resolution categories tab", () => { + setHash("tr-1/resolutionCategories"); + testResultNavStore.value = { loading: false, error: undefined, data: ["tr-1", "tr-2"] }; + setTestResults({ "tr-1": { resolution: "issue" }, "tr-2": {} }); + + render(); + + fireEvent.click(screen.getByTestId("test-result-nav-next")); + + expect(window.location.hash).toBe("#tr-2"); + }); }); diff --git a/packages/web-awesome/test/index.test.tsx b/packages/web-awesome/test/index.test.tsx index b661b6de98e..1667c5930f1 100644 --- a/packages/web-awesome/test/index.test.tsx +++ b/packages/web-awesome/test/index.test.tsx @@ -21,6 +21,7 @@ const { fetchGlobalsMock, fetchMetricsDataMock, fetchQualityGateResultsMock, + fetchResolutionCategoriesDataMock, fetchEnvTreesDataMock, fetchTestResultMock, fetchTestResultNavMock, @@ -38,6 +39,7 @@ const { fetchGlobalsMock: vi.fn(), fetchMetricsDataMock: vi.fn(), fetchQualityGateResultsMock: vi.fn(), + fetchResolutionCategoriesDataMock: vi.fn(), fetchEnvTreesDataMock: vi.fn(), fetchTestResultMock: vi.fn(), fetchTestResultNavMock: vi.fn(), @@ -76,6 +78,7 @@ vi.mock("@/stores/envInfo", () => ({ fetchEnvInfo: fetchEnvInfoMock })); vi.mock("@/stores/globals", () => ({ fetchGlobals: fetchGlobalsMock })); vi.mock("@/stores/metrics", () => ({ fetchMetricsData: fetchMetricsDataMock })); vi.mock("@/stores/qualityGate", () => ({ fetchQualityGateResults: fetchQualityGateResultsMock })); +vi.mock("@/stores/resolutionCategories", () => ({ fetchResolutionCategoriesData: fetchResolutionCategoriesDataMock })); vi.mock("@/stores/tree", () => ({ fetchEnvTreesData: fetchEnvTreesDataMock })); vi.mock("@/stores/testResults", () => ({ fetchTestResult: fetchTestResultMock, @@ -153,6 +156,8 @@ describe("App", () => { expect(fetchPieChartDataMock).toHaveBeenCalledWith("env-1"); expect(fetchCategoriesDataMock).toHaveBeenCalledTimes(1); expect(fetchCategoriesDataMock).toHaveBeenCalledWith("env-1"); + expect(fetchResolutionCategoriesDataMock).toHaveBeenCalledTimes(1); + expect(fetchResolutionCategoriesDataMock).toHaveBeenCalledWith("env-1"); expect(fetchEnvTreesDataMock).toHaveBeenCalledTimes(1); expect(fetchEnvTreesDataMock).toHaveBeenCalledWith(["env-1"]); expect(fetchEnvStatsMock).toHaveBeenCalledTimes(1); @@ -169,6 +174,8 @@ describe("App", () => { expect(fetchPieChartDataMock).toHaveBeenCalledWith(""); expect(fetchCategoriesDataMock).toHaveBeenCalledTimes(1); expect(fetchCategoriesDataMock).toHaveBeenCalledWith(""); + expect(fetchResolutionCategoriesDataMock).toHaveBeenCalledTimes(1); + expect(fetchResolutionCategoriesDataMock).toHaveBeenCalledWith(""); expect(fetchEnvTreesDataMock).not.toHaveBeenCalled(); expect(fetchEnvStatsMock).not.toHaveBeenCalled(); }); diff --git a/packages/web-awesome/test/stores/keyboard/keyboardActions.test.ts b/packages/web-awesome/test/stores/keyboard/keyboardActions.test.ts index b76a5cfb4ec..96fbbd005a0 100644 --- a/packages/web-awesome/test/stores/keyboard/keyboardActions.test.ts +++ b/packages/web-awesome/test/stores/keyboard/keyboardActions.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it } from "vitest"; -import type { ReportTree, ReportTreeLeaf } from "../../../../types"; +import type { ReportTestResult, ReportTree, ReportTreeLeaf } from "../../../../types"; import { environmentsStore } from "../../../src/stores/env"; import { activePane, treeFocusId } from "../../../src/stores/keyboard"; import { @@ -9,13 +9,16 @@ import { getHotkeyScope, goToNextTestResult, goToPrevTestResult, + goToTestResultTab, navigateDownInTestResultPane, navigateUpInTestResultPane, + openTestResultFromTree, toggleMetadataSection, } from "../../../src/stores/keyboardActions"; import { layoutStore } from "../../../src/stores/layout"; import { testResultFocusId } from "../../../src/stores/testResultOverviewNav"; import { testResultNavStore, testResultStore } from "../../../src/stores/testResults"; +import { TEST_RESULT_TAB } from "../../../src/stores/testResultTabs"; import { collapsedTrees, treeStore } from "../../../src/stores/tree"; // --------------------------------------------------------------------------- @@ -31,6 +34,34 @@ const setNav = (ids: string[]) => { testResultNavStore.value = { loading: false, error: undefined, data: ids }; }; +const setTestResults = (results: Record>) => { + testResultStore.value = { + loading: false, + error: undefined, + data: Object.fromEntries( + Object.entries(results).map(([id, result]) => [ + id, + { + id, + nodeId: id, + name: `Test ${id}`, + status: "passed", + setup: [], + teardown: [], + steps: [], + labels: [], + groupedLabels: {}, + links: [], + parameters: [], + breadcrumbs: [], + history: [], + ...result, + } as ReportTestResult, + ]), + ), + }; +}; + const makeLeaf = (id: string, order = 0): ReportTreeLeaf => ({ nodeId: id, id, @@ -45,7 +76,7 @@ const makeLeaf = (id: string, order = 0): ReportTreeLeaf => ({ retriesCount: 0, }); -const setupTree = (leafIds: string[]) => { +const setupTree = (leafIds: string[], leafOverrides: Record> = {}) => { environmentsStore.value = { loading: false, error: undefined, @@ -57,7 +88,7 @@ const setupTree = (leafIds: string[]) => { data: { default: { root: { groups: [], leaves: leafIds }, - leavesById: Object.fromEntries(leafIds.map((id, i) => [id, makeLeaf(id, i)])), + leavesById: Object.fromEntries(leafIds.map((id, i) => [id, { ...makeLeaf(id, i), ...leafOverrides[id] }])), groupsById: {}, } as ReportTree, }, @@ -124,6 +155,26 @@ describe("goToNextTestResult", () => { expect(window.location.hash).toBe("#tr-2/history"); }); + it("[base] resets resolution categories tab when the next result has no resolution", () => { + setHash("tr-1/resolutionCategories"); + setNav(["tr-1", "tr-2"]); + setTestResults({ "tr-1": { resolution: "issue" }, "tr-2": {} }); + + goToNextTestResult(); + + expect(window.location.hash).toBe("#tr-2"); + }); + + it("[base] preserves resolution categories tab when the next result has resolution", () => { + setHash("tr-1/resolutionCategories"); + setNav(["tr-1", "tr-2"]); + setTestResults({ "tr-1": { resolution: "issue" }, "tr-2": { resolution: "accepted" } }); + + goToNextTestResult(); + + expect(window.location.hash).toBe("#tr-2/resolutionCategories"); + }); + it("[base] clears treeFocusId after navigating", () => { setHash("tr-1"); setNav(["tr-1", "tr-2"]); @@ -217,6 +268,16 @@ describe("goToPrevTestResult", () => { expect(window.location.hash).toBe("#tr-2/retries"); }); + it("[base] resets resolution categories tab when the previous result has no resolution", () => { + setHash("tr-2/resolutionCategories"); + setNav(["tr-1", "tr-2"]); + setTestResults({ "tr-1": {}, "tr-2": { resolution: "issue" } }); + + goToPrevTestResult(); + + expect(window.location.hash).toBe("#tr-1"); + }); + it("[base] clears treeFocusId after navigating", () => { setHash("tr-3"); setNav(["tr-1", "tr-2", "tr-3"]); @@ -324,6 +385,66 @@ describe("navigateUpInTestResultPane", () => { }); }); +// --------------------------------------------------------------------------- +// goToTestResultTab +// --------------------------------------------------------------------------- + +describe("goToTestResultTab", () => { + beforeEach(resetAll); + afterEach(resetAll); + + it("navigates to resolution categories tab for a resolved test result", () => { + setHash("tr-1"); + setTestResults({ "tr-1": { resolution: "issue" } }); + + goToTestResultTab(TEST_RESULT_TAB.ResolutionCategories); + + expect(window.location.hash).toBe("#tr-1/resolutionCategories"); + }); + + it("does not navigate to resolution categories tab for an unresolved test result", () => { + setHash("tr-1"); + setTestResults({ "tr-1": {} }); + + goToTestResultTab(TEST_RESULT_TAB.ResolutionCategories); + + expect(window.location.hash).toBe("#tr-1"); + }); +}); + +// --------------------------------------------------------------------------- +// openTestResultFromTree +// --------------------------------------------------------------------------- + +describe("openTestResultFromTree", () => { + beforeEach(resetAll); + afterEach(resetAll); + + it("[split] resets resolution categories tab when the focused tree result has no resolution", () => { + layoutStore.value = "split"; + activePane.value = "tree"; + setHash("tr-1/resolutionCategories"); + setupTree(["tr-2"]); + treeFocusId.value = "tr-2"; + + openTestResultFromTree(); + + expect(window.location.hash).toBe("#tr-2"); + }); + + it("[split] preserves resolution categories tab when the focused tree result has resolution", () => { + layoutStore.value = "split"; + activePane.value = "tree"; + setHash("tr-1/resolutionCategories"); + setupTree(["tr-2"], { "tr-2": { resolution: "issue" } }); + treeFocusId.value = "tr-2"; + + openTestResultFromTree(); + + expect(window.location.hash).toBe("#tr-2/resolutionCategories"); + }); +}); + // --------------------------------------------------------------------------- // switching base → split: focus current test in tree // --------------------------------------------------------------------------- diff --git a/packages/web-awesome/test/stores/treeFilters/actions.test.ts b/packages/web-awesome/test/stores/treeFilters/actions.test.ts index 23305263110..d9d38cec515 100644 --- a/packages/web-awesome/test/stores/treeFilters/actions.test.ts +++ b/packages/web-awesome/test/stores/treeFilters/actions.test.ts @@ -101,6 +101,7 @@ describe("stores > treeFilters > actions", () => { { key: "query", value: undefined }, { key: "retry", value: undefined }, { key: "flaky", value: undefined }, + { key: "resolution", value: [] }, { key: "transition", value: [] }, { key: "tags", value: [] }, { key: "categories", value: [] }, @@ -112,6 +113,6 @@ describe("stores > treeFilters > actions", () => { clearTreeFilterParams(); expect(setParamsMock).toHaveBeenCalledTimes(1); - expect(setParamsMock.mock.calls[0]).toHaveLength(7); + expect(setParamsMock.mock.calls[0]).toHaveLength(8); }); }); diff --git a/packages/web-awesome/test/stores/treeFilters/store.test.ts b/packages/web-awesome/test/stores/treeFilters/store.test.ts new file mode 100644 index 00000000000..2f0833923af --- /dev/null +++ b/packages/web-awesome/test/stores/treeFilters/store.test.ts @@ -0,0 +1,69 @@ +import { type ResolutionCategory, type TestStatus, type TestStatusTransition } from "@allurereport/core-api"; +import { buildFilterPredicate, setParams } from "@allurereport/web-commons"; +import { epic, feature, label, story } from "allure-js-commons"; +import { beforeEach, describe, expect, it } from "vitest"; + +import { hasActiveTreeFilters, treeNonQueryFilters } from "../../../src/stores/treeFilters/store.js"; + +beforeEach(async () => { + await epic("coverage"); + await feature("filters"); + await story("store"); + await label("coverage", "filters"); + + setParams( + { key: "query", value: undefined }, + { key: "status", value: undefined }, + { key: "retry", value: undefined }, + { key: "flaky", value: undefined }, + { key: "resolution", value: [] }, + { key: "transition", value: [] }, + { key: "tags", value: [] }, + { key: "categories", value: [] }, + ); +}); + +const leaf = (params: { + status?: TestStatus; + flaky?: boolean; + retry?: boolean; + resolution?: ResolutionCategory; + transition?: TestStatusTransition; +}) => ({ + nodeId: "node", + id: "node", + name: "test", + duration: 1, + groupOrder: 1, + ...params, +}); + +const matchesActiveFilters = (testLeaf: ReturnType) => + buildFilterPredicate(treeNonQueryFilters.value)(testLeaf); + +describe("stores > treeFilters > store", () => { + it("should activate resolution category filters from URL params", () => { + setParams({ key: "resolution", value: ["issue"] }); + + expect(hasActiveTreeFilters.value).toBe(true); + expect(matchesActiveFilters(leaf({ resolution: "issue" }))).toBe(true); + expect(matchesActiveFilters(leaf({ resolution: "muted" }))).toBe(false); + expect(matchesActiveFilters(leaf({}))).toBe(false); + }); + + it("should combine resolution category with status as AND", () => { + setParams({ key: "resolution", value: ["issue"] }, { key: "status", value: "failed" }); + + expect(matchesActiveFilters(leaf({ status: "failed", resolution: "issue" }))).toBe(true); + expect(matchesActiveFilters(leaf({ status: "passed", resolution: "issue" }))).toBe(false); + expect(matchesActiveFilters(leaf({ status: "failed" }))).toBe(false); + }); + + it("should combine resolution category with retry and flaky markers as OR", () => { + setParams({ key: "resolution", value: ["issue"] }, { key: "flaky", value: "true" }); + + expect(matchesActiveFilters(leaf({ resolution: "issue", flaky: false }))).toBe(true); + expect(matchesActiveFilters(leaf({ flaky: true }))).toBe(true); + expect(matchesActiveFilters(leaf({ flaky: false }))).toBe(false); + }); +}); diff --git a/packages/web-awesome/test/stores/treeFilters/utils.test.ts b/packages/web-awesome/test/stores/treeFilters/utils.test.ts index b67fd7ed381..3abcc658d2a 100644 --- a/packages/web-awesome/test/stores/treeFilters/utils.test.ts +++ b/packages/web-awesome/test/stores/treeFilters/utils.test.ts @@ -2,7 +2,7 @@ import { epic, feature, label, story } from "allure-js-commons"; import { beforeEach, describe, expect, it } from "vitest"; import type { Filters } from "../../../src/stores/treeFilters/model.js"; -import { hasActiveFilters } from "../../../src/stores/treeFilters/utils.js"; +import { constructFilterParams, hasActiveFilters } from "../../../src/stores/treeFilters/utils.js"; beforeEach(async () => { await epic("coverage"); @@ -24,6 +24,7 @@ describe("stores > treeFilters > utils", () => { [{ status: "failed" }, "status"], [{ flaky: true }, "flaky"], [{ retry: true }, "retry"], + [{ resolution: ["issue"] }, "resolution"], [{ transition: ["new"] }, "transition"], [{ tags: ["smoke"] }, "tags"], [{ categories: ["Product Bug"] }, "categories"], @@ -39,10 +40,19 @@ describe("stores > treeFilters > utils", () => { expect( hasActiveFilters({ transition: [], + resolution: [], tags: [], categories: [], }), ).toBe(false); }); }); + + describe("constructFilterParams", () => { + it("should write resolution category filter params", () => { + const params = constructFilterParams({ resolution: ["issue", "muted"] }); + + expect(params.getAll("resolution")).toEqual(["issue", "muted"]); + }); + }); }); diff --git a/packages/web-awesome/test/utils/tree.test.ts b/packages/web-awesome/test/utils/tree.test.ts new file mode 100644 index 00000000000..7ad58c06bce --- /dev/null +++ b/packages/web-awesome/test/utils/tree.test.ts @@ -0,0 +1,19 @@ +import { describe, expect, it, vi } from "vitest"; + +import { createLeafLocalizer } from "../../src/utils/tree"; + +describe("utils > tree", () => { + it("should localize resolution tooltip with the resolution description key", () => { + const tooltip = vi.fn((key: string) => `localized:${key}`); + const localizeLeaf = createLeafLocalizer({ tooltip }); + const leaf = localizeLeaf({ + id: "history-1", + nodeId: "tr-1", + name: "failed test", + resolution: "issue", + }); + + expect(tooltip).toHaveBeenCalledWith("resolution.issue"); + expect(leaf.tooltips?.resolution).toBe("localized:resolution.issue"); + }); +}); diff --git a/packages/web-awesome/types.d.ts b/packages/web-awesome/types.d.ts index 6b04553ab24..c293a205474 100644 --- a/packages/web-awesome/types.d.ts +++ b/packages/web-awesome/types.d.ts @@ -1,11 +1,15 @@ export type { + Layout, ReportCategory, ReportExecutorInfo, ReportFixtureResult, + ReportOptions, ReportQualityGateResults, ReportQualityGateValidationResult, ReportRecursiveTree, - ReportOptions, + ReportResolutionCategories, + ReportResolutionGroup, + ReportResolutionTestResult, ReportRunSummary, ReportSearchDocument, ReportStatus, @@ -15,6 +19,5 @@ export type { ReportTree, ReportTreeGroup, ReportTreeLeaf, - Layout, StepTreeExpansion, } from "@allurereport/plugin-api"; diff --git a/packages/web-components/global.d.ts b/packages/web-components/global.d.ts index 2bc77608c4d..bac035f8cb5 100644 --- a/packages/web-components/global.d.ts +++ b/packages/web-components/global.d.ts @@ -1,4 +1,4 @@ -import type { DefaultTreeGroup, TestStatus } from "@allurereport/core-api"; +import type { DefaultTreeGroup, ResolutionCategory, TestStatus, TestStatusTransition } from "@allurereport/core-api"; export type Status = TestStatus | "total"; @@ -11,6 +11,22 @@ export type RecursiveTree = DefaultTreeGroup & { trees: RecursiveTree[]; }; +export type TreeLeaf = { + id: string; + nodeId: string; + name: string; + status?: TestStatus; + duration?: number; + groupOrder?: number; + flaky?: boolean; + retry?: boolean; + retriesCount?: number; + resolution?: ResolutionCategory; + transition?: TestStatusTransition; + transitionTooltip?: string; + tooltips?: Record; +}; + export type TreeSortBy = "order" | "duration" | "status" | "alphabet"; export type TreeDirection = "asc" | "desc"; export type TreeFilters = "flaky" | "retry" | "new"; diff --git a/packages/web-components/src/assets/svg/line-general-check-circle.svg b/packages/web-components/src/assets/svg/line-general-check-circle.svg index 7245a0c7314..a2ff8a4cd2c 100644 --- a/packages/web-components/src/assets/svg/line-general-check-circle.svg +++ b/packages/web-components/src/assets/svg/line-general-check-circle.svg @@ -2,7 +2,7 @@ + stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> diff --git a/packages/web-components/src/assets/svg/line-general-eye.svg b/packages/web-components/src/assets/svg/line-general-eye.svg index 4f3aa413933..614f558fd4f 100644 --- a/packages/web-components/src/assets/svg/line-general-eye.svg +++ b/packages/web-components/src/assets/svg/line-general-eye.svg @@ -1,7 +1,7 @@ - - diff --git a/packages/web-components/src/components/SvgIcon/SvgIcon.test.tsx b/packages/web-components/src/components/SvgIcon/SvgIcon.test.tsx index 7fc2b6d6c12..4380b73e416 100644 --- a/packages/web-components/src/components/SvgIcon/SvgIcon.test.tsx +++ b/packages/web-components/src/components/SvgIcon/SvgIcon.test.tsx @@ -8,17 +8,19 @@ afterEach(() => { }); describe("SvgIcon", () => { - it.each([allureIcons.lineAlertsAlertCircle, allureIcons.lineGeneralEye, allureIcons.lineIconBomb2])( - "renders %s without the obsolete sprite reference", - (id) => { - const { container } = render(); + it.each([ + allureIcons.lineAlertsAlertCircle, + allureIcons.lineDevBug2, + allureIcons.lineGeneralEye, + allureIcons.lineIconBomb2, + ])("renders %s without the obsolete sprite reference", (id) => { + const { container } = render(); - const icon = screen.getByTestId("icon"); + const icon = screen.getByTestId("icon"); - expect(["IMG", "svg"]).toContain(icon.tagName); - expect(container.querySelector("use")).toBeNull(); - }, - ); + expect(["IMG", "svg"]).toContain(icon.tagName); + expect(container.querySelector("use")).toBeNull(); + }); it("does not render a broken sprite reference for unknown ids", () => { const { container } = render(); diff --git a/packages/web-components/src/components/Tree/Tree.tsx b/packages/web-components/src/components/Tree/Tree.tsx index 2301573b055..9f65cd2b433 100644 --- a/packages/web-components/src/components/Tree/Tree.tsx +++ b/packages/web-components/src/components/Tree/Tree.tsx @@ -176,6 +176,7 @@ export const Tree: FunctionalComponent = ({ groupOrder={leaf.groupOrder as number} duration={leaf.duration} retriesCount={leaf.retriesCount} + resolution={leaf.resolution} transition={leaf.transition} transitionTooltip={leaf.transitionTooltip} tooltips={leaf.tooltips} diff --git a/packages/web-components/src/components/Tree/TreeItem.test.tsx b/packages/web-components/src/components/Tree/TreeItem.test.tsx new file mode 100644 index 00000000000..a280057a410 --- /dev/null +++ b/packages/web-components/src/components/Tree/TreeItem.test.tsx @@ -0,0 +1,22 @@ +import { cleanup, fireEvent, render, screen } from "@testing-library/preact"; +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { TreeItem } from "./TreeItem"; + +afterEach(() => { + cleanup(); +}); + +describe("TreeItem", () => { + it("renders as a button and navigates on activation", () => { + const navigateTo = vi.fn(); + + render(); + + const item = screen.getByRole("button", { name: /failed test/i }); + + fireEvent.click(item); + + expect(navigateTo).toHaveBeenCalledWith("test-result-1"); + }); +}); diff --git a/packages/web-components/src/components/Tree/TreeItem.tsx b/packages/web-components/src/components/Tree/TreeItem.tsx index 7cc2d55f6f2..3b128f31892 100644 --- a/packages/web-components/src/components/Tree/TreeItem.tsx +++ b/packages/web-components/src/components/Tree/TreeItem.tsx @@ -1,4 +1,4 @@ -import type { TestStatus, TestStatusTransition } from "@allurereport/core-api"; +import type { ResolutionCategory, TestStatus, TestStatusTransition } from "@allurereport/core-api"; import clsx from "clsx"; import type { FunctionComponent } from "preact"; @@ -14,6 +14,7 @@ interface TreeItemProps { duration?: number; retriesCount?: number; flaky?: boolean; + resolution?: ResolutionCategory; transition?: TestStatusTransition; transitionTooltip?: string; id: string; @@ -33,6 +34,7 @@ export const TreeItem: FunctionComponent = ({ duration, retriesCount, flaky, + resolution, transition, transitionTooltip, id, @@ -44,16 +46,18 @@ export const TreeItem: FunctionComponent = ({ ...rest }) => { const treeNodeId = focusNodeId ?? id; + const handleClick = () => navigateTo(id); return ( -
    navigateTo(id)} + onClick={handleClick} id={id} data-tree-node-id={treeNodeId} aria-current={focused ? "true" : undefined} @@ -69,11 +73,12 @@ export const TreeItem: FunctionComponent = ({ data-testid="tree-leaf-info" duration={duration} flaky={flaky} + resolution={resolution} retriesCount={retriesCount} transition={transition} transitionTooltip={transitionTooltip} tooltips={tooltips} /> -
    + ); }; diff --git a/packages/web-components/src/components/Tree/TreeItemInfo/TreeItemInfo.test.tsx b/packages/web-components/src/components/Tree/TreeItemInfo/TreeItemInfo.test.tsx new file mode 100644 index 00000000000..fafae1e29b1 --- /dev/null +++ b/packages/web-components/src/components/Tree/TreeItemInfo/TreeItemInfo.test.tsx @@ -0,0 +1,16 @@ +import { cleanup, render, screen } from "@testing-library/preact"; +import { afterEach, describe, expect, it } from "vitest"; + +import { TreeItemInfo } from "./index"; + +afterEach(() => { + cleanup(); +}); + +describe("TreeItemInfo", () => { + it("renders the resolution category marker", () => { + render(); + + expect(screen.queryByTestId("tree-leaf-resolution-issue")).not.toBeNull(); + }); +}); diff --git a/packages/web-components/src/components/Tree/TreeItemInfo/index.tsx b/packages/web-components/src/components/Tree/TreeItemInfo/index.tsx index 287d2eb940b..d91d7e3bd12 100644 --- a/packages/web-components/src/components/Tree/TreeItemInfo/index.tsx +++ b/packages/web-components/src/components/Tree/TreeItemInfo/index.tsx @@ -1,4 +1,4 @@ -import { type TestStatusTransition, formatDuration } from "@allurereport/core-api"; +import { type ResolutionCategory, type TestStatusTransition, formatDuration } from "@allurereport/core-api"; import type { FunctionComponent } from "preact"; import { SvgIcon, allureIcons } from "@/components/SvgIcon"; @@ -14,15 +14,23 @@ export interface TreeItemInfoProps { duration?: number; retriesCount?: number; flaky?: boolean; + resolution?: ResolutionCategory; transition?: TestStatusTransition; transitionTooltip?: string; tooltips?: Record; } +const resolutionToIcon: Record = { + issue: allureIcons.lineDevBug2, + muted: allureIcons.lineGeneralEye, + accepted: allureIcons.lineGeneralCheckCircle, +}; + export const TreeItemInfo: FunctionComponent = ({ duration, retriesCount, flaky, + resolution, transition, tooltips, }) => { @@ -40,6 +48,11 @@ export const TreeItemInfo: FunctionComponent = ({ )} + {resolution && ( + + + + )} {transition && ( Date: Thu, 3 Sep 2026 11:47:41 +0400 Subject: [PATCH 2/8] add resolution rule copy menu and filter counters --- .../components/ReportFilters/BaseFilters.tsx | 7 +- .../ReportFilters/ResolutionFilter.tsx | 51 ++++++-- .../src/components/ReportFilters/styles.scss | 7 + .../TestResult/TrNavigation/index.tsx | 52 ++++++-- packages/web-awesome/src/locales/ar.json | 2 + packages/web-awesome/src/locales/az.json | 2 + packages/web-awesome/src/locales/de.json | 2 + packages/web-awesome/src/locales/en.json | 2 + packages/web-awesome/src/locales/es.json | 2 + packages/web-awesome/src/locales/fr.json | 2 + packages/web-awesome/src/locales/he.json | 2 + packages/web-awesome/src/locales/hy.json | 2 + packages/web-awesome/src/locales/it.json | 2 + packages/web-awesome/src/locales/ja.json | 2 + packages/web-awesome/src/locales/ka.json | 2 + packages/web-awesome/src/locales/kr.json | 2 + packages/web-awesome/src/locales/nl.json | 2 + packages/web-awesome/src/locales/pl.json | 2 + packages/web-awesome/src/locales/pt.json | 2 + packages/web-awesome/src/locales/ru.json | 2 + packages/web-awesome/src/locales/sv.json | 2 + packages/web-awesome/src/locales/tr.json | 2 + packages/web-awesome/src/locales/uk.json | 2 + packages/web-awesome/src/locales/zh-TW.json | 2 + packages/web-awesome/src/locales/zh.json | 2 + .../test/components/ResolutionFilter.test.tsx | 122 ++++++++++++++++++ .../test/components/TrNavigation.test.tsx | 47 +++++++ 27 files changed, 303 insertions(+), 25 deletions(-) create mode 100644 packages/web-awesome/test/components/ResolutionFilter.test.tsx diff --git a/packages/web-awesome/src/components/ReportFilters/BaseFilters.tsx b/packages/web-awesome/src/components/ReportFilters/BaseFilters.tsx index fadd0e336e4..f4bdf18165f 100644 --- a/packages/web-awesome/src/components/ReportFilters/BaseFilters.tsx +++ b/packages/web-awesome/src/components/ReportFilters/BaseFilters.tsx @@ -157,7 +157,7 @@ export const MultipleChoiceFieldFilter = (props: { counter?: boolean; onChange: (group: FieldFilterGroup) => void; onClear?: () => void; - options: { key: string; label?: string; description?: string; icon?: string }[]; + options: { key: string; label?: string; description?: string; icon?: string; count?: number }[]; fieldKey: string; logicalOperator?: LogicalOperator; strict?: boolean; @@ -258,7 +258,10 @@ export const MultipleChoiceFieldFilter = (props: { dataTestId={`${option.key}-filter`} >
    - {option.label ?? option.key} +
    + {option.label ?? option.key} + {option.count !== undefined && } +
    {option.description && ( {option.description} diff --git a/packages/web-awesome/src/components/ReportFilters/ResolutionFilter.tsx b/packages/web-awesome/src/components/ReportFilters/ResolutionFilter.tsx index 84f5cb4ff69..c6970fd5edf 100644 --- a/packages/web-awesome/src/components/ReportFilters/ResolutionFilter.tsx +++ b/packages/web-awesome/src/components/ReportFilters/ResolutionFilter.tsx @@ -1,7 +1,10 @@ import { allureIcons } from "@allurereport/web-components"; -import { useMemo } from "preact/hooks"; +import { useComputed } from "@preact/signals"; +import type { AwesomeTree } from "types"; import { useI18n } from "@/stores"; +import { currentEnvironment } from "@/stores/env"; +import { treeStore } from "@/stores/tree"; import { RESOLUTIONS } from "@/stores/treeFilters/constants"; import type { AwesomeFilterGroupSimple } from "@/stores/treeFilters/model"; @@ -13,23 +16,47 @@ const resolutionOptions = [ { key: "accepted", icon: allureIcons.lineGeneralCheckCircle }, ]; +const emptyResolutionCounts = Object.freeze({ issue: 0, muted: 0, accepted: 0 }); + +const getResolutionCounts = ( + trees: Record | undefined, + selectedEnvironment: string, +): Record<(typeof RESOLUTIONS)[number], number> => { + if (!trees) { + return emptyResolutionCounts; + } + + const envIds = selectedEnvironment ? [selectedEnvironment] : Object.keys(trees); + const counts = { issue: 0, muted: 0, accepted: 0 }; + + for (const envId of envIds) { + const leaves = Object.values(trees[envId]?.leavesById ?? {}); + + for (const leaf of leaves) { + if (leaf.resolution && leaf.resolution in counts) { + counts[leaf.resolution] += 1; + } + } + } + + return counts; +}; + export const ResolutionFilter = (props: { group: AwesomeFilterGroupSimple; onChange: (group: AwesomeFilterGroupSimple) => void; }) => { const { group, onChange } = props; const { t } = useI18n("filters"); - const options = useMemo( - () => - resolutionOptions - .filter(({ key }) => RESOLUTIONS.includes(key as (typeof RESOLUTIONS)[number])) - .map((option) => ({ - ...option, - label: t(`resolutions.${option.key}`), - description: t(`description.resolution.${option.key}`), - })), - [t], - ); + const resolutionCounts = useComputed(() => getResolutionCounts(treeStore.value.data, currentEnvironment.value)); + const options = resolutionOptions + .filter(({ key }) => RESOLUTIONS.includes(key as (typeof RESOLUTIONS)[number])) + .map((option) => ({ + ...option, + label: t(`resolutions.${option.key}`), + description: t(`description.resolution.${option.key}`), + count: resolutionCounts.value[option.key as (typeof RESOLUTIONS)[number]], + })); return ( const HOVER_CLOSE_DELAY = 300; -const FullName = (props: { fullName: string; testCaseId?: string; retryHash?: string }) => { +type CopyableResolutionRule = Extract; + +const resolutionRuleSnippet = (resolution: CopyableResolutionRule, testCaseId: string) => `{ + resolution: "${resolution}", + testCaseId: [${JSON.stringify(testCaseId)}], + comment: "" +}`; + +const TestResultCopyMenu = (props: { fullName?: string; testCaseId?: string; retryHash?: string }) => { const { fullName, testCaseId, retryHash } = props; const [copied, setCopied] = useState(false); const { t } = useI18n("ui"); @@ -91,7 +100,7 @@ const FullName = (props: { fullName: string; testCaseId?: string; retryHash?: st }, []); return ( -
    +
    scheduleMenuClose()} > - copyValue(fullName)}> - {t("fullname")} - + {fullName && ( + copyValue(fullName)}> + {t("fullname")} + + )} {testCaseId && ( copyValue(testCaseId)}> {t("test-case-id")} @@ -138,12 +149,30 @@ const FullName = (props: { fullName: string; testCaseId?: string; retryHash?: st {t("retry-hash")} )} + {testCaseId && ( + <> + copyValue(resolutionRuleSnippet("muted", testCaseId))} + > + {t("muted-resolution-rule")} + + copyValue(resolutionRuleSnippet("accepted", testCaseId))} + > + {t("accepted-resolution-rule")} + + + )}
    - - {fullName} - + {fullName && ( + + {fullName} + + )}
    ); }; @@ -190,16 +219,17 @@ export const TrNavigation = (props: Props) => { const isHidden = !!testResult?.isRetry; const hasFullName = !!testResult?.fullName; + const hasCopyMenu = hasFullName || !!testResult.testCase?.id || !!testResult.retryHash; // Nothing to show - if ((isHidden || !hasData.value) && !hasFullName) { + if ((isHidden || !hasData.value) && !hasCopyMenu) { return null; } return (
    - {hasFullName && ( - { + vi.stubGlobal( + "matchMedia", + vi.fn().mockImplementation(() => ({ + matches: false, + media: "", + onchange: null, + addListener: vi.fn(), + removeListener: vi.fn(), + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + ); +}); + +import { ResolutionFilter } from "@/components/ReportFilters/ResolutionFilter"; +import { currentEnvironment } from "@/stores/env"; +import { treeStore } from "@/stores/tree"; +import type { AwesomeFilterGroupSimple } from "@/stores/treeFilters/model"; + +import type { AwesomeTree, AwesomeTreeLeaf } from "../../types"; + +vi.mock("@/stores/locale", () => ({ + useI18n: () => ({ + t: (key: string) => key, + }), +})); + +const resolutionGroup = (resolutions: string[] = []): AwesomeFilterGroupSimple => ({ + type: "group", + logicalOperator: "AND", + fieldKey: "resolution", + value: resolutions.map((resolution) => ({ + type: "field", + logicalOperator: "OR", + value: { + key: "resolution", + value: resolution, + type: "string", + strict: true, + }, + })), +}); + +const leaf = (id: string, resolution?: AwesomeTreeLeaf["resolution"]): AwesomeTreeLeaf => ({ + id, + nodeId: id, + name: id, + status: "failed", + duration: 1, + groupOrder: 1, + resolution, +}); + +const tree = (leaves: AwesomeTreeLeaf[]): AwesomeTree => + ({ + root: { nodeId: "root", name: "root", children: [] }, + groupsById: {}, + leavesById: Object.fromEntries(leaves.map((item) => [item.nodeId, item])), + }) as AwesomeTree; + +const openResolutionFilter = () => { + render(); + fireEvent.click(screen.getByRole("button", { name: "resolution" })); +}; + +beforeEach(async () => { + await epic("coverage"); + await feature("filters"); + await story("resolution-filter"); + await label("coverage", "ui-components"); + + currentEnvironment.value = ""; + treeStore.value = { + loading: false, + error: undefined, + data: { + "env-a": tree([leaf("issue-1", "issue"), leaf("issue-2", "issue"), leaf("muted-1", "muted"), leaf("plain-1")]), + "env-b": tree([leaf("accepted-1", "accepted"), leaf("muted-2", "muted")]), + }, + }; +}); + +afterEach(() => { + cleanup(); + currentEnvironment.value = ""; + treeStore.value = { loading: true, error: undefined, data: undefined }; +}); + +describe("components > ReportFilters > ResolutionFilter", () => { + it("renders counters for each resolution category from loaded tree leaves", () => { + openResolutionFilter(); + + expect(within(screen.getByTestId("issue-filter")).getByText("2")).toBeInTheDocument(); + expect(within(screen.getByTestId("muted-filter")).getByText("2")).toBeInTheDocument(); + expect(within(screen.getByTestId("accepted-filter")).getByText("1")).toBeInTheDocument(); + }); + + it("limits counters to the selected environment", () => { + currentEnvironment.value = "env-b"; + + openResolutionFilter(); + + expect(within(screen.getByTestId("issue-filter")).getByText("0")).toBeInTheDocument(); + expect(within(screen.getByTestId("muted-filter")).getByText("1")).toBeInTheDocument(); + expect(within(screen.getByTestId("accepted-filter")).getByText("1")).toBeInTheDocument(); + }); + + it("keeps counters independent from active resolution filters", () => { + render(); + fireEvent.click(screen.getByRole("button", { name: /resolution 1/ })); + + expect(within(screen.getByTestId("issue-filter")).getByText("2")).toBeInTheDocument(); + expect(within(screen.getByTestId("muted-filter")).getByText("2")).toBeInTheDocument(); + expect(within(screen.getByTestId("accepted-filter")).getByText("1")).toBeInTheDocument(); + }); +}); diff --git a/packages/web-awesome/test/components/TrNavigation.test.tsx b/packages/web-awesome/test/components/TrNavigation.test.tsx index a321fa8a586..02249d01018 100644 --- a/packages/web-awesome/test/components/TrNavigation.test.tsx +++ b/packages/web-awesome/test/components/TrNavigation.test.tsx @@ -119,6 +119,53 @@ describe("components > TestResult > TrNavigation", () => { await waitFor(() => expect(writeText).toHaveBeenCalledWith("retry-hash")); }); + it("copies muted and accepted resolution rule snippets for current test case", async () => { + const writeText = vi.fn().mockResolvedValue(undefined); + vi.stubGlobal("navigator", { clipboard: { writeText } }); + + render(); + fireEvent.mouseEnter(screen.getByTestId("test-result-fullname-copy-trigger")); + + expect(screen.getByText("Muted rule")).toBeInTheDocument(); + expect(screen.getByText("Accepted rule")).toBeInTheDocument(); + + fireEvent.click(screen.getByTestId("test-result-copy-muted-resolution-rule")); + await waitFor(() => + expect(writeText).toHaveBeenCalledWith(`{ + resolution: "muted", + testCaseId: ["test-case-id"], + comment: "" +}`), + ); + + fireEvent.mouseEnter(screen.getByTestId("test-result-fullname-copy-trigger")); + fireEvent.click(screen.getByTestId("test-result-copy-accepted-resolution-rule")); + await waitFor(() => + expect(writeText).toHaveBeenCalledWith(`{ + resolution: "accepted", + testCaseId: ["test-case-id"], + comment: "" +}`), + ); + }); + + it("doesn't show resolution rule copy options without test case id", () => { + render(); + fireEvent.mouseEnter(screen.getByTestId("test-result-fullname-copy-trigger")); + + expect(screen.queryByTestId("test-result-copy-muted-resolution-rule")).not.toBeInTheDocument(); + expect(screen.queryByTestId("test-result-copy-accepted-resolution-rule")).not.toBeInTheDocument(); + }); + + it("shows resolution rule copy options when test case id exists without fullname", () => { + render(); + fireEvent.mouseEnter(screen.getByTestId("test-result-fullname-copy-trigger")); + + expect(screen.getByTestId("test-result-copy-muted-resolution-rule")).toBeInTheDocument(); + expect(screen.getByTestId("test-result-copy-accepted-resolution-rule")).toBeInTheDocument(); + expect(screen.queryByTestId("test-result-copy-fullname")).not.toBeInTheDocument(); + }); + it("keeps menu open while pointer moves from trigger to menu", async () => { vi.useFakeTimers(); render(); From 7fd155c32450357bd3457fc3b152ecdc83f5d708 Mon Sep 17 00:00:00 2001 From: Dmitrii Evreinov Date: Fri, 4 Sep 2026 20:42:05 +0400 Subject: [PATCH 3/8] ui fix --- history.jsonl | 2 + output/playwright/resolutions-copy-rule.png | Bin 0 -> 86075 bytes .../playwright/resolutions-current-stand.png | Bin 0 -> 88877 bytes .../playwright/resolutions-review-fixes.png | Bin 0 -> 88858 bytes output/resolution-ui-demo/allurerc.mjs | 32 ++++++ output/resolution-ui-demo/history.jsonl | 1 + output/resolution-ui-demo/known-issues.json | 1 + .../src/components/HotkeysProvider/index.tsx | 16 +-- .../KeyboardShortcuts/shortcutsConfig.ts | 8 +- .../src/components/MainReport/index.tsx | 28 ++--- .../ResolutionCategoriesList/index.tsx | 102 +++++++++++------- .../ResolutionCategoriesList/styles.scss | 40 ++++--- .../TestResult/TrNavigation/index.tsx | 25 ----- .../TrResolutionCategories/index.tsx | 6 +- packages/web-awesome/src/locales/ar.json | 10 +- packages/web-awesome/src/locales/az.json | 10 +- packages/web-awesome/src/locales/de.json | 10 +- packages/web-awesome/src/locales/en.json | 10 +- packages/web-awesome/src/locales/es.json | 10 +- packages/web-awesome/src/locales/fr.json | 10 +- packages/web-awesome/src/locales/he.json | 10 +- packages/web-awesome/src/locales/hy.json | 10 +- packages/web-awesome/src/locales/it.json | 10 +- packages/web-awesome/src/locales/ja.json | 10 +- packages/web-awesome/src/locales/ka.json | 10 +- packages/web-awesome/src/locales/kr.json | 10 +- packages/web-awesome/src/locales/nl.json | 10 +- packages/web-awesome/src/locales/pl.json | 10 +- packages/web-awesome/src/locales/pt.json | 10 +- packages/web-awesome/src/locales/ru.json | 10 +- packages/web-awesome/src/locales/sv.json | 10 +- packages/web-awesome/src/locales/tr.json | 10 +- packages/web-awesome/src/locales/uk.json | 10 +- packages/web-awesome/src/locales/zh-TW.json | 10 +- packages/web-awesome/src/locales/zh.json | 10 +- .../src/stores/resolutionCategories.ts | 8 +- packages/web-awesome/src/stores/router.ts | 2 +- .../components/ResolutionCategories.test.tsx | 72 ++++++------- .../test/components/TrNavigation.test.tsx | 47 +------- 39 files changed, 280 insertions(+), 320 deletions(-) create mode 100644 history.jsonl create mode 100644 output/playwright/resolutions-copy-rule.png create mode 100644 output/playwright/resolutions-current-stand.png create mode 100644 output/playwright/resolutions-review-fixes.png create mode 100644 output/resolution-ui-demo/allurerc.mjs create mode 100644 output/resolution-ui-demo/history.jsonl create mode 100644 output/resolution-ui-demo/known-issues.json diff --git a/history.jsonl b/history.jsonl new file mode 100644 index 00000000000..a6b79f59557 --- /dev/null +++ b/history.jsonl @@ -0,0 +1,2 @@ +{"uuid":"c9bad8ed-9d7e-45f0-a1db-b728d07c6afa","name":"Allure Report","timestamp":1788533054087,"knownTestCaseIds":["12f5412270a40ad98e6911f123e74719","ce6f3573b3f36d5079d6ef74c628ebd6","9bb3c6ff7fa971a47b1d32ec91117c04"],"testResults":{"12f5412270a40ad98e6911f123e74719.d41d8cd98f00b204e9800998ecf8427e":{"id":"96c8d95c0957e7af420980e4b0a03032","name":"sample issue resolution","fullName":"sandbox:test/resolutions.spec.ts#sample issue resolution","environment":"default","status":"broken","message":"test issue","trace":"Error: test issue\n at /Users/form/projects/allure3/packages/sandbox/test/resolutions.spec.ts:4:9\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64","start":1788356819120,"stop":1788356819124,"duration":4,"labels":[{"name":"framework","value":"vitest"},{"name":"language","value":"javascript"},{"name":"host","value":"MacBook-Pro-form.local"},{"name":"thread","value":"vitest-worker-1"},{"name":"_fallbackTestCaseId","value":"88f188012373096531c7824a94319abe"},{"name":"package","value":"sandbox.test.resolutions.spec.ts"}],"url":"","historyId":"12f5412270a40ad98e6911f123e74719.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"ce6f3573b3f36d5079d6ef74c628ebd6.d41d8cd98f00b204e9800998ecf8427e":{"id":"4a48271d625a253ead59fdfa73afff76","name":"sample muted resolution","fullName":"sandbox:test/resolutions.spec.ts#sample muted resolution","environment":"default","status":"broken","message":"test muted","trace":"Error: test muted\n at /Users/form/projects/allure3/packages/sandbox/test/resolutions.spec.ts:12:9\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64","start":1788356819126,"stop":1788356819127,"duration":1,"labels":[{"name":"framework","value":"vitest"},{"name":"language","value":"javascript"},{"name":"host","value":"MacBook-Pro-form.local"},{"name":"thread","value":"vitest-worker-1"},{"name":"_fallbackTestCaseId","value":"1bb10b68391cecb6d1f8a33115950053"},{"name":"package","value":"sandbox.test.resolutions.spec.ts"}],"url":"","historyId":"ce6f3573b3f36d5079d6ef74c628ebd6.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"9bb3c6ff7fa971a47b1d32ec91117c04.d41d8cd98f00b204e9800998ecf8427e":{"id":"78404e94dee13be87bc1a689ecf38050","name":"sample accepted resolution","fullName":"sandbox:test/resolutions.spec.ts#sample accepted resolution","environment":"default","status":"broken","message":"test accepted","trace":"Error: test accepted\n at /Users/form/projects/allure3/packages/sandbox/test/resolutions.spec.ts:8:9\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64","start":1788356819125,"stop":1788356819126,"duration":1,"labels":[{"name":"framework","value":"vitest"},{"name":"language","value":"javascript"},{"name":"host","value":"MacBook-Pro-form.local"},{"name":"thread","value":"vitest-worker-1"},{"name":"_fallbackTestCaseId","value":"921b2c9f2d2e6b8ce4b90c24f9018f3b"},{"name":"package","value":"sandbox.test.resolutions.spec.ts"}],"url":"","historyId":"9bb3c6ff7fa971a47b1d32ec91117c04.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]}},"metrics":{},"url":""} +{"uuid":"12ad259a-e82c-473d-b86d-47494b81948b","name":"Allure Report","timestamp":1788533162433,"knownTestCaseIds":["12f5412270a40ad98e6911f123e74719","9bb3c6ff7fa971a47b1d32ec91117c04","ce6f3573b3f36d5079d6ef74c628ebd6"],"testResults":{"12f5412270a40ad98e6911f123e74719.d41d8cd98f00b204e9800998ecf8427e":{"id":"96c8d95c0957e7af420980e4b0a03032","name":"sample issue resolution","fullName":"sandbox:test/resolutions.spec.ts#sample issue resolution","environment":"default","status":"broken","message":"test issue","trace":"Error: test issue\n at /Users/form/projects/allure3/packages/sandbox/test/resolutions.spec.ts:4:9\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64","start":1788356819120,"stop":1788356819124,"duration":4,"labels":[{"name":"framework","value":"vitest"},{"name":"language","value":"javascript"},{"name":"host","value":"MacBook-Pro-form.local"},{"name":"thread","value":"vitest-worker-1"},{"name":"_fallbackTestCaseId","value":"88f188012373096531c7824a94319abe"},{"name":"package","value":"sandbox.test.resolutions.spec.ts"}],"url":"","historyId":"12f5412270a40ad98e6911f123e74719.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"9bb3c6ff7fa971a47b1d32ec91117c04.d41d8cd98f00b204e9800998ecf8427e":{"id":"78404e94dee13be87bc1a689ecf38050","name":"sample accepted resolution","fullName":"sandbox:test/resolutions.spec.ts#sample accepted resolution","environment":"default","status":"broken","message":"test accepted","trace":"Error: test accepted\n at /Users/form/projects/allure3/packages/sandbox/test/resolutions.spec.ts:8:9\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64","start":1788356819125,"stop":1788356819126,"duration":1,"labels":[{"name":"framework","value":"vitest"},{"name":"language","value":"javascript"},{"name":"host","value":"MacBook-Pro-form.local"},{"name":"thread","value":"vitest-worker-1"},{"name":"_fallbackTestCaseId","value":"921b2c9f2d2e6b8ce4b90c24f9018f3b"},{"name":"package","value":"sandbox.test.resolutions.spec.ts"}],"url":"","historyId":"9bb3c6ff7fa971a47b1d32ec91117c04.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"ce6f3573b3f36d5079d6ef74c628ebd6.d41d8cd98f00b204e9800998ecf8427e":{"id":"4a48271d625a253ead59fdfa73afff76","name":"sample muted resolution","fullName":"sandbox:test/resolutions.spec.ts#sample muted resolution","environment":"default","status":"broken","message":"test muted","trace":"Error: test muted\n at /Users/form/projects/allure3/packages/sandbox/test/resolutions.spec.ts:12:9\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n at new Promise ()\n at runWithCancel (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n at new Promise ()\n at runWithTimeout (file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n at file:///Users/form/projects/allure3/.yarn/cache/@vitest-runner-npm-4.1.8-38f4df6de4-278d148212.zip/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64","start":1788356819126,"stop":1788356819127,"duration":1,"labels":[{"name":"framework","value":"vitest"},{"name":"language","value":"javascript"},{"name":"host","value":"MacBook-Pro-form.local"},{"name":"thread","value":"vitest-worker-1"},{"name":"_fallbackTestCaseId","value":"1bb10b68391cecb6d1f8a33115950053"},{"name":"package","value":"sandbox.test.resolutions.spec.ts"}],"url":"","historyId":"ce6f3573b3f36d5079d6ef74c628ebd6.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]}},"metrics":{},"url":""} diff --git a/output/playwright/resolutions-copy-rule.png b/output/playwright/resolutions-copy-rule.png new file mode 100644 index 0000000000000000000000000000000000000000..8b035aab59721dcaaa916a1f1bf0ebdb726e7aea GIT binary patch literal 86075 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 GkN*bv+HJl7 literal 0 HcmV?d00001 diff --git a/output/playwright/resolutions-current-stand.png b/output/playwright/resolutions-current-stand.png new file mode 100644 index 0000000000000000000000000000000000000000..913e07e920ea92d7f27172f14de08287669c3a57 GIT binary patch literal 88877 zcmd42RX`m*)GkbEf#RiDi@Uo^krpWK?(XjH1&VLn-QC^V;_faRcPS1V`-gtt`=6_G ze{untOm-%-CM!#xC!umOqR0q12vAT^$l_wc3Q$lmKoxr8Jv8u7kWk_c6x0VOapA8@ zZt2GvFoGD8czw6~3}_#ERD^p4YpSc;+S+)tR{s_4pZGr`iB>btd^wvlRq?3LpVs)& z(=t{wGBQ?|Z97xc8`l4dp#a1FD+33`cK_7{8K9s){qKcf<^S7tuCmLUC(-|2!+|Y@ z)N6(d6vXZDxU#WjNiEBJ15yW38G8s*7+YCOB+g;o(k$%XmkWO;(KBi9e|tQ_zoS3 z!oME6_O0yXi*A#D2#eoZNk7<{%GDUW%-w}q zZ0F;A!tg4MPxu@GlU#)V$V5gOT@;X0!znT zMm}$=s+N||w^jPc^h$5twvyC;E72=VQaM~4V?ve-MTAbXJ`$ka_uLm4DtjU$BcFoN z@IFGeii)(UaT&D5Cnx0z_`UCSYP>%G6EIPcVuMMZs4HU;o3xSA%nmJQkDsE+IcaG#wcy}j?JoBs`)&^nja1pp)`_>K_YNuN zWP@x2=Wo+6^NFXUo(tuxY9m1>{mj>C93mCTBX)kAo*7%Sw&WcjceI3Pz1$0ObI`hc zv-ZN1p=n_UG;7>yNHTcpbAI{x@GZNZdS62-BG7-S!*wp#-G!R6ByXCwYi5R>PEgkR z!J;4`t<{{V1vwP3e1igazK~IIk9!S)RQf79C$Yv7q_}Cn! z!WN2@y$EO-*$R3-j7fZ7huv2zo5(=GW3kNsce^b$g5t4{%qfi$Rja zp`oFU*mT!7H=~9IT6N#q!_Kd-^QMY7)DqtP9h}|+1k54|)#ZLx`s-O5d*GgQP-u*h zvCh26>r2ubqq|Ga60o$6ct>9o7Op6CGHsvzsEIdz%OqrYF^gf6W<2jgbwZ&X&0kQi zG=Fq-`F3-2Q%Onb=2XDz^fBRAwqDvt5m6LEBgNcL4d+e=%z6`kYyGn6_gD96&OXEP zq_C<~wxUNq56_09t@O5FpX~6WLc>|&z=y+wLw?_Li=9JhK%i?4d)bAB-)Cu1uo-j; zdIEzZ**S;X+`A=C34il;Ohrcu0h(qzvDo$ufM@coV=Gt@Ifq_@lAQaJ9D(bdLBhiFC>9S))u$WF=s5@$F%UkCdZf znIJgs{GN6|hm(VWfrNzR%a_Od@OjrWfm&Kc32Et*Upa=jO~;3m4MH&_K{A;<0uCd- zqA17NjUP~DtGF){Ic(>OHD-tUWivC_jOWg~+mw}+MWa%r(hjFuGMb{tQyi0u+09Om zspaJ-2?e~@>YY`GcOy@ZCCGay-8>((I_%rz13j>I-3uK5I8oaU)~@~itUp?(f(1jF zhQ*AWo{JDeg6#El6PV^o5F{$Rlt43?=ZHIH9-Z0A*u+leabp$ix z*BGAMNJ=^@#D|ku#Av%*r>>AGn<-Zj_rjiW zt8oO|t2Qx0JX$MKXRFj#{dIfh=;h1*c7%+%OG~%9T6phnvNy?s!!Q__>U}vSy7ZTU zy$XvyZ7#1zQpMW7n(<+JI^0FLsb%tI6qm2QDaXI_s;_FLS+u{PBuBnk&nI-N<6-?^ z8P!H#AMH$AfHCbQt4ephv%5&FLSvWpY_ULk@(&Ev^UQsj0AIUR7`6?#HMAf|T~BTx zGmw(1Q|=AzQm5f;*e0$NN64EuU;D?kG6f9rdhz(}Gm-T9__X_JZjjS0-7!vi<(AT zb)n$Jd0TLQR92()aB8=xY;aJpG@gLNdF`x`H=oxr9yYG4*-N7%HpAJPCl?J(sn6;X z{&Le;(s=quGYd1Gw)Xe%C?&d8H=wWHv$M0*3c9kn-&2V z_j4qH!1Z%C<#oEn)cg?2&5QIWkvHguc`%YHE$wb1`h>ayr54h-h;5m$FhN>f?xv8L zbE~ws57$7mxg6Ghh*mC_3wByfvOR@`c#y(g6KynkkE4C;-t=7TyrpXRD)m|5YB@Sf z)0L1~&suq6DVE;gD7G4pGZzdjxjhE;`39lzLgYiMHTS=Nb~H1V*z+hN-Wv)fa&eKd zvCx$2oLJ-+zl9FuZLl`6F=_QV;t!4N@9R6|b1GHO;|W64AmnrYx(Uk5H9Qq?FrRM! zy5};=&d#oCyQ17;u=v%RN4M?T@6Yg_EVtKYdO?so`1C{^Hcq3k<9NYyW?VpT;nyia z=31Hy9-T^l_8n~8C~>G4!t~Ve{F#ELP}b>5Ns3=sjFDXijCPCQwv|M@eb-Q#J_uanQi>8ROabl0$7 z*7b10q_-5=C`E-z_hx7|?TSp+A)cTwAW(>FviqfAn3F>KlloZY$irq9&I^XE^N z0&8h$=~zA^54#Tgqto((I5BO&BT|&nV6)5@mVf%pG8hs!W4p9Qk++b(<%0^AMw{9t zp;S<_A}G)AT2zJVhxr}@RcS<(cl6Caw~D`=KIh}%h&>9+e1*=$#>ihaSbC@Nje&A1YJT)aWkvhs>%ffd`HD zW-WZGHyKboLQX1f2WdH@A3qPl&5t9zV`_=YpJ32x+1Vpp=rEML(580K%NipatOR>} zK*xO;yGEB(UmI(zx3-6*^Sd@A8XAA}H*vqzYIW&fUQUV(B)?4{xl~V%NqV?$YYS43 zZOBYczI*Q8Qy>rL^MM3(PD!7198u~(v1+iDSf=*>7%>{xU6aO{DNIH%mTd8Sj7>4E zwI~@3yfCp;RNCz`+}cFCau)YenAQ{2`{4Memziav2o_ocaxi=gnqXRbFTVNX$2$iP z>bF4%+rD>KEvc=kLNILzI}+1Vu7vzC7)`XsLRrhVSrbzdxz9HjAI5Xs9+z)zTnem9 zRcnfv?gx!v;-Cuco_L~^s+}-Q8Q0vNP7ReqwlxueFaipymMGuH9S&G)->ETw(Wh}X z*4JkX){q3LBOPddthrj4s}~Q9D;kf);~&UT2trJ%gopXtkk--anz-;S@=zIv6XRx> zbjQlbXrW3L6%+Go(*z3O{zOJanZOU!6$pwvT-*}!Q@oMV@3&AktGimPu@q?O%-61< zyTt$E5HM49S%=NT!-J6>9Tjz>xQG21)zidk{z%2js<;FbsvkxsVEB8*dZmT7F8lx9q#i9eDzv0X6Ydf1^z zmRpzm_RFUD@1}%N$#6!RT#g3YB5PQWOtcltlp_T`$5O>W=rIOH6g-}_N^3+?A)!+7 zf{S>yItR2~N;0zGAHn-(mT?ptKc>baEA}DsR8tqp$z){jVg5d#5>}L7gnsnGknWU_B{kk8RePHj>FQw6oK;SG6{(-X4{23m8n3 zFs^p<-uOp48PK)1&-J$;|v!R<(a% z!0!*f1}C+`fCdR}7iaMxYW(cfR77}qo?mOLhm{pxctliG4F9`>$S(KWn7NNX$CxdJ z;{_!(U1pE9xvZX*F)sFp6dHHWJ zk|gfGHxu$5o*o~M<|@c*V6;2(pS!P|ib_j|GVc%ISxH!ESXd-T-YjP``3HL_lQVet2Hp9o%F*T&O3X zt@^5IN|tFYPUSNoU0oONglgz|Jw2YSc*}KY7*~K52SW`LRrh627dpCPz3*YKGm4GH zc#t#Td*l3y7-ufN&VKtsG0UzdemxwztCrPdB~-*A?dfXyFugS&5}hS26=ATosmXyh z)+$56RK&K&2)0Ett_c!r$7 z5i%$>XOFNoSnx2Yce?!E#ALTrQe@I<%v7vMDB~pH^GWs6hGr7_wQg>!6j8( z`b3(z*;?r^Fy`SrrpIuT4VaWSHU0%Kh+yBxd?8Q^8pY=+mUHFci`@=d&l=0N%0M!f z6mAE;ZWy~AFJr9>udwr|&}Zu8HV50RQo``ho*<~*Ttg+NgjL>_mq?sBK9^0aq9|+6 z>wUaWpX$wr87%y$b;|d*#q;RtM%3YgOO^4)(%ZIAwk(UQ1Pl+~p`#myX|ehC{UI;g zW6-KB%~fcSD4@>u@0n7f(rr`>nIo$k&+O8gFDVQQV`*A^-zN>MgmkCWtSLO!lL!%K4&+SW&v z-P`5M3AN_nR(QDAodcBT?sQwrVhd|BqFx<=Y71`HFv0QAuv{r#+sG^Giy{~r3_+?3 z-4Z3>wKwTKj0{3h8_zr^OrjBEM>+&sLds!kYU~>u$qS_udHEZi!zpAlzZ~)E^#K0P zh2}1=GvwRsPyz=us>r2;~QFt8LmU}l}fBz1Kh5bm+Y-D9&VPVvRYc`E- ztV5PDl_Z@dWwS|}A}svGCV2-WY!jR=jzv^jMp+>PG_0p=k_!?D(9=iRG> z#i%zml2BaPZD~7 z-^Tiuy})kq&CODo5xAijGD<6cxb{R_=@U9L$l7Z;cpP3yHfSMv5IKzZM2iZ4P3stl zgJ7#K0c_wi*06`zuXAmAHwTmYB;DISVNQ8+n1mjN_BCvVkusGcc-RKCPgFAmp`jH^ z%)Nz*8? z3&}<3rDT8U&4lyobD&yM*g9e19~~F!g%P&laVLfg^y^BNzm*OW|NnVTD7grPe@pbW z|28y{-#-`WwT|%rLVcz=J}x!$_Vlzb1+EF?zcySmafpwn9Dwmtu&I zj3swf>^?d`Pd_EnXV%jEPck}Cv@gpMg!VuOznpbdwLwCa$I{n?GLmsU{e!!-3Tzp9 z8~o1J>*&8g&n4TwvBn&#TTPh2H7KN=P~5yFtsF@ut}D7{+py>PRZM;uzCHnq<5W+W zFUm4vVxYSinI2SH;06)4|9%&l5enmGzK?Zp480$DedV3%pos4i>DFsr2sHfR?+b#_ zV#i|@OPAEQD+%AXK&u07Kv!UBKu?zsPOq;5xyd4^#NYV6UWx;!{K`qf+^@R~SfE!A z@%6(zBij=KB?TE-t*+^L)_jj}4m_Ri+pQ2_u7Wlc@>*{Z$$YRyx=O@}{qvC$OZ>@U zs_P*;n2egbB6nR9G`nf9139p=_~@gfC*8dC{F7+VK2Gt@Xq9|+zDsCWYv1mn_%}5& z#a`#CdRVM?A)*($M$a6MQZEQxm^l~98^8ciAcr0;us~O}B;+g9>kF9YDk(o%&__s* zuqV$LhpB4aK4b2}RC`_1VvGW*VGI>TW%)c%*Z^EGJQC17KRvtpXFeF1KKfg}e-@OQ zl7?jM!E`3A|Lg4-WODv{$H>s!47O?)3wt%v8@e1HWnr`85{u%p62Yt2PiHPf<%b^U zV?zA8Q2pvJpVj|n_JS=MMimQ6Vx*8q;9^_Zh84TwWu&E*RV9Tah4BCBoEUExuNL{{ zY8NnsV5^?yq}`^+@@;gt&MI;OsGjZ(q1*=7qAiC(49?+UYbs9ZC&=qZ%g6rE`T7G7 z!*o@{>zc)(i7=ZrwfJkkfgnCWl_dZMGV&&>V{s*OJV^?j8?M7Es0x6GIz=^*nj zFPepaZ}}Z`_wf1*zX(A^Uhxr%A>6l*lnP`42YI;xlmF8L8twI?7(pE#(n!rdr)(YG z+A^F$g}=Pd)5igB3@|;b{km&-MPgWf3RB0>zGJ+5y?8AkT0f}&<_My_BlR<0=zeV< zp!#e0Dhnfwi|vXqHz$&=PXa@)H(pCEwZnGBkgj;P*X#0oE!*!ul0PTly+yiz{n2Y7 z>i^p`pd3^4Nrvfv8i34!RPM<9g8`P=|29CiK)=`fKlK#oPfuC@4QOO(^j?$e*MD~% zU_Sg`>K0lQv7qEn=(yO}S%PmEw&c;?&nPLg&CF8$0>&DE2!BC;j`T{zSU2pMEVtpw@+r{rBM3i8E)-&8DU^C*b{jE0k((y-%l&!n1`;uOzwTS+^SQ?U zoCf-hmmU<<-7RQSnsJrZaqEhh97*;cJf&b13$P?ow>CqKA?yQjskwP?Z|^+>GTFb=dn78Wy*rlNW6Tqs`6Z3XI7&J+cbTJn9njcx zUk2~bBOm4}?@S^4>AeYQsA5k;7_DRxj9@ROdOJ##{Pd0x*|O5otE08d;U%qBpZP+y zjXyA#j!;ILJ{}%jZcm-=c|3RnOGZh!d0$u_`F^Eb_K}i{o116}_yDfH=yfTIyYwZf z5eW%tv-V@2C{nxk&h`_oX_YP)hn1af7`OB8W|}KuvlJx<2L}}u7aLmyppEuokXBU4 z?P1ae67Q-IN^e(;1LhFJ+t#5RCYqNd-R|L1mi&K6x=%hD2Jv~6yCg|CrWM?|* zj2AT>)I!CZuAK2wu(m2#CM&67eS7pW9&jI6BF{@!h8e0FSPWHTqz zNh}2tGz%DmGtWZ(bB?9zHC~GiX)a!N&cmkqYdO~8l^IJHxMY|eHq%i6AW~XVnpjWG zZ_@K?vp1|-Wa~LiM1XbcJ90{w+YXSr)ZnlbwtnZNRlg5hWO%&y{B*ipqoa-QX!91- zCN8?Ax>6_o0Q)4|QoA;?gHt>5X&vcv4tf^o?{P0KWVis!qRV>^qQ0A3#87ql2^W(( zUVan~fJLHDHKhIZ(RZm@5R7NX8h;3rsWX>hOYb<~0Z2i-)WPXS0(d9@TDQv+g9aqe z;YKs2iX-lMJ%;xk<@oDsT5GNIML6Z^BC5>i#Nuk>S689oa}aRh^)*$+v;qgrlAIcqTnlUhjMv2 z5Qm-;U;;(oKknd)_xydok$t4A!(U&o`hupj#(yYIvg|gN6A}fo;3tLC{i)W<1c%3MHB}q_J2Fc#rk3Af zwf|F=YMzsRRSn@yrL>nZ_2z*G&r1!^+aRr?a!BQ@g056`vxYmzh)dFXW&s^ zj0F}|fm>p5|3WG(XC-z#T+Ay5A{L5&qM?Cyz?4aE(`Xm_otdE# zlbAiQ4w|@LM)i8Unw|R7?i+n`9BMIJ$ajC4(qKEA?DKPvPF*)oqt~M$HZyck=kD~h z#^Korz||l;78d~n162C!UH4a>MvCPV3;Nz%G12wjV0&A_u2}Lgq%-iUpswn!eT*x! z?|otN!ots=178hI6jHGwkJxOtd-m?M_C!g*-8C^gYrb0UgD<*~Xgs!JzjbQZG_DJGjrB|wcl%8?(Yv*g-0*S- zcRqXl0}V5>JniLfLY;aF@K%w~Cz|ZJirtMwj=C3P^PQxorviXW7*(QHIg`DXfx)If z{H3zOGYSXyFz)4Xb+yj^DK%q>%{UZ*%zPo6&JLHQswIN=rlJy2rzMy3xp{_Vs+AK3 z+N{#j$SJ(7E=RwC2)dh;g!*xP5D~&_o;w zHWLmu=vctzW)@fVvfZ5~zG2if6A%!e?^EVj_QSX?=1^iT(l$GLPP!tor<=!e0t4E| zk2llPo`=o9`@X}nL`$wo(Xybb;J805)n9_7YyQZv2PNXPlqgjz@n4iSjd*hl_&V8esF(W)A&SX2kKsHYh3AKp0c`J*fCSzCvp9L*;j zs!g3s;MZUD??4WY!mit>0LaUGG}rtQEB{s`2Hk|ALVI=NBGQwGM0-< z%l%1`0%A`trxPA8m62)l^yHe(i>1h9>b$O2j!&C4hH#C`s#LhI37usE_p-J&Ptd3& zKWj^aA;nnsCu{2pAfZoNM;+UMwQJ&NBBfPl;B%nBfl+5T?+=(>$e>oc7k-Ium{x<+ z>EmJ?BE|qAI(nPa4y@1W!U9*=XXbkFL0(%3$}ykqu5TdZI@|4H&>Ry2__GdBep-k} zH|Zo|`?2K1z6)($n5c8cj1L9Tk#&ECEI0}RJ;k~AR!%4KeHg)RM2={^!)dhP_WO74 z54DXC9P|fMmG=dfuIM6>si>LFKY~Q*vUtty&SX4MGEm@=_kNsYGLMbx#(mP^GCV%I zCDhhwFA%fUeK9Ozl*M7sR!!ot1^aGtO7gJs^XnfRhc0Pom@^)K|3i}eOpl147C&o7%oWOe06f{j_J(-;`R_SEILWD?ps9k>%^ zTiZ2(GMQ~RB5bJKPke5hkNNUX*yA{|OTjYal!x>!&bO1Dt4pI9JcmcoSxwt*L1ZKQ z*`-Q!l7ueRFqfJRB>L$e2)o>S(--4JK|%XR*n%-wCWT~sLy3*l^7$WT6*N>uH6?fL zC+~T@HoqMeUe7b6$P~p&grYn5lk>G3jlEOw%Rek3E6EXEvmX@R{XHbS*7@yQcW!Q; zI?l&F`CR^AEM-mY-qy>W_2%76ihW3s-P7OHKaLR;hMg^y)tLl{_Rf#QW5m1k3nTeQ^b+y+zp`il-uWdAoqqS8iXcbP@p#@jx z=_5vVl@?Ep*At3`3<7HOhv@ibW|qb?zVGwdf+8SL@ESrQiM`~vr0q(#FN$4St4Vd8GF{?oOS z^JVJp0l4jGVz26S#hb}_lPaYQ@K_@FA5|5)B(X=76crU66zhs)i?vFiDZMh8PF5U0 zD4S`>D=J|DajI4!HSu05?LrAzqX&S=&ktbt0D-??WdExpLZ+u6wExn zQ%;IR=NL;SQK|L?i%f0FM3!QDKfN9FA2f}*z2;Tzr}?8wpr)RhR7)-4PlGw!;dP`@ z;SdC1HVHNKW9=(bzm1MaC`{`VIik%WFZW!l1C@iS2iyWmw}z?eYxN3xy!xn+bQGZ)}Id_ zKV}#En#()W>xB7>4FCQws(g5c-xdT3Zxk?!E+x0b0*OWySBHmAaLS5#Y0&JD*mv4o zrWPluv$3lfT^=Q|;(}-nd z6BZx%OxP=Qj}{IjuOc$T&YOT#_HW`Gp?<_RIK@l4BUb9OW(>h+qc$w$UPHE-Ac1xa zDnrc(Cr^o6kz7e#r|NXM^@ATFq7I*f+r7oJ7?(ea3>uR^@Nsd~d#Nvf?cmvAXODT^ zvj&E3r&!74xF=Hzc)F927VFZBZT1hyjr|T4!mb4J{NqU7rQ=NKi}pTSMC{LZ;41^P z5(4k1=Qs@=F_p=!iPey??d{<&4EoWH4a?#xlha;q!bY`*mIcw06fCG5fuNSEfdR82 z;-ip}ECZOo{UQub0sF|*ES$7;NF`%O2NreS^7w|N4=nFt9t=VRM`fLkeuhVGIgn5B zWl@8oaFR>kc(=EEpM7z%0oS61$9FP+bjmA44gINkOHiZ%<*0y@jQ;tLmPeT`3bY!5 zY=-XLJ>tVG9?ym9cv#b!mbea9b>rsLTL|$^H=x`_{>{y90M&+nN|+78$ws%LrZPPD zqo%vn=|iKIOft*ER6-gMkQu<1Z%UstLnq|d;LNmsXJCe3-!I-*Q{IsNam57w9pN)} zKq)}O&qG5aVKVjxO7Q1JDl0lHxKIpskBHE%JF0sSK_0xLm-ODh_We~V;Tn)?a=&J0`g`w5$0Q}^zOVgR1jeQ}aDqmAf z&&-T0@;#sPv&K0I%qqVxDPx)2WPp}Lwy6P&IC;EHp9h#${U|F}F}+jy*NRXWZC_ePVt~SW&;GYNr1Cb7=sdhB|`h-6xzwaJ$pvO+wrz z;np_9`RbG*opS4{Wf%x56TtDqm#TDvT}D<`bwMpD%KRI$F-1k#%NXaU-ThSZvY51G zUSW0qEmcqh9aPlpi)vu0xKyhj)g>R>hM%|m)kF52+*c>BV9E{-L}xfGa=)L3?Yl-k zCjJ!53Ew{-ewc0|L{I@}B9}KExQmuCG4fSl@9nKYGY6mZ;GV&_y()msC>^g*F6R%V zXyTZBwjWuDiDM$)Jlu3|tt4m$KDZn#b>6pHKN$8x7_>XC_0D2gH{0?=Exf%uvIulS zNvI058wz{{Kcp?(|Bl-emDN?S(@HP4wAa&PGUk#$Ha(u}pq!;u6}yRqrCw64A%USn zZi!#(e70TlrBi8!>cXFL&g%5qL(MU0nX1g{guuL0s4Sl7DbgEF>j#pJw*2Ij7Q7$4 z#kae|ZpnXlQ;sKC=xmz;?o(q&f94m@0zKVaMZ=5X<)qB=yTDb) z{h1opBx+E9kC>2927%r_UJPs@rE_hb_!Gbtjo}LiHlotL87iSuX6wsmLu>}_{AkJD z`&jpC>Oa5NPD_Sqmy(K-#$8><5sc$ZoMS83SZ+nGndI4YG4QMEhAkO(23E>PSn|Dt zf`jA0GR9&idXpr+%7#3;`Wt9oHVFciJzzV7S+(DtzmA$J)63PXl3{nJzDrq+jJ>7Y zS5nw1I;xlGb)eIM^c5EswHe>aL$tGx!V+JxS4mc>w{>>kPkcQW|H}mw>oSD%{uh)YPcjzSqQ0WJspAxgij6_L*xhz-H7XoT&k6$8^^`*Ud^|IqCq*cG@#lV1-AMScK_%%+Ce5j^v!q7b8IkJID16 z4L5jPI9OOR!FIm`=4M(8OA5r*`P{a*|Neg3k8(WT=9aLsvNE!vXnH>Q8TAzMAj@b= zs4xjQfT}t9kSEnThPn)jwC>}xw{fjhsRYmqB_^{wN3I~H?7h{-QQYdvV0;aBie87u z5zMJi2s0Rz9wr5**~D8WDSM+rED_jB+o!Se)y}tQhNOW20kCcW_(QMRwzaa8=F!?} z7;-~lEF!yn)Ocz;pG#a}qtdpN5i%w!qjNl$10(5s>wk%gIzDEdc0s^W@r}oQaLJm? z;K1B-s`$;79fyTnw6SGVoUh1eXE(%E(N0S^2U;bc2`)0_YxF@!Tch<_G0M};s`vgE zdnI26ZiV_P73sr@yGF}j#RoJr0dvwvn3%MEGS+D}EA}Aiy*lGrEfxi{ii1nlIJq*V z&Is)ifiu3`NUKFhBk;yF56_Y(2f|ZUl=pYm2D_IS#Dnfb<>L}E%wx#_AYZ7}?$UJj zlRBUBU^@zLAy9Yw^x*nnIC>oSQ>jRd3hopZ3)zS zg32qF8b8R)TPc<^VV*6RhZnC%U@>ZSMdbx}qp_DMJGtLCO1{{WIVFu|2zwHHw^^-5 zNzR`lyi2c;u5mE_5&fKBju4hP*9lLqLJiX|(vo|OjK>;Br|1#27b^s5Hp*m7flDKy zNnn%~1)?aeCFogG{FD5EgjfCPjiuLa)7I3ivnaUG8j5+%Mu_d%T!D0sn(%-A46ChW zG7SEb7cX4{B#}_?_%bv;AI?^CKph}K&WHmbA7;hupRO}&TH>JXGx z+R9_DcdgUWqNJalmtd8;>`I72$l3xNUN~ND|MKRIzcWr#!6vtlooDE#$O972&f_t8 zFQ>(Nz17ADvZjmmN^Lm0GY3W0Z1<&VxC&cEjd=72M<;skUu|cmkh^?=c!?v$>i6E zL_SBK$|a5A4Oym&{w{(hBh2Y< zTnbVY`(Z|H{ngYs=ZaXGf5WTWdrfww6o;;D?qs#xu5k zk$1`j-Rv}Fy<0riX4ic<+|D9Et|*&diy%0ix5# zLAqG}t&775wv7$6)YR0Wc871f_VWBCYCV*yaiIbK>skzDF{V6xbpD1x=BY)!THfB8 z^JrZ5Xg~P&DeDFPPiO{=uSNVOZr;Vbt;r_tC%O;0B#>eF1p)O&#QJ&&`H(M?qP$|B z?8+M7`NOUK=f0rfKhNXWM{}`1DUCJ1UNLCRA*Md+O9;hS+0iZj;cIQA>`#ttt*ISp zvKvzp5_;Pz{cv~BUaZ=tdu9Y1g7kU8^Xjkv48rr@8rGC17h{RhWEK^Tr=k2p!-QNB z1o@rimRnG4TIv^lvM2KEvfR?Ce0l8~<>pgAoqC1?wF{8=Q*1f~IJrdET`m&bZlgX+ zgIV%5Rb>!jYXt|Dk2_QhmXc2xH0|!=zPAF2MY;9uXkm0gg@zEI0aUnrLbU{?uJnD^ zulH^{gw}&x3JOmSxuM}?2Cv`6h(9iLsNmhst;oHq0=!&peK8p0BwWV-irB7pENNuR z0IR-U0^lwstU+f8rUy?iOmVTSM(qnY2 zyEqKKNUFH#Cr2#?`vz2}h?Re*?qoLkdR^vMz7Hi?43_Zt##poWS+*_jR_Q>gxU6ox z%7wM!A>S>N*%)u#=|?JeN4wX6L_wj%&iuvsHR(xdUf!|e_b`rL-d~Ja?~U67j$=3q zFHGu8-$3~x#U_MHJ(&RMzj9Xo@sxF_xCvv5YPJiV=y!sL@82WL$*ImyOZ!}G9E-^C zF+e$>Uf`{lQ~A-h-%U$eSBr#y#qw?MUs!D$cra#hOLz#2TCTWM6-&t;HF}c{gNFU< zQE41NI1OTzV_z&LY-`ENmRY&>Qi%MxV_=^jrKis5HK@G%;9n7Ibv$=yu3_l_ksC(B zM7gdX9#v~&XrrsQ{MSm<1tz(t_x!|wM!Z6yVzy#}6i0a`i|_>l>&oT+2NU(Q&kr`s z=A<3FJ+E{DhmY!GP=F7x)BW)lQLJnv62tT29cG6u@YS;>2C{Z5t;dGU8@Z$!4p&n^v`oi*~PJa-)HUHkZwmV%1 zXoZpsC^su;ESD?OD*3})Q*%Xps1CNaXw@O#E|J(*bk=5f)^^53eg*dbGRjT7aPuy8 zefe+Z0d%Eg_(Pag3co3$zN{}alLQOgyZMI+3dw4NiV)zY(f|Y|(Z`tx;UYLRNp2 zm1SHitnwB7_RU~5RoT#`iRNTB*afYxH)|6A2on;P(a{{Hk|MZUW3Q3W{H zXDhZyyi)A!vtGOI%N(|H6%H_v)|Z7v0GgB`;4KEC883)s6QRwLylc>&58L<4`!L9WptmtlsITLA0Ezjf_X4 zu_~6D`%6p`Opq-@eguzeH5bZ#E#rwwpl-KXMNx>T=VkFvvRx4WQ{@|tqOZSU;(lqR z#t|pUt+-qM>LvY{`QrSHLwyOH4;gwaCEBUC_oab#pCP3frPZki_0Z(#Z{&{`gzpSc z>v#Vib4C=$samYHJ=9CI}42CuLF-_tu<2+;MWTjUaNZq6#xr~L~g<(2* zx(Yg~kAF*Knk@)rYWa|qldx0{JElVeJKj=xCqs*9R{> z8cGK>Z+nk!jeKGu1$H`$ajgxd3P?c!bpIFiy_G^2MG*3pa~fN*^U)eQLYw!!iHXIx z!=yi{sW=sBbH3-0x0JE*z$rN`NKRQ&lr8G1JR$*bHu?)zl z(eY#Sy}%jKeDC4!Mo#GXn(Un~JwZc>ae<*R`rWNj9KDFV0>0e_c*iH-{`^_M(qs{Q(3Pu;OWng(i8e>>3;; z!;Gy?Pp7?QuD~#~35?TCp1judqX5;n?d9=$c=>F08I>MqzCx{&jl0H?BHHL+T&Gps zA>4Z7umWxy{kw=rQX~CbZVb93%Pk?FWLOlIyPHSk=Oxd}O47O)TpJ^^Un;saKBjLe zMcWj}7v>#|B^*eoX*2c!_Jm{-osEGN)mb)AqYcU0Ef+t(KMVjG#FPy((#Y3O)J*@e znKG7Kj<2PrNaW9qe20P@P9%PCa`duugo=(%D#2LM2e7MakJjM{319vMl^@NP9;)?b z-mthH1Xut4X+Mp10GyjZ9ig<5D{8%K{iqvieyOsU#3-%PbVZU$%X!9W_mKe^0VRXU z@O+=RqnORiwbY^%*zC4_EX~Z~>Ex4-wGt_4c!I++Dl7qLS6X>ifas@}whTW^1-^><+x6g0&G0IA=@u3EHp9bhu;AlT5+#R8lQJzW#kGVqdY`qX0V%c z^~Q-U*Sy>%6L$cD{w`4)FCAmqL{Jal<5)3d59>G1GwV7-c)dHgw*Zb+K;)m8NI`gW zans?jMUXOxf$|=SgKc6DTb_%G>qmWMYicUw%)iqq0vOzUDVrlm=vy~H_NO$KfsS2z zPxUloA2{0^{BF86&4u7_sk22Wh(!szg&Q1xHPTFEk3{TLArP_ ztcR9Fv0`1Afnx%T)alhae+G4VRnas+B=;i8<7Hz@AM)AFZRkb7{(Fu1cWp<&`_BZh z&jIJ^kX}xMrA0RgKa~qY_4oD)xcJQGD3kIRs$5Hi$m$Tid|{$elT~d4GKhFk+;3qn z1@`=&#|HyKvtN|~@6Eevtv`SMybTOg=i=Z2!R?Ey>A|sg1;2e~8vjhN4(% zFf%eBb5c*^bRbDee#aDqxZPB)+m^c7p{9`xZ0>yKDCHK5sGgMHw;-~5LvU~WZStd7^s0dBi<+ms~=V}g4M>dTNkH!WE zm6lorfP|Hm-{?|=tJ)Ska$3uUcc$)*PPfZvaE#)Dw2GV@6K#kjwN}WA?q(5->~cd3 z2Zk6x0^l@Po0-~Q5eAqnvM|sLG;8@AIKG0*J229k9Uj1 zh3*lE8Es~s0=HT)uLu3A_6}srQe#U3op!>xL@p?wJnoz61{vA9Q zhmc`T*9(o&i`@;Mq|nC1#5)~+pXcuZUQbggBd!^pdhAItUwp516ahksFxr6#f9JCj z*U0{^@Z}HlaESjNGe<553cz;(NYhoIl|BiwqdL7i-Nm z=M&d`KaQGpt^qo(x2uRzexMu*v0kX8Bg=yR2HI{Vp33J=`Sspa8a1DZxp^c3u_-P- ze(Tl<1V?z5bk*Fzqd1c6bEsbtNS`96-wKc1| z5OPC>kgD5Q>?;Z!JUpA#`^j5EJ2o!Ds4)yGP2I0YGOJ6cd33x+wCa+GFv%vmXE}RL zMJfdZE&RCh35i%{W`(FNSKA5mTSxbVG&IjUf#$mmhU@{ThJ>=6FGtwDikWLVb!3+0 zO8)k?>6uEi^FylUH~Cgj&&j8CjilQssmbbi%rf55{Cex#GaMaWLc=1W?vnqxZKn6f zO9IyPl;4TR6SKh%Sk(oS=?*2gCFI{v2VNiQc>mwKgj8M;frZ0bJls%nC!5+Tl9{iW z5VeoS|Fc9|?xn|KWb~%Ls7Ne@TCqkz97F9$wMQ`coP!y!h0d9L%QLw3D|rJDBc?Vx zbACU!XLzr{Q-pAF*JUY#* z5AU_BZCLRYe!K6$6WvDE<+OreY1V6>8omooCd|QHIU^@LSqC6V2hiFyjIu?;odPDu zQk|LdQvL5H+ns7qp|bzvcSaiMpExw(*t?M~9XrT|loXUm440bZa6RR=Y6g|97SI5g zVz#14DK5hvmfWOTAduiQ6*m@q|I%lv$qAc2of97g6}e%rO`PF3)yyniNhe+eikI`jKBP^vdAKI}2?^P#!N0_%p|u3> zWJELtuB;zA3U*PtF}1Hjs=t2&L*!U8m(wKgmwXVMY8I;g*2AEXB|$X61pKKnX-GELy2G+2lul zROHw~-CdpM!LFv+&HY8db(OY+Ku^*A{XmSo_w9xdk7Gl=&S`mr zWXGhXE`gv30j+#h9(r%8FBPK8{Nlw}c*y?K{sB=kRvS||{F5hxgTnA){8L|+njHX7~Vi1+k23$cRGwaJXD&>vri#sz78lXro(qHLis(g7~ z1fJ2DJ`pinytUfmcSav^L1};wbB0M}Wo2bGawW5GK9oL@sEEO<&#Y0xVajsukD(n1 z#pWD#rZeVW94^~z+*(o&XulKz=*DR`d|zL3zR&Z8Tvj>PJMj}xQ%u!$x66C zR|Fp>FCsF85X)+fcZ-dKLy3opgVRpePyS_ADNJ{5N{e}~R=w4Q3_`iOw#wV!;dpoN z2ju~t5+O+SPb0tGL$>J30KY{?m$tqA30&uoUjryP18>3tLxY25#l)o68Sv1&e}w2D zI#g3Lqk!9Nz-v!w)I!a~%J|&%b8)#-jYsH6ZEXVjJ@U2|BbIm^Dvghrm}sb|QeO3% zf)*CkxV9!HpYX>EUDiOME-5L&%slS`Hv&9W{a!_txS#oPwnuj$Qi|Xv&`YN8FPEZ7 zx>t_l<>q3wm}PdGdlfX>WclHNMl+wU54nqtK$ws3@9xDs9=C@GPrV^eu<{_b!_io3 zXd)6ke9pHfyQ7ToG%p^z%5KEH%cJqo<_7EkmpcaBS{&}3)nbdaZu)YQsV|I21Fy&B zH)vS1^^#|LuaQApUZdkldBnsbCK?d}Snq02DgRU0u!huc(IBF>D$gLb3 z$5pU8uBZD+PB*!prJjyd**tuH>6$YQMSyuh5d1^$H(1dXgp`z&Kyshl>O9#uj$yUb zLigWW*q6TKE!JhUJ|TP4S#8@xr%1=!@Z)K%?t(CAN@(&5#NAS7@l57p1fM_aP5d++ z8rHVWtgVjLov(6WMcb@;>i#-FM~5FJ$bA<|@F1eor>|4#IS(|*rHf72xMjBC#tgi_pu%8Rwo8vc!zhzU z{Y@Y@AsDJm<_(^4pMK6OV8WzNLb`xO_O;vwh@~F|yDOINVA1{rL##!@(p-1W|G1-X zqEa31uU!+M2je_k477dlRv60PD7*?9~xPr z-az3e|1t}{d7r;-IHlibT`NT~vQ%0j_o ztvyb&2jQ-BvD%zCL9Mqt`fM~TA$Z!T*oXYa(K?yi1J-49X{jaK^BI;sZ(}jLPJhK} zwP^RW(?`)cFc2eTyU4*zu9;Uu|x4kdgvPqf7zl*@L@tv1@JwveJ#mC9{SO~oJN51N5$q}kk9 z44JHx42R9#2PL6_^9m=MujAHXdq3pUTsVucXtU+CC#_#Z7k9qShj*%5wb_EX;d9Gp z;qv;Os~dY_4{@}Hf|5J(lwS$Fq@?!8VzIB8VvJAS#7_>FYHIkK=TPnb_KGu9Js)lS zZ7`rr9Dy@;`nvoHUB;LZqE}_U7{arj5xFHP5&zN_AmpFdATg6gwMPg2F<3LTqTG?N z#Iw=M49k%o8ldEefL4_oA9kQ#I$z~WJUg70N^CW|D^rcr=x8SCExzWj)9M0&6?}84 zx0ouvGpJS9elV_bvUssQr`P*q2{r%g(jjo`0mZjrou(QpORC7C#w+~sWfqzw#UlAY z*n@c{UeDcyq+0x50?WzF-vckfHq!)jJyjHAXL&=K#7Xw2*B`;&u+E#t?v#KEVr?Dq zHJf)q0-^y1_t0r;U?jl78-4C>1b4ajhvOj(ancRt|7rm^b5H9D2nGyKw;R%~OJ|VU z!bHm13>RrXg^4U=Apd~|GWONZj)trilOqX%5htsh!WTgJ) zr(=q0(vf-%1}_eZVTsF)-YybLDGh9HcLE5qnPOS{zPX17_hUrYXD0{`YC8IVj=8-Y zc#L{*2{*)xHyBp6W=r`_;WEi4#eb@koW5o1g9;SdotEtLi}L~o$ngk@qRGay%a+mW zgHN-iA`BQnH$HTCy59MwJ7_YA#d=<$Uf$2KB&pInH~SZGxp6$;J_mh&GYK&`(5Wkdirq|LzYT zNp~e>69SPPE{BY*h9>CbswITGVB;lzsI&&LYX26fhn-SZM12Sd%Q=_^`hLj(7JJQw zqtnle(D2HfI9TMiLtgH>bN_>2oXxQs7V2CH61OQ6fn1K+cIpb($?QK%-6H-#1@HB6 z*|ALbY{eK6{ZDWhf%C3`Pm~K<=TgoWqzYg|Kw6N=q>+sZ2t@Mu-d^GG)E(u~Eps^F z|A&GiX-a*TP*ebo4~@b|_}Q>s?MECsqr&ooh3Byhqc7+~2Ma3{8c5n0wPazC{r%h& zG;(?0$0`$(@q#i<^vg7qK#Ti6aRG*uXv22dHwSwdZKCo;Flt*LKSqAcbT15UE*oV? z^IJtM3`WaZ4UHacaJp--Y`jcswO^bbe!A|nGak}XuXN{esVPPja91r06jKDdefC`v zaDD3C*^rD+Hb!)~$iFr@kr`U`YYU_Q{PE~NxEJf>|D@OCe_EYU0bdFK32V?vXD!n(OY9-0r~j>n^rCLEfo&4`}!w_AhUW>?=B#%d`gc zzZDncVB(@RdyGq%@{Z36vk3yk_6zxpDzT`C`vY5!T$4@zOYsGGegDy|uAS?+kN=JC>jrwa$P~24EBwQaqKP8KEIB?tT^REsxy+B*#MXdW zY!}7_lD$~M3rX*_yrD`{&+&Fdy)@$$NvBjcUa#YAiq}D?=#E-bXoF(+*MX9%@!#_- zR=10$tr&Tule@h;x}CPCo(3B~XwH?R4nFPQo}k>!qdK4L4xT~Ex=^;ax67SbrZK9K zW>D!Qyd_nv%3oD|>p6Vsc7gv9?;}5n2)tN9Dw{)Ug#^9Z75+wy$Vs#|hl}Iuu5PWn>uarg$6(kR62Fs%OhM4vzlX>MS` zcV{`%6us^62igUZmpVF3ArAn@E{EMCgVKx3vD`?(JLA7@U0^rfgLwn8t{=z|ElLD7 zl?U^_kLhhaL!@(_1IOOP9^!gYP0xb5z6=K{jKchUHsvDCJY@%l2djmKtKGrI3}4r) zqwy3;Y_Ky`^&9`0um*yfJrx>*aWG`UZCjf+n5SPtWJLD~;@p{eI*a)M&aRdA@jkNS5 zB1e!d8j4^hlp&2Bvh)>?iJAF5;`D< zy~UCQVS|T<2Xty^Xo$U#M=zRS9s?I4A8n%oO@wo zYsDlbp<@gQH)#sZHtNLI6x9;FT;>eocLl^B|J|O~TInEsCJ$KE9+`Eeq;B2keqsbS z=taz{XVZ=!W8}vIeK140SZqB5-%==;3U%@TzYxy~e#Xc0TK@<5x7n|*_=AijYnGB9 zI0UFZJwOe6XExvCzI+z@zmR$Sr29`FFYmJo^LutkS}9rY-0PVgutoo;l?UICY@012 zVlteh+miBn7X1G(@O~EiM+l%o1)^d;&aPCq#fbC%&t~8d_W82--pN_O+RbJYRrxq! z+3h?X>O6mz!RvnqSvF4BYQ%t2*Xe0mw8dpr1qpuKvGyl>Jr+K+4_t?StEX%RAwx=kS~_U5+!G<6n!dnzB2+LbjA z;rw1OU@Edlg#GU#v89+ui@vD&NGZo#;8ZX?+R4bbW=ylEp=l5&Ky|}0$$A@S*$C4NqM*SOWxx#ryNaaM?vg?qYeAKNH6pG2T zd3uiGNzSKJNf4vd|HY7#Bm%cHCn!E$;~f5pBMJN-5mesKkCuS@>)0D3)9vVtLktz{+U#K~kA=vu@Mrw(!Ku7;B2}{J`T8u{ui;Z+U&c-iE6MYTnqLZ$yZU)YP zf7sABpi2TIL%AUjBkjvNhbQsARblD@srvKoap)GH?or7#=DNA8@o4uxB4a&*{!7q? z1kmqP#DfM8Dy6QWN&0XO3{Vu-9xbk-Ad_njW;CUih7A}D4KL5c(ql|oc%SP?P0Q<-Dy`lnWVFX&^u;a(o#u^J zWptYG@ILnCJhLth4IXIW8C-6Ur@5I%X+Jw(eULo@()j-Q_VF$2g_irj@?r)C6QJ4P z3~I?(2sH=Xw}1QWcs9YK1H=Ks+jpA`DQ7BHvhnpXv^X4jI4^8}{Ch{5`-p6n6+TO_ zs~yrOba3sQ^5|`{1Y5Jb`Oj13T7{;pvrfl5s8EOiUShL0GWbr?I={eHkb{(+g$Tnh zxe;Ztr3D?*H{zYW7aSRXyTQp`iCG^1$tV(a>Px9$A45LTxj$~e1`Q=}bjVO}xGAzV z+cjGsO<{A(G2WWeWciug1~jQ<@vMRD-b%Rr(uvg}OwnbR9jc9tj2@X^My1Nw*OnVG*8%yBaVXqs8;tl~ zoLWV|a_B3!{!29BH&OJ*XS$Ial3tUc=4TS|-^8$?_JQMX3l?N`77b}Lul;3$rj+F5 zfarI&8#f@4xj4F~^H=!O_02p`xqG_Y#ne(w)@dV-g+4dxB)>3G--D*GgQU@bPRnms z!#l8?3JMAwj%K3l7Z(GDL*AbUAZ{xce}_5cz3@K$zghtHwDtVcW^+<~f+=oKKTz0h zGQjmqb)Dwic$Vjqc1vzaWlsSy{tQt4dpcc>Opli+WJv%XYx}!)i-W_}wNiG(Mfu|* zc|ejAZf;qX^7Q4PxVZdZAo~!N(aKh$oQFJY9@1N>;sC5_6Hp1r>8=$Pp(x0}yJrLg%Mo}z=t<`_10djoar zkLOE%OxJWLW>kohmdqCL?Q0s z{};17=A(cGytgm$Ig4_06Njm-k4i1`JFkU@wOg9c{_br5Y3|KDn$F_hgL|6TU`|QD zEWwhr2;jOu>9~^+k{8ajyS<(*Dva$BJmLBPY4@x!6Tb8&v0 zzmF??r)%Q3udiT-*o(@twOktc@1MV7MjgmTP64lOtm&MFe(wdCSKu7^@!mH(*Rcy# zRw|Z%U2F|PHY9qjvPk*5NQ@*bOnRT0hK-iz#Lqn0Qm>lj;^(Ecv%#t_gdW2BY0m^< zXerF|nDBB)28H1mZWyutiVOTt+1|lNEuDk&$c{##^xRcfNtjIrA)eB1p`5hzFSmX! zEa@SmKng2Bas@uD!RBVf;P^q3X zj$s|4`)RBeA^5Xewey8?lq@$#HQ{2TZO0*CP=tj=qy3*7m%>rM-o1VAd3iec^W%e9 z0JTnSmdIofaR>0PXtW%bLw3HxuLs4~p(Ku7@CZ&XIQ!}tSs4B@yr8q@4dibn6=~1IW_$AMUl)RkA^K^-A?Fp2a!1fS)YZiUFAM0W!(M)}}m0Vr3)czXBN{UsvPf zRmZF)jb+obvc?Eb`rr>*RE~H&wHeHPfKllj&E1k`Ibp`9PpCLJ$TbF+ug281ms*Ng z4)kE-`+HiFzphL;7UQ5$WsUPt5Jtr)W&?@#29b*8f^>U-up97D^4X zVzC`(4E7Vl_7Rbw#8WHSw$+7rPl(xvgxE>%F3$C@PWbHsboF!S6;!ff z()TBci~m;H0_kL7S()hS+4wa6rJ>{~y}b8`H!;cGaRD&Y0MjmZcXxqQo6C8%eRc0K zHKMPbiw?eKSjUe@>xjoyqy!!n03Y9Chc%7-8yzfcRu?9F^Gz;e&nZ2`9^~VTck1fc zSV|{5XMPEfQRrejc|LAV+?ekR=JfaRtB5wrEn;DmE`2@_)p)#SHyx?o>!AZiP+0Wk zoKVN;+iKdy|B%cGuxsS~7zzuc!uJe1qT-^LcyOHqltXs}Wr{m9Sq67`-A*pIcO;3S zK>Dd4xgJ5MUTt{&<4|gRj3uqEiI5J0#7M|BHba5f>FKYNJhmTF=D}oO}xL)IZUtfO#WZ{ zosTJmwl#ZHVTlPNoT0ILdFw}Pl%Hkd{>Dg1g?n|qd;7+COa~3^@NZZCl#Bq1stVOk z{a0Dh^xQ;XqKES86?ktt5oCw8x&o&o}y4T81|y}yq}s><46@>re=eSm-{mm_Y8(=P5IBsZKk)c_%kz7=jPN` zWsi4v+h3_?c8cpsOWSHvlsgQMg1DEdP-UDUO*``~tv-RU{mm`+$)_j?aYX5|i`ZD0 z0Umq?M%l9DQCdaJFk#v6{3NR@B${{X8Vw$gLwoY4ZEAdyl7btxY(Vrt(irdO$MVi~ z$Gxq$6OCRGk8`_=3l;N^l$L(ezZ#xeZ((G13P9#PKS>`NCZ>fRy1(6vq7RL=keOew z*m3uc2@jd#<1&fW#V$m73^gQN%}wI)mDeEpiaZeCt%8_D)cgB`V4=c*?hPCq=VTOW zgT1_Vi_O7AE(O^e2@&CwO528;|DiH^1sfCS_FEv4SK_$1l_k=EYm8DA;)FKCu3MHG}QwohQ)+l-yQ5N zRxiltC!qzBowWr;4)^Mc7C4ZIHV|7W&C-e+h3u48nkKHCeXwCo?Tmo8Fd*pFC(qYV z>&T7Rt?n63+@)~IH2{aumvBhhN7w%k9 zk#{ssryK87HKLq$Z=eC$SZZ}$!RV{$#7jnnEm#GTINAqt zjsEWW>F_GrI|-f|D6}@a0(2;%5w>)#jZM-;^=e{JErbl@(_oXn`H8_iTPVDmM}bTm z9LJF>|GHnQ#pm(!6ODlOM=6zAJpKKRfD3EN$RI4)OBnzheR(||JU3TEU8{?J$Ad)Y zwH-sPnfz7cnWPTy3hIa=sq)Rhi~$tLWLw?c#p9rw!S{L4$<$T=^+1(SX* zIZ+TrT54qWez?+c_n8{pjed|MWl6csewZq;+30=%Y#5tz4P<6+&k6q-UcHcBI;5r< z5IYPa16`GwroFFAT%-og$|Z`IlNu@sTPHgFp4S;D7{IJ}w#87tAraPh+-vAd1oQtA zaXUS`uk?cP&4c8)E6Zfb^RAqGQ|kiOZ;c(0c!+pD+J6(chg?LH>&{wj>!9!}RIv4_ z3<-4+D<6`&AAUfRF0WNeW8sq}x%>5JDo1^H&LY#3x?LWXlXZUkUJuen=4`)OhK%k7mU5g z#p(qMS$T9b(;xs#<8pF1k9iHOiUe;R=?C?bqe5-gUq!($cpMAaK8Zz?_X2t60jH}! zOHSLWBn1GDqI=#0L#2_7XbiEevF@HAf9O=1mgQM#2iT5TMy8A8=?f~Y7S)w%k2sAC z(s}h)%VjJROBU*alf^Bi2Z7r%!&V&e>Zk$+il6ZA^^nqxWm2*pa8NL&))Zt2CpL+O ztIj^-OVtKpHr;Za=xS(Ja;q&B!58PwwnK(9sc(&vjYd>cM+Q0tOk$)5JoZu9JHKES zCnqQ5_2Q?Clq`E5*Roj-ppX{ZGai==VriHo1UI91-z6!H{z3IU8fKZp(Rv+#!sBk=$&c<<4cg@~R)sQtg)O5lk>~BA{5Z zo~ZhH{i=}5;s-}BB2Z5*3L{7BdcV5mEu*IdMX(=Ie{?43IB1%)Dq{~3LA5hNXMT9_ z=h3JVv;%E{?ve8E4^hZA=5(Dz7B9uxecjPwU7cdfW=tyjw>4zus51v~8FSO@a^8$Y zc9ruc26(Mj*BMl0$L_MWEg5?6+D;w+PQiAzkuLGgO#4{}e}Op>^&E0pd;1V)l@-*; zF#!UyXv&OE)hUpPk43+m0^0!zd%u^1=VLAi>#9C7gkIsYpDl00P^Xp>jj0e*Y*+@w zu;5xGEw6@hpHhBjh#nNj62EMNuc+>k(yDVmBo2It3cOvtxSME34<3Sz)vjoE7ylBi z3@INcBFaK9U0^Wo7o$}Ib7f4-h?Q7ew&dtBoff+~JLL_(e)ZzJ?E3$dSN|QJ*H_1> zU#>LX+qH6TOWbudb>{qV>}vgH%WkC4J}fSvw#V*Wso8I?8(rwt+WT{Yjzp{kux5gO z%rV=O$=^V60O|9~FQwn3y+=VqA|IhNU1 zN$;@ZL@`4#aFBQRFbEbCG}(^qW8Z0-txVF9J%Lrg#58uc?qdP-uW3V|&`16z{#ax9 zCb+>W>VpM`R1=*&@*m@$reo=zj1gQOKV6i=6leHXvEs>um#hn&QqHc){P?D!J;TeM z_xFZ6H8Iy3k!XUOB~Yl7Qnr!s&?*4Eqk3k@%L)R8?uoV_N{pwfO&$;8FC`KFf-(v^ zg+acGuI48oxbf^w zOO8sIx}Xl_;-)@Vp%MO-Vflu9I*C1ehHY1z>U&w+uU;DSPYnFD<{B&M!>suWuI0x7 z?7xcl4=ED;M!x5|ET1RFHmVfN2k_;;KL$Ggs)+x-{{PFC+U%`i!2i_(*56IA5d_TC zUH5L!e7Yt3%+IB*Bn&oGX$=J}E$P^o6r!2Ba;ZCE1BJo1L+v5SER=GTzS^{2wM}PDzS)07coZ zkr8`-}YTpRh9i_QeK_eU+en2~5A5 zJf=MzuxpFdT9wLRh?c#s^VvMa#PYrP2q2MP@p1>XJ97}bUMKNy%w{cr2PERQ!qlGv ztLRI8vOzH5B}MWBFu&kWYQFj#xM~1!w)4vq!xeMZBgKNn^_jj(&F*xm$-z2TY&5j$ z?>mWrQe?H7^`mVA6pTC(62!K%OvjAw6SF6lPIJK*lWygn8Zb@d-@hm7dAZ>xWZ$UqlyBHwUpS7wk*DnYuIzs6*!9W5X{ zMY+ipNWxnHw?NU;Ma9}Jn@VH70|Z1n4D9yjG0xeYG*mQQshP#OA6wo(w;3WlZhG{8 zOw*s~_;ea^0j>9csUAa0R&% zFw@tBBdGitj>qY+x~}#iTxazJQ*kKTnELv1@!>pD%c(4dr@?yf3}U@Gpfi*MCh9p9 zI)glG-~5V4u!}0>8$c2pFEG{TrZ$Hr6`ab_)R?Sq0SHv8*;=9-i+{))5T4MUgP3sj zpVL)Z4}j6^E`3_PespGru;Jbz;Vw5n_1-EW>}W1D*=y?Pc+JH30X9%G*Y2`C7As6? zNUMnwkHQ8j0r@ukYCG@ezju^{Oj61xCo4;_%0FfT^l&Y$-+}u&sxnf!jubD4|~GXtd|>YpL{4| z5Ac_`mh-()AWLG9<2AA&k2mjmU3PJ*7teP&uK}jDDmmVq+_&v^J>$~nvjh6*=aT~i z_B%e9kkUn|tPEgNE>WUiu=mwt_58J@WbjA9Te+;49yA)=aqV{>jKrw0!w1}Yi>9sb z5OHjFPA>!lWJknLE-xd+B3kl@SXdml4t>X;ur-=gKi(GRmi9?-XeDuj3~H%yHSecgBB^ zGc<*14Im2C72pN-_U5O)Kb_Q2C;mMb$&9qTy*0*^$~*G+eH$W0|IcC-Gfpxz(UQ z4tsKP0xq&(zD^5FBiW);J0PowG6H%BKn;#>(T>94ak_+k^K@|u$6>9O$zqAI0K3t> zW6imZ&sJ|FT7EM{!J8!_Du^k*q~J&G!`@d^(KcOe{h%ok<6ma8iR?sY&A8ae0@3i->1;ye*EtbGd_Xb3D1rR5YK>jpqFQS2nzO zm~ynT7H|_b(sBEM!)!XoRUt?bh0JT?DFZY2Iw7;FEXnE6F0)cR6c=o!MVgiLXjsAT z-yvnh0EBR7!R~9QD^1>@wos#T1U=r40H@=<{qIb_tD{BN^^sC8Qc?^$EosNtD!$nw zP>3IC`w`w}tOtgLs*yGfCAUg32k9_5jtyXxEq%}A$sy{NDFC}K;70&V7#kl?-fT#j znV+8z?4INhKOiAmPUqk&sRU(2ouk+(fSHWaF8}GA0N!!GeZ_P!vky2?sLcSUYuaWw zh3Y&;NoH@9cbjK`rT|=2iX)T9(6>0L8@G>wMg@nQ-#dp&nHB{dt(MaZ3T##<*mszA zoH@Wo`7tfxuj-(8c!uLo-$vHh3YyO;s+$|Kpt}+!^DYI8W9*36vqEe~K;fD67y#no z+KOVGGIVQL$%TsSV6Dy2FqFyPGTd-uOFORhPshU^;EJgF&9dTB`c}436lw~D{Y!}& zi~t!X#!B8mY>HvuSJ}`Lc>9)GyCsZpkJ*yf?T;;syuT-E_XBHiDL==NCCA0=?=1rC zqz+FBw&&Nvz^)?b1*xg)-{U~QDSQRnUO=`S#&C+`#(qX25}LUA=$R;B8yEbjNW<}M zb_V_!g<=egg;i$8C3Q>j%jrahdg zI$h650W|a72VmJwy=X)Kna8uQeRi?Yab2jH{xv1+X%WeoSXr#u_AC`Omu6-qeP9qU zJx-liN=BkSgiSJ!MEH+&WK-?AlaBKhLK%JEco`2UT?0g~6!(5q~&ExRY z4?4{rIm79=yHMfBD2qEQe7N9G! zriNT!zXGN}6@(N;z|W9ancR45|I~IhhTT9V440X$RjFmC5<{UYE0M)+Nq$USU*!G7 z=%iY?Gjkudd^uP{ZWo(c<02PeJdPtUB`RRVkk}{W;_|7%M@cexki+&4FQZe61w?%G zgUL4wAsDDTx}s1_NNN|moZvv>#r*bqjrDx{GOzB$wP_Vy{|l1zEeHAVP;559I+^$N zUt|hKMACQpO_f;>CyYO#ynUq@Q0=hY`o6gKRl$SL)C~zC0$Rl*DVB|N01g&bcTY5S zpKFGK27G;t$}p~Wtu4$X=9tQu#^vQjmSht^d=)!@`BlNG0xqe_c#D9VBmCR(>uVmb zn}#S4_7gPm8Z=5>8azSBmq2`3qu){b-d`dG}}){D^S;N^bBAwE>A=L z7n05C8#olqpiiqfxppQ*+A-xq}zVeIYfb_(^dO*$HIcdNNR z9?6F55DUYd@5uP%iDkg1%+)p!GnfHRN>Vm?qd$&RX(~_D7=?(aW-wT#l+{!*Jmw`u z5R#=v)R^aaX95jjvr4`E>%f8Dd7jvJFhPiYiuRQ?3G8Xs%D@CG5MedO>vDF1MMbr9-I) z=44@*V3e*G0ME~HhS8NuG;KDb*vB8S#~Tb$Y{Osr`WPBXxtovqDFY7BvUT~#3NFVL znC7=Pm*Xqsb53Ji*f7QzS5#C$l{#y6c@9q$a7jilfMEpY3al4XiVYNI_8%c+oAzKgW0Jv=kx$@6- zrfPDfDmu}i#ZI;zQjx+sz-l&}oo|n&&V^jRKi`=Z*3bYbmdkke1t9ju427Aq1?SQ2 z@jTr9Dk(>9a`xsHsOc=tbX)Nto^Er6l!YB|S2_B%6$8_S!umDRmkR$JSoVi_J-ddk z=>?0FO2uS7&z;pn%LBQQYHk$`gg!!2Fx&|= zzs^TUn`7Kh3o6lXZ*MWkBX}7Y7}TejDivMVe>xp;hJ;fnel_vAxp_09KoFeKPOVnK zmXZq+P?rV$ic#ul584pFEGERYHK5*K`S|A=huZ==rznV7z&EaA_ZPkMB}Bl_Qz0Cr2ICx5(vfR zZg3*KXfYr5-ea|LGFeW9ekm@YZuNZn{Bh?7D%nI-%0x`l>zFn523fJC#dETVQi2*r ztw&k;#%j@p4{K+jUJ_fGF0Nm`B`vj;GRR`3WDi0DMn#GW+3zsN@2oRp*Wj{y`dheA zl2lA(3F8tHi$UBXzp@p)z4m|cE|g<8EM0yp}0ZRG#e0`enY>Kd6z!0b>!wkeDs_xlX4!H@>s z?YemtnX%}cz`#f#2i*HCB|G20AHyPp?>eIP+i1MlMN)+(1xhEcBo}$CcYlA6L9I=1 zdrgqX!MtO4^q2)kwM)L$ojg}?wZC@Ek<@N=fE2&yv7IaS6AnV%ov(yeC}D%~jGq=- z$;hyfYQGnRP>2J0b;do;LbJHwT3LXFBtkF<;n^o`*M;bCT^?5*=9Q({BiB984qtMU zR2o<>*Gqhgm9R>)m9hHbu^s8!9>ad_JXd1J=~-a^hmw!EIkqw`&S+kFkZttse5^T( zPNPd+ivo=uqXKdo@Io_??Ov}K`zS0Tf{Bf7xmcczH+8ko`y7sq)sRq-kT~BhO|~@Q zB8=$RhPHTNI35~e{YWO1AusfrjjaLcXx1iN3%sv{$nA_8_tW3oz+FbAwb~;;>js9W z`3W>pqwd>_!+x>|+LhTe^yz%h~4N?*DquLn^?p@VvFiWXg`}tFYG-nLxe(;kXXJqAxmBuF|pvUZ< zYfP1%15t$rv-QBkq0QgZRfoWD!t5)>ibr91ymluOFjG`@(?22^YSS{^K57tq5Q^Ds z(9@sXaL*=%mz4ojbH^iRZHHVwn;@2$c~VaD-9bv|ob$t_N3anhi9BW9Jw+;xuFSde z))DUlm{drvX2PY&rf9E(yFaTEuA_|rDNbdws&loy)d9=(kSlNa!6g_?>st(>G$JBx z^$10l5hOvOJDQUQ5C0=(A54Vh$H5K^s$?Zud!kJ2VE=~1n%stlL`ujVpXrY(BDrAa zuPGJGYF$}G3ba6vFjy#`SF;9GbF)=cAbT*KZ6OO(V$jB7+S}gQ5tgMvJAlgHd1RYh zt37Zq%ci#Q75P$RdJ9B@s$adJBhkOie zS|9Q`s&VMFTV#xoN@O^54#?5lPHS2{&xVAdQ}X`enCP^M1hYO$e7A9VYz7M0n3$z% zt)Zv0=~kA7ERxE_d6d6x_DV%)I2OH*g`}k&_Omg4{bjGuZ?KaF<5T_n;iFCTXF9R89K>fO5E-aJNje$_jY!yW~7w&Mn_SMJAWmd-O!wkQckoG@mPKs zP1mL=R43|@UTi)(PWEe`e$8C0qMzYjmZd!v9 zr9zNQI!V&sj$$6Uxxrz3$%&kTN&{O@#}{-v#;fngJEA2X&+8@c%@fYg&*P=R-Gv5@ zW2k0#UQmUF9j2Klfrh-v^UMku*G{aWprHxZLj0gp?~&nc zwScj?rKN)$yk?zyN*ZC(AzF6v^|XK9wsvQPT4C5^QF7z=4c{W{l;D8y)Tv@QEe>gp zR3vV#MHr99Csq%hBz`bH$2$9SLG^FI?zihtk9q|_~JwZolI$;!PeasyJ@1)N zu{d4wWbvRlA(0)o(N*aIXs(9|Y>uDyV5eIwgF)eu#bQZZSjn*SuP2$X-OX6$qep|o zA-nUOSC;tJ`Tm^VYE}Ju(qIC8B=v{{8npUg0TRM_DuOR2S3~T<^w)H zg9Wu8Hf!OsfC0I9aaRuhdA3+CQ(zxRlA_ehDda4mw}#o2>?>buWf0G!$MCIC4Ge{fS z+oMyNcM4+mQ>;Avqi6(&2cZ~)q$)!Em)lZ(3p{F5m78?tbGaJMs?He#ua&7&2OqSA zA}cs7pu`?f1)M@LuKYdk?^Tpv=(VXgwOO5oA=x0{YFR6 zTPhL5H*UysU`!_!`tava2|}H8!hGd=WF=yC2_w3K0u*D~rG~q7$3e4bvJm2uYWuF+ zXZzYBl})z*nLF$EC5>)RdQrs==A5Sqm^^hlVkR^7!7Ads*jQKt$sA!!*>^N+Zc3xOk&Lyz2cuK0E6)EmO*$mr zD&$by|D3oHhT`bMY`v7tU&*rgZoPJ{(nBlgP}sddLgk{RxzWwp83~icpJ5?iuem#P zSA2`bLsqm^TZ^JdQ1n5xFv^PPBE^hWgDse5ccv7rS_3Sx?c*hyQ(CWnvPBk9i4~cQ z*Iey7%Ny^DQZWHEAVzsj;d~u#3hLt_{~#hWZjo41YoW_HoH3ndZm8Ho1#!@GnMLUO zUhPRbrTQyd-b=E0ZcCq4&RB*JOrD5C^-y*D+%t`0lNI1YN+ly}*lwtiTHmDE^o^TY zV6^&ce)`4w2~hz&;I`4}fQD8Eu_43eDF&3w-ylhH6o`9e+39lmv~BE^=ziZi$h!+9hV+0?a6Q!I zI0`}$o*WGJ2YDZsv_N)Wl_5nf$L>9F<%E-vjlYI^d8imhr zddIfb7i*y$2BaZ547PttHjSrTxd`OHb185XPxLiRmG5ZcX2CWyXLxE7kqG3s#Or5Q3fwcANJtrV zqS4~+Ik}Jf!k#0cDcmXOn)JM6mP)jt2hqN=GuaADO{xTr;_9>hnd#F6=l!wxa%W{e zfCPh#gcde6@k?ON4J3Ta-!OqP_ewjQqfAd zJdf@oXDvkZEwaPkE2Ep`s}v)A&PKQi3pb~bqqEa?$HU(@-88PYT9y<(6NwMXH~if( ziELx~KZ0AmYPTo%*uYebynb~wzZ{q@uGzLgD9TJ)<4wc&neKR*GEa>1;8e9|AmWq6 z?)uGMn{5dR^|b)!7p_8v^}gvoJO++DAve!Zg}#>51NBZz(OpzA$X1^*#aaoPV5ns4 zpwas%KJbL%luBkgAh6%;l}%={ z-#a>4ADC;q_AS#o7B!>ZkJTk)Miy52JOn*KIzN;yGR_0F=%+Ts#m5pGUa1+lV&5ke zbG*5Jv#wGxS7F_B^wAn*&P6v3ur#Gkzf?d)#lFjJMxiE3LJuueZSU%@#x0~0vwu~z z&umM6vQzYgstMQrq`0XiX@mvpMCqtQ({Pi!2+K3d%q4KECH5L;NZ5v4WKYlUy%iNAt3VM(M4Hc z$VZ~{Png2ZX%7AC`D&{(;4i)ni;MJ(r5z2Vg|zy2@h5B>1wi^NlY`2tKt*J}?X-iw zb~KMVU69$4)8kGuB_8NIygshO=-3k^>ECDJycpBuGP#MpIMfNnq1)Ry@6J>V=tjQZ z*-1>oO^CiJwq(?bROx{;rTTj2T*DTVp%nnh@dyg~`ibxaXC%XW_W<7F#r^p_uf}lX z3rhN_J(Y9~OyeROS!z=Y9$JMG@g4HdBl58=L3Rb_Zb(kP zjPmJLA-(Hjg6Zku-#Y1erp8rtm|L4ZG?kWI~t zce+cj(Rer4U5u5;?D(iq21kP3{M3clg3S!@*}I4i2(cVDZq~1)RI78b@?^Z6u7}#t z@YsUU^Lem=Z_FhM62{LO+<*SLT!gyS;@4%uzveN|i-~L~D zG{r1gNES-ZMExY_RakQEb{$Y(J}J!f1%g`Z`AQDt(Y)lEou>O=$Dj~{iud+4Z8azd zg#f|fZ2GO3rt?;JPh*1@Ot8KCZ~5aEY}2Pb&iYtLh4zjrM`PRGSBD$TKS4yG>3b<> z?s{2ZS-zU5b4+VzCx%-#5|YwOdy?L$lg%+Wk0B5qyT zyGM7OkctXM3WDxnH0xuKdChTpwia1^g|^jFKHreG^SrydJ}s1p$}2ay0yHN*V=fol zR+Q1B%m75kQmuT^)j(NO(9EH;(xuRyCtznrIX)7<9{>Wc-3Cx)ZVH=av!0JDa{`LM zx~!nh^33eJY_0dJsybVmOBX9AD-X36{MtQf(+topeh(SPcMALEBKkE=kis6oaB931 zG}6{5pdA(1DdM7!iYawYJ9dEd|m3^I-l&@U(xWo|%@$f|I(KNd#NG_&; zy$yv6s$!IGi^C_hq>$KG0@&I%klfxCB0iS`U;{N@6<<2@^2G}-P^6-kE-GWtZ8b1A znsB5~`zhW8|A-c!*+?42X?t4P-9j}a^P^^Rzpn8Nm0lf6Ef9$`cmYC7(&#eSruh%I zttYWXsX03uaVfFIzqC$wmbXJ+mfwF*E+{9GX<#sMb^pp-qd?yem_7o1xbyBISoeL?vht~SH(=2rl4oS$zo9xP!I`;F9AMTeip`1T`x>6WH zpUsrAtL21kspjJe;rcD*OzC}2-$X2rrH&fsD z0|ODA!ly(*-oJi-rrzlL*InH3>A1>V=k1&dkx835D(ybaEVaINI#k434S8|~y;h0* z^tQ73hSh7ZYS)+Zw75zMe|)n2G$fVH`ljN&SAlVer0?E`gF}*aVHgXoH0O9m%dSF` za-&l~NIfWxfGwbAxXPlBogs^oWNHH-JScR?>)mhpS(hlWs!W0g@NlA;_e|O!h)3C- zyu#8Mv(KwKX+Q9^IT?IcMEM8c`8&h*V0gC(2V+-Xrx4}i%Xiz29%g+-33&4)L4nJ+_nb2bY_ z|F6a$J8l6J418RQ*Y{9Yp|4F%uXw9|of7ks#!>2iPF~>pJ($baz7ALj(9dAc zp`fAy_)bWq!M1a3C+`obsB$T~oAGVgl znf&!@Yay3_*RRp*PSS%^=HxvqHkZazlAyD8kHZ&a-mpE9+>rIrTZ9uZ_(&46wK6h; z!qbUSxe9#bAf0ll88PJ|=yt;?W43bz3jn3k=6St*$S{UZIuDv7d0q6c3k-e)!}ovt z=1H%^X?e5twzx$H1N?^Gwz;*nlU6r*g-dcoEzK@OPO zQY{2vtDZ|o{>=R7{wu!@&VuUO%OpHZG1$1}&WYGI&Ap@`*>ljY`{KH500IZjAHaI0Y%3{t5TI@>9^I31~0&63`w@ z)yFq_b=*EVD}Bv`xl(bUc}JejTs;93RlHCoo4VHSczUBtRvR+8cnkvB=?3@8^fFm# zCzSOo(8PcxVene^sEcEr#rG55ukJ)B880l+XhYm1T}ESj}uR!JkNYp$E& z)&(-w`iloO%~i%$G}8$b@G&ut9tOMTU^{(mEg4&voNOWZ!M}QNFflRFU6!rhR+H*s zA?fVvtI+0Z_Ier)+Ea|~eyn@BJ8$YSl z?;|}aU`PGlchEgZ;V=j_0K|pgX)Pxy$qw={1w#ZNY6>d9ecd{81`YEexYw}TrwQz4 zDbR#eyYo2dZD1o^RiBMn$4;jHO?=tkRd}Ic=&QX(AfTayXc;gs8Z)|XN&30--8uk{xNy zsY>&>_`JaUgo|&>n29jsAa;-M%n&--Fk?RC?JER4=FQv~S6*_hB6GhJ>3!i!rb?&f zUuxXMU}JTCu^qn`0;Irc+?JVuoYQy^6&3Y6E2@SxG6aWeh^Xq)>dnpD7{+rfkK4EW z*&zXqcslN$qw0LfEEC&03;QA;Qgr#+AW1o;`wLAjgXgVKDs!dOnHemS#mlbcG>F#f z;ew>D4MuLSu4aGm&u0vG+w8LZOirR(<^JyJ_NJuce{}3{TsRim^)xysGs8S9hf0m! zySe}cL@SN6o@H#=>g6dhK%dML_F?E`16-2TE^NKuCbjGIbD`sGos}f|mJxvzEgK6P z*{HMrA|b|cEkUvMR8@>sE;SnVc4JWL=WFx~KJS(27q*^n)28cGs>xAzqs;3}I#ma9 z8k4BHU3cfgH3|Wn!KiwTiS6oau-UL#6*N`}=|WQxXh4WAP0vI|E_J$^&j4k`!Nk1Y z9#lI={J7yIA|^7L{qBm<$R)~0b|gx#{Whw1Xe?CjOF|#UV8`r58FXmiaaLc;;+nW6 z1OtMHnGvi5`a9irB~;dloNh@Tv6yrLii0Z$7=D5XrBYb;Qk_a{--2wbR*E^N9J9iA zL4IUN7=i4OhJP6T1g|&j9o~o1WDeCRHraim_`u-Gw`@-%@ucW+cn9QOailtkV;gS7 z9)ptUvSL8XF4MH44Du#}Ua?j);sUR)$)}i z*sw>mR;pQB0cgqk{i%G2ZgjMwEd2b2tQeo8fQDD-W7J7-niOj(!+hUZzFoktMl9yQagmT!WEUcT@=au%{o&1F`>>2a4stYatpvB=`f} zk%qovk;yW^P+mC$_$E?hfQ^;a8eNsIlao`yxNinkki{T?rhcBVQO1hPDV4ETlwq!) z$Tdtcr1+W6<(exag@@^G8U=aD{0+D8g7f3Q&)-OnP z5lTw8nzBQ`STHmO%)?N;_Vz$OCm0!SUlQ2ex>1vzbE<`^O0&E)1{8D5@+b+nLktX+ zhNh>DN7{q{Ara6B8EbvlF?W?nY)gl7j8A*kZV9>U^MJV!MU&c{gA$?JnKog_$g_m+ z|4s!-RW7*`W$G1fv%0-abX(OI9SROHAt9)2q`ONe<0&`Se&X}P8EjYW+owD1Hj}P> zi9ZRnXezw=p5T0A=fxwPdJ(7NPu9BUa80^BR#EO z7637o%(d`oigPA!cDA>FCUd9HAb@H?cZBSk@Q;t(D_lmt<%=z+ps!hldYU1XN9FzB z+E1Mcl5S~iR@XK{+%hOl;@9seR(ne+DmnFV8K6s?Zpgf1wHz%4J&!+FNuG{sm_eE> zTk{CC)7v%Q**3M5VpC}|`gj-nBb1zIBuX(16X(8n%SN`C-yle>K(NpUE+5%AY54Vf zH<$g@_dO9t=E5=*+Ms@*R;I$b9sweGlfpb?<>F8NLey$SZwRMb%;7EAvv630F~v}b z=3G}|8=c;ex&tbh)5hF-lg!Ko9;XH9Rlea|HbyqpX|}JoiE#nFq6J`M?Uk>oJrn8b z5f${&9RKB3#OnzkXcu0Xrpv*U*HTwyC+PwLr4G~Au&+Jggm+uVqu%hM+D)F;T@~*| zkZ_~LV-Cj6yBZ45$9GPNw(*v_Gq3U4sJ!i*S9{fH1g-{U+}6e&-6;7;v=K?3Az`vF zlahab{2aK1{RRBMZOaIVU-Dnol3fQ7ipBYyRklQhQ2B>50Rhs2N5%bHqfNyHQZz~^WtA#00F@j7Y5h{RuY&ZmKA7K7T!Y*L?wYt!R#BL-UtUc`3iL!-(XG69 z9;oWW?D#wB!bP@bZrYxFTcgVr;o5jKKfP{zLBEd;1Q;A~h<%(`lf;C|`Fqd)m5u;y z8S|GvA_euT(y7;Vz`kQm#@w=K^Jjf{Hmkr)RDsC50@>*Yjfd{1ClAdIk(l31?car; zegm(*ryGd+i&Fm62BG~&R{!uLAd3C}{u!L#;c*O4+nNBZ@<^QPPv;r%Ie7Z#O8=a+ z@$q|k^(VJ60P;lo>)tI4wGrBJR{ZpVqip13g`{P_{r>;LO#A(V{aa7AkdjQa%R@2m>W>i}$@Z27$`jid4<-SE-Yo_V`p{pKp& zm)F#N{Ph9O`Eaa>_Fa>mr7Zr4h37)xPH~dO{)*!NfMELjV#|&HH*ZHm@N1~K7_Qmh zU&CE?Hly1d@;68b*ICZT!cYIjD?Pj@{^1}?jgzJDLcs}&>aBMU{4;u4>&PK#-{Et zCQHrW1^ZP>OEt};E}&n)rBeJwYpYA&3bugF&YQZQV6vLY$=Z3JBq|=>2^??mW@>Gc z_ZXM`k znF@O?-uxL+(LimNH}v#(2dzQ#O)fc%TvN04Wh_kWD^(a)4ppo_MG+qmoPQ4HH)kGu zV{S>jSyT&kM)t=dp!&efHawc8VR&9ER{t|sYT7~208i}0B`jEO6N>^tw$=_e%;V z&S^Vi7L$1a0RdbYfmkZ%?UPyxIUUMPBEAOIGVMaW48p4}c3G*6 z#uk+4&)tqs&hB`%#J;9;+TRo)tq%qU1zl|OTP@!tQTy}HNA{!YR$AN+s@bBTqPn{r z&NV1_$u2kQFV~pq|A9(9+|$TMfGA|2KbU-3Bz0)8CK`ggltGw&Razn*TU9cqQ(4b|9d_$3Q70jC(CqHt5u6%5Bl% zy>5|l%VVjm2aEOmAwY=Y`eQ1pI|P@@`vw}8Qg1q(D1BVLL0eP7IB09^wzC&7jIVli zeQi5k*KCuP?Dzh=RD9{dbhcDum2utv6y{4TR_l|G-j={6mXFUnSerN?JKGSX>%zjq zdcz6Xjb~E%TAP^X373fe!FwSAbK8Ns#o|Rz=U8nH={a0>{Os#1z~?xGZqJumZl1?p z#pM44;)aYxPP$h2eUtKZ9Ypj!OAuP_?@Kj*yZroFc!rAYsab*LQE)=3I{u3njqcr9 z5jGjP3|cxRW>FuyL&OuEWxfiC_ z1BA$~5zltU%C^<>T~Mq1HQrqnuNBtWP8R9E->pAfh|weuy&Q+8?hj z_6l%Fugx171%3qF~M({1&2_Qt3;SYB@8=7yfl zUJ&uP?i2lLPYADL-xi2h)RAF(^CmJtW!zh=s2E_Df%>AxY~ph6N(!sur>zPkuc6D^ z*~v*=T2SzD|2)ulVCAWtBqoEL3;LY;ha~6>EU;}6je)e%jezsW(aI5Y!1f2 zSN>AFxER@3-^r;aFHqFTDCe^B3lSDVO>GU=GR|j>-2G>qe(gSR0nW}f8jojQSc|l#YCEYEAI`@1y358lq4bB^Lenht+5=hu`VXB`GVrIaVzQiUJc{F zNzOM_bY+pU5$Ac4d5mZjY+X?{JMe65Yz#aG=i8$R7estuX4nA`(<|DcUG8!Bo35+E z>cN!yL)%3+`8q4A`1GL#FtThxkH^(%0tUO_+sP91PVfYJoD*2hH2C=wOvh2J@9wH) zdQK;^74bT{y#TvxXyM@J`#iNmZS$2&1>m7qR%T%B&cy2442TpIWN{%i!`lUEK$D}qLIXYcd5(No;^a=`#3EGk92`^@Z`i8lBk z6=fAbkZgz*IJk(jn*YIF`GTd-8GAS7SjO_c#GfcNn@{7^{ZE}K;{o}UDXkIEVR24 zu(+Ga%i9IXw&snbs`(&lLBT{Lc5;v}cX(8R-D z--rQ3HpiC803u64N1b55(KAZDj(wGMic`Mw87=3lL`Bm%o-BEeblPidf>PptBGa)V za#Hy4(!oN$XIWgQBZfvK%tv=s52kF-sw?D#?%v*!MD}1Qw3%dqH}Yy~_tl}FpDfeY z)O5v&2n#d!s=S(cQA*r~fFLX?8obGpOR1a2EFpDu)d~5zid!~L9s4GY;h$e(4F->{ zpQ1g;lfm(3HVSN8a2CAmlqzDC%Ra-%#Dk7^5`u0F>@{BE;CKVk9XZl9|LHG!(i)m= zUSKJ5dtgh8Inx}ylYl8>F`WCTyI6^QRN?lduY?ptp?}XBX)VsMO*13QoMr-YR@|<~ zJM^tV5)9NJ9!iN1mckZ#dJ&VpK~4KE)ylx*`s7}9!IS_}7NQ{$V*B&~o%V1Q56eI z`l-LcBQVygdg8@-#1M6hM8j8-^U}mt;eX+skxpz>n*-z-mM6)O462X&m8M3b!->Rw zRG~m#R-B;p1kzf``KDL*isdczq?(a!#pr;8=|zlwE=4A=l#*ab{5MR@i8C569~-oN zB0;n~)GqN|I8za$?MQURP^oWVl&52KQ0~Z-tslMb*%L|6oDtkm3@Or8;l}%uv!j!0 zDl0PA$&aYftgWyJfRNTChWwb@+qojaCcy6z?)}nxIMp(c`QfS>x2#0BeSCH{;lqiR zMmP~~PP)=C&>Pz>w5hpYgD#D4tQb+7^tw6~M$Q1&cPcjdAok+IZ9#kvc&5UYusBHT z2idpyr~PDdc4l3@wmFIZakI$cL=fYjn_W3Fw`cS3BHkA233(9!Bbuc0_ky@)cuu=> zW$yvhp3{BBN?hEmeL;t+q`0^<9*}`&zuD07*#lPeMVXC~DP2u16`#x6LyQ3$=~FnJ ze-@H7TXL(iF=Oyezw_R4*!}tGh0yi38M5hH)2NlbDM!2YqxAX+~*^eyruO4`Q|Hm;t9 zQdWWRP%XY|0f7%l1m;==tga$!ZW8gkotHMFyE~cdm06jG0KqZYqq$6LDMONJx?9ja z1pE_@PtLhK_gMef&ACqS_&TLYZ>5yeRgS^UU;ez_EV(vBNybd=%!+vD6QF8Km5O0mjY|82(^TyN?{7WM4}MdTEZqH#Y6Z>()Az9O4+cfA zLJ%*=$&qp(lneeRc5gbxrQe2d{OG-j|6U^UnMme_0`>J0*6C8zsn6(UrCkb+OtEsE zYsrSbR#lfjSuul7qe8JLTmDS=a5AfSKRKu|>ioM2)Q)&uc*;W=xeb#nPb{#au!wYC z<`vvlBDWzT4{6;_SXC+a4f_Y@h&Kzs1;+lt#$E?h^&c-3qM&MOVy1`ZwWdGy+MLcN zV8cABrL&4aT#VqDC*Lwe2e{Kv44H&(O2q$-D5Qu3D; zG4YuKDfw0mD&VF}7md&!P;TcH*WM%~1egC3qh5*pD@Fw9#tQ!O#cDB6B&d$A^G9dB z)nc>bNG6a9y6n!$Zs4F1@V0s^8rL^mC!u`guJ5w5_DlysGSTa*)Gwg+>0?d;PN%gs@UZ}-U9+|5 zQ+k;V7`m?eJU7d$6mHuvS@;BD$BO@*MMvz#{9aZ9_Bz?z9OwCSDNN;oS zIj6iSxu`8XKFY7Gfg0y%Tr}W}Kmd0ucJ+Ka^iq3Rww3^&qomn+^6n~Bt=49`3sm1B zwJD$=fK3w{SC0U2%`m&aBOLBZyhuZ1hl8B`=OBYPaGRVP6Bm<;fp3iaQn1xm@Y0pR z2U&>(^^7zvrBCjWj5FflBUu7qssahR*96UZK_Tmtv?=XI-A%w?Na3rWAD>&xLwDG} zC+~kdS{FxnLGxndagH}C)am5qw&NRDp<$vDgwI8vYefikVUlM04_Sf>(>pU9@o)F1 zukan-1b{UHpz;Pira>D9oWPUMpI0Yw;NZFxIHLgZ9UlvWUS7cuhOp9be=<6u91#{l zQd^vrMg7l@!h(Wl4xiv#40?gJ#5~on0-Liy+3`jcM6Z;;cU1fZlGr}AV!N=JaBO4Y zi>JOX-M*f+-ul{Xt=o7}mxeo!Q5>VZ?E8jM6*v{SdF45}6DMuz8pw>L z7+|+?pI`_`;#fY_EaiTV$#CRn9#?_#i;^j=A|jz%oxy=m9RJ>O-;xmd${RHCF61=e z6cYJPSwi`4=rJ8J@^gJ=6N$8FroqoNRO(fZSLKp|3y1mbJp7@ZbxB;9AO4N56+buJ z(ul`aifi9y-LuHUsbEZm`c8K2+2SNWDK>kX`OBEZIZ1I{QG_Wi|B*(TwBR~J@y8UX`_+|CzAY~U!8xi z*oet!svTo62^Ij4f+bKZ6aZ+j?a7i=6PA&Qh$hRiMSAHY{pR{xx_|$9)hmda>=+D}Rl$;L4rg-Q&WKTe!(-wP8{6E1(eVNfmY*uFWv^7r!KG~nG_%Ah=vmq}T` zrV!yshSW3Rk*KT(I-^p%(6!44hl^1)S9U7adlP;3k%{#b^gx`0u77WS6@~+hA6fn0 z^js5vs$D<=PRy?w`@sT9+ z;XmCL7PUiqy|go449X-xvlb%ea=4I&71i9F^)vJL@85cDp390qid2f@X*GW2h6n|r zIqy8lrY8_z!??Gge8Kk3j%(x*PR4x5aB!Se)zBJnm2Bdk!P#(oKtqGWfkyIN_iop^ z!yl`J5)(ko$BWfQQaB>KZeeG;tsWP^8wR_4ePcs31iC+4p9=XL7zi3x?cNM_jQGaE z_rjUlr}O!&p0EE&0)q2hqVkuh{dDlVP!-goH#af>1{9baRB??AIG+4-FWP>%mxw zM)k+z74T_R+3GlBDCGE@w&Yvg&-%W2pRDz#^LkJQ>H+9<&{K3m@p6&I+R92M78XlL zPJg~!2In`{mDAi~CM@AkK~`vl{J;$Z7tk$s(6C=kIOinBY?duF-7Bk!4d$sY>*~zN z4?RF&aTsm@Ec4gVmrSqbIk&Bw?ZFFRZCWYhp_RCqJD$<{@pO2;bAn%pCUXcWMh%HrxOSrhS)m>%BY8)) zxAO;U-R+KK@NY8&>pp!NM6c7-;(eQZmYK%q)s&JldwYGs#>(2KNC>|9*XkdRgqz)%wv6O$@&IGAhf z4#g$nb+1t_RK#buG8-=%A535{(8x!Nf(`!$s|Pah3AJ7HNoH|d`}$mnx246<(6Ez) z_!j(5Smy-{VhL-goWwlc)||k3fFx0l4G8vvDK7@ikk%3!<5p)+`wP z(Xjb;pZhN_NTOvJQd!kS3KF*%Fgt?KiPD*kk*3?%24qv%!`c+r0+4Yf6X<0Y%7cTS zo14r8NSDeA&h+;OTg&5_t->RsRMgi`LLjf$EU=z$fW9`nHzMLH*fm6b9b;XIcQ!L_ zecu<#O!HL%T?7DL!geMa?9OCA3O@-3IDvLt8pTKmr*cJhI{~>t@qfnnm z(a?gQSWIpwYXfmKF^(X;l=?%Z@$=^==;#seKOsg5=rbW8vbPzrQt@JEWRa8ILY%i_ass#DvJJ$$g2C(=19JYs#h` zABstgEGW*lwl@CWHj_Zp{qKwyD`anKjsP$q+v|e~;BLo%p%A;6EZ3vGxxIEx+KqOz zG%%=iJ2ep#6FdIs=y0&h{R?7FOGk&#YR2fiql}h=^m}b2 zI%?}N9XuelljPISVBv=fsB6hYFsKRKsUsF81ECM$GX$^#gDFN~8$hGwYs_(EHN4{-*wD_K$} z_F$ZX0}p#Q5WN7fWb-2 z$!fPGz#IvZq*TZ8bXt_CWV-b>4^7{oehxB3ro+i(j>Km6;(iS372hOc$Vp2r#|nOD zi=pG_mFx1(ya1WuPhb+hxx2j%!KO(DxMB?rYmi0OtcSmPMtZj{e5(K4{|9lyVvI2I z^(eB$-*B-JzX%4}19v`*mPEy>sJTzn0_fR-&mMDw+$J~$z$7J^7o*lY#zKBRuqQKEbt{kvK;&X$t2Npz%rb(i2?>3= zzNRE5Chjtgm&MT}0|iSdDJlEpzCQ8jiP!S4Cd&ymUll#Z_6rFqLb}C%#xI;D0Jlws zi~VASsZgotWQ>6#Sru&u_hAu*gG(ZPzA7y&IGRU^$2*%Zep{u2Rje0}xWhs4{pHfv z9|MqA9r2Nw%fG3=`j-YJ% zqq+TqQj}<^NN`fmsVKu&Q0n(u4(y)iD?U@l9W zxwc8rIszMjI0Eu3Zv!x5nW&wbOu^eXeO*Q z+uSj`p*#E!{35JxwGX0zdi&-X)LH3d_7VO!k);mD17T&YK{eZBrt>}fm6i4nD@-Kf z-+K|M%I#`)d$XP*m(fnhYoGUie#T8&`cgz!cLC(}XkTMvpN)31u#@+Iya`aEDoIz9 zpQUhEi~9jd;X>2tH`kG$pPoXU-0m!XtW9HGos7>0D{X+y(0H-Z>csq0;Dq#$J9&dz z@L(X)albc@Ab@3#|MbWemy|5GOBMxXpyR-1?|_@<=Rx)E*J?gqE!wXv3QU#VI9joh z2jS};E>C-mL%Sz#@54K%r(HjonoeJhusk|4-We}6H?*#G7|zqG_o}nih_SrpuC)*r z=}kRunaWj~^=F>|9~Cs*ZB3Ud0bI215qAPo2kH(*g!`eLMhcP zL zGaq5gi|$XA#d+TMpzhG>R=R91d;&m#S=YnOYsXC2)rqw6Gy*{9SzA+I?^s?9utL_v zV$`d3Q3BP&>z^`gMO-4fQ3n6z0topWfVwglkbo{)?5N1N0>J9#`RIv0c%#d}WDe^~ z==5p(q;2MbpO=T#T-B%D!#(v}HP?Eexh3FoDU!&Bg>J~CaM|{cY5161nsX_azB8YD zMn_i)07rAp_m|&#?aQSmUlUN*n~$^d@%cTRp8ma)C-H4eQo!y%zwhHs$RF-kTV3DO z6V#hJP)&i1j$$J@Hr@(LN+QwW@bdC*rvq0a;E8Z`iq8ypN%uu5$Uo@u0I~mG(2ebJ z`(wT`#zMUnpU0h9`;u56;J8{p;ufStv^jo$ocY;TqUnkB8v%qrUnv(nyq9zG_Rh}0 z#n|tDF@EsAOQCQ7l%tRn=88ConP_PhRC`It0SpCZk%S*4ty%#|rICk;CbjqZk zlY$#}dHd$!|CrGqYF$vlG!s)MiVix?GKuXz3S;4ZiUJ>TiG#%G2oKV!zK4fXsd6Jk z0R0ENmD=e_Em5u>^|`}#!cNEB+h5Q~cSXd!k3+z1nM5xA-HT^W?r%=fuj#?k36Liz ztm0rBQKs8Ez$ew{u4Q;%C18+_PjxDxiFTSS=;+smHlBluLNElN4BK1;n4W|YawjwuJcBzO0wy$k1) zp{p=0mm_pKTBIp;4eGLq3@O&mndpl*Xo_zo1}6*T0k>{ms3cz9@NXo^TrshSkBMOht8O-;d~ zxZ{1cgMIdz)$G?$5{v8JltPYp6rEO`d8=gwPeXuzcUb3rAWC@ zyYb{l0J5=7^iah8-gNbt??wh88WA5T^UASty=uRamynP!1VyrZvq-S{>gn!giWGoT z)w%@kwkdBv*kEQgONZoz%N4x;NEmK+iE3tU4uDT{fXZh6Rg+C8nZ0ZTZfO$}>$UrS zUPPsWH)3NYBgcACv-bWZ7>+QnJ)l-Jn4WA~iHOSUL4jMEthbyjvzc#V>UXPyJo*TO zZrd)jG=d>eZ91~Dx|%PWR#dVXj7b4D(N(4+ghg+aD6J>Ublly!&(Kj&Qd!L*6Qx?f zlg!4}R&F(4STfTUY>T{LP`CR#-T;H0)r}3+$`9QM40?n-E?@nb;<6j<>2+H^ZbNdh z?1cmc>Gj%Z`8QebL_%>Cu6=#s$hoAGPw4JxCzTM5Z3mVY78YC&7jmII_AA1O7@SYl zdAALi#rQ0r8}n4jvxF{7Yt17q1LNYlgX1qDAsVe_MZl(Lrw5n8 zBH=mqfWnB7*xj{jzQ>0T(V>px096HA1k&Bhbn6>ab<88O^L5+Z)GGbwf%PfKQGSG# zsC`g`0JX^+cg>54{g8{<`a__z0f}H)^k!#s{t8?4t6)M-PfswJf}xE)kdVf1jxz3H z{HkW>*XdDPsk^&-`63LM?%f_^E)oY=^EjK$S80$KpYBZ-3RMY#&=F`m>tKN}p`Md=(4ruNc{=vleSRTua`2P06eGA%~4h5<(3pR zqE}PpQo4h>GqFO*ZZm#07Yy%+1Ma_b(p}B(l~?Qqm3tnHFm)ecBA0wQ|Ix4i0jRV3$3fiCUphc(D;i zd3c|AhRKIV`JiICSlRr1R5L zbj8=X1B@}Bjp((g_Zoffy^9cexVaTC5}6D^Kz_E?9|N|tkj_W&i1OG8+$JOGfDa*) zSr2j;f|>Gf{`qCQBWItSbqJ#Lv$Hd>5tmcZex-GBFpvJ4^A{M+Cc|ARQLG+VDcCrE zy^$UD^6ar_C7$S?kuD5s8Ln>ZuzKF?t^d63<*B!> zvyKoe3sX`WrOdR}ZErCO{t!#8RytkdyjpZYbW?A$SPvqDfzpFamU5ndxS=muU?E>WSgo5| zf?c>5=`4mHrkTkWue=i3-B50Cv-q9|2iM?6rYuJp<_}#uTCIwnc^>d5bMG=((hTm< zhu7#&+Dvf+2%ULMFTmcxBJ7oPEIBthSdHM0=)j~t+%u2`OfSH!H6EBYj6crjej+Gs zl^XiVYuDuL;`O`Zoqdm)_Y>KU#fsgbjP~=KdpVoyu7~in$cd9>+v3BCJxeT%>$;(j zO%R4;ki|n>13O;r1*t~I+uGXNu&-aS z&U4UweC~_YKnwR8OiNu|Sj0F@Q1E%oE+Yp=zNZwM7E%XTf-~P9@ zPV&oFuN<~Db*HP0lV;5B%n<|82nKBHacNY)*6EwCrkcM4LoWxxJG2K7az}eme@{*- zP=23nJjN6$tTo=&mKLe0=X2V^% z^Jw`aIGOX6JQ%;O5%8N^ z)HWw>-D}$2R~PE$36b+g!|7c1ViUZsAfMcu0|LdY=ISym(nYV>%p%6~QD~iWX%6Z- zI8X54yeY6;L7H=+K!M~SGb3ZMKp|VTT(>kkTL?j`2$92jCKje79v&QA86SCQZfQB2 zBZ2uU;^y*juCY_a7g!V(K(s3K-zOom(sus_ScTo4jRtqLu!-K@d}FEOJVSSP*l50- zhD}LH31x=kys|~StpI)*J3G7bNvOusu#f=Y zZ1_u-0Lf5k#jw{b_M&M$`=VhP>;?m=Yq7C4W2|MZ!S<>EJvTD|0)i1+1nZKORm_Hi zfphGJB69lz3%OeDq+sBhM0j#p?l|%tI$C=nk2F+SDJl0Yga2BNMQL;aUepE9-m<<` zxv2&gHMBA4+K*-tQ8zhkD)%jA@o?BG^B%D2lTO}&t-{sGdiLG?+>FvC@Fuqh7z^Om zErOS7xhKD_q|%#dk-N0S(CWc5Tp<)E$<>30k<1$-a(P$N@kz)&-^|yRl0>Lx{#HG~ zWf%n&x}IS@)1jh9ku0f{y> zGCCgfT6z1O;zYIeY#m7Hte4rZ@9)dR=^k_lR5|ae7Og9WT^zRG(`!_bs@>%_9j9>E zHV7q4#ZikGPl4=Ko}|;kTvAgZzp>S;P4LaKFf-R#O=A$GT?bt7IBf~2m{~|D>D8FM zSj-?7(@5UU)5tv*6BUJwsg-JiT0xJ%V{HAiH5$@ITPO6+u^MSMd>`!C+q-0*IE;B8 z3f`v?iFVVcU#|VK`}?WXeiG!~N`S4*_-<3z=a$17+plKt+zA)TeJ7F#FZJRAR1y0}PDa2VvOK zykojjlymil+2OK$+jm&og|DRfvBUt{Nz8G)T8qNnTrQorTyHYYr&2jF4llE@QA7PB z=_CP^=|U@BOEYn?X|F(Iz2mcc5qQN8! z{Wv%{&bt%2!5c7#oyl^!(W?6TeCxdzB%*dfiY)yB<)WZ!Vwm04{PFn1z&@E|EF%j` zc03pnCU5+ZD%??0*RHXvFmUJ!a)D{NSnecwY10z~gwfvq{z_&Q`8!m z)bVAP9zrIB42b_=V7RPZQo+{b8_)I{Lu+-qH@W0Lc%Du$h&aF>z|JhvxE+^opB~4p zAMksE&{__Jt5ua}MBF{6{+CtGF2<56NlAg91F2F?Eq*n4r;+r^{(ct}7g;&o$d?M(PIpegjrTJ4`i@~~-Uqrjm%9t$N6%>a)*iA@?>V)Z^_?W! z5Q|Ub)(a4%+4V0OJd|LI5j(CsmI@7dUKtYiL*5Z&0=5TXJm?Jv_1<@HGj9|^+-4`% z6=-u%Xh$7qYW^SQ-ZHAnF5VXf5m5|8326aAx>_t&gF|^ZzRopJxQRp+)w=1Y9D`Gs(%xptFuA z5tODd7S@%(#ZFGXGG1h)fCzit5u6KFUY?$wyR&uf7e|y1sx$(E2|Uh`A_6H+|R*J&@XN6 zrixjuIV`<|GGk8IDUopT@B#@rjJK9lyC>{72h7@l_Yoz$)O6+@F=K&sCvX!uhWVLA zh&z_E;D=51uPzwuiqK9?IXyF#$+!21E!gU2E8EhjrOPy~Bs7qcz@@`PjzP}&K#t@n zutw~O=bYj1NBd8=@gF{*0 zuf0eDrxA;(ps%jGgb8pX;9LSSzXytLe*hH^y=H-1^Fjp{au?h^N@_b3cPcmdtol9n zY8K1ncGZd5bOE-vky_%^H(W3QnvZ&*QNq>=J*04_S7iX!{?OxC`!#lbNU$Zr=15*W z!d#WvNajh~`{{Ec&>*ARj#IYHN?)0y9^Kt@JPY7Not#+ewR%p*L5DjOo|qUC8!N)c zbwV)DIl$axlwa-~ubzq4>kOW|s<(8`v$AIx7IeK@#cX6`5%r^`2Cay8v9ddy zpRZ^}a~BdWDwjr!^MUVrgze-i`sI22JLi49A6sxmKK=RC4dzJVsD<*`%i#D0ry1w7 zt>Y@Rt;xZ`!7vUkWmV}|K_oJE#0W|zYW>W$iA>HHH1wG@SHh;XF2!{``1f+z{6lEw zIo+vsXoEE^0pbJZ}WK z9*(gSHeMrvlDC`#U*zllf_O;18gzhWB+e7T=Y9iBsN@Tj)g}DvMB?*;dS*MZ_bf!7 zZS(1h^2OeFy}|4mo;Fi;|FlgVK3VyZtYm0pWTlmyuNPvYc2MYDbUto5O1_yoKIL7Q ziI7cWcZoym%)e@PDm*-##+8^+e409{tGlf&x$xH!HyY8D)mU<^ub9|?11+80 z*vVWXtp@uwatycSQaRuEzAkxohcwcCIVP4Rdf1(3a*qRhj&_{e+2deq<9x(2YEQvS z(2~1q;w-hWS!!|&ez^*!0r6Q1IXcR*o)a4QMfNOTu2#phOh#yDnV9*Cgc>PjbM|t? zNL2{?mAftsie9-Op(S!FXQW8~R@Atky+h*FW1|aPWJQ6!W9U!5USLr|JDjPoer&N2Yx?Mzaj{EGkSc z-ER5!n>C%wOYE)NtY0?*GCO=uY*yYIRV^5QOi)?5b#=ao$LA((x(7Lz=JI$=$5hwl zXb3rl|I=a*k}RwZnpLA-g@0<0Ze+shes<)jqN0DP6v!+@f@>sdeCCmu5TB)#o>RDy zv|X%{X&@l5kQK;f2zkY8HXjQ}U+a&RhO>6Y3dL&F9f&HO<8|*T<^0<2bJIM}pF=}@ ze-!lXo3Ko$mSz)5x2&Yid`BQ-!G7@vuZtyimNq+rWCOeXiQKWVFR?OlD^HE3I|@tG z*Zt!}c*~`YCci2HBZ@D(MEWKsGwF%cWryA)#ob)bs$I4}IM<*YuWP^sg7jK3>gv!E z`y^mYa93|8JF`mscTSuX?~2{FO%tGz!(_XYAEXnpeT5uc2m$dh6zkZNG$Vhy@`FV5 z493JL>2(>&CC~i07rDZ9+*)IIa}g)k&*lUB(VtvX#Bs2(04dJU8xQ z)y%r7YF(Tk#Ae9~ZT1hqACkZJmbS_(RHPoQSjO!$i&E`5==`RBoi|ghTq%TJ#YAQh zNnH10WpL!A){&i@E;00~?`C?9STbm)6)ZPWh0WF3b6c;Qf1b`2?Bem=KFf{$G`-7r zztp1t$2C4^YIe=7lFBG(3L*47z823JBgCprY{rjr?MTlpKZ%Pvl32^9z5Ye?tv28> zHWg?J^H(1}*8ZXW5?NtlnxWh(%7}jEOZ+=_Hz7V$sc@>O-Z-I2Qh#NO+S5JC;mPw8 zz|Jo&sQtY2WFY zlNA_wI7#Uar%+0)?v+??CkWr!9w~rc`9~z_Y6zqjBATq`#K7Ct`ECKG!|Qqz%XZyJ znnu&rO~~gwp6~3leHkPpipO4UrQx!$G%i7Twb#x;!sK*0L+ZZ@Nyg!_+v%`K`T$ls zd?&6Pt_=(ui|fm-?Uzy@0n&ILytd3n9YhmqYLAsIQ6HkxnVU8CQt?Q*!h(rJ2;3ow zv&m9+RHgEtVoUaRB^6g?U-)&_O5exauh?-M6bX)J+0DmUjDDkJF}YY^KJ!NH03|q) z`7S13>x0(&8@Y4@O_Wg`#PTiAl*&K7N%Ajm zE_(ZhoJ_tvcU}YP-WxQOVOMkkmB3mw;!p6Fu96DRRTDa%!o^$8c%b+FI7F+*frvXo zn|x}cOlRU1-HtfD;CjSfOWI`-d2lk?N~~m+@i26++HkOk(9!~*O4;Rd#{E(&m_uHq z-M!B^0V2^WDkZ)`IG`?;_9Bz_%L|schGEi|s|c$&!Wwa^IYTB&pAd^)(cPpxa}wn_ zjCON>H;PNAcl)a04!2?h7Sui+3!5hL23vtkOFZHYK=)--Q{AgoZfKk=jb`w`M5XL| zSBszbk|84AtzF&iSef*wy+#o9tkP+*r!tSuKpa#4or$-gSXw1@cZ6O9YOx8(kw4yX zo%1bSHP;d+dQ>o@t=)nPwT4 zN>2_mirhla;Qe?smW0UnA54c4n+^d12l8WcKB?A91!aqdIR;^s;coCW!R!_w3WWY# zTqQc&2qYRUlzRGBlYjs>PF~SDE3~~U*H+OvmOAUlLps=t5p^HFjsXYwC{ zy8U_iLNm7UDB#ICyDToP$bJnWPWFz%dHu_M^QFpXGOsgOg#EoAr09}{<%kB2V;g2% zBL{9)h||qm3YlSJ+QckTFpQcmWUI*uhtK?&la3PC?U>QNJTNe(hbn4I<`llH-kOO@ZiECiMzYvYEqo~*C{QLT8xSN{TloW+0swty~xKY zg?u%rFhcLg+T&Rfn^RO8Jspw0UycX6m-`xGhw+~r9h>Z;4SQ-;yM5SI5YS~h#rA5E zZdV#N*n4;Hncxv}iGD7f+${ar{IzN^ZH%?;ogBe$ZKI<_N*4B`K|MrZ!Su~F-D`)W zkLQ7g;^c=J!71;ofsMICu>4~qKmVVjmNT}wE26^HhEL7ROen{K>G?1$j1GIX4r(R6 z7iKh@N43+>-W$kSMz(zmxvp4LJ1$%ml2%rx=;Dm~p6Dkns_)k(4Q^>TOD2<8L6`uO z#nJABdw}?h2Lsj!t!UGac<(bD2*M z$>z7nV(h-7FISeAW5iS}_o5B7M@g$^#bqT6(9-&qXe147IaL)yWXZ`G-F!K+s*PUN zy)s#X!xsvcE1&JPVgjX@tX`z8@WANsaEE1bE*S`!V|iGoDM2rJab;_;yPH9l97a#e zlduW%CNBD7TaCp-@bRQW#7o|UMcS6`wsb%@{lyN*>P$MTO+U)io!?7(yk5~Aan+z) zV7km%2I;p^DuoPj&`WQ)Vg&mUio0KV-}~s|k_t~9e41%cNwIlQ1Ycj*{#=0A_oO&< zuRcoKNA^x$>|xcD_u2R7uOH%=9ZCiCr^Iu5skp}?rtWiVCR7S1+cTaWkST&JQ2BXm zWP<&cC5YZRiC?F@Q!uLpwEUlLniW3hPoFk9yzH_PEm9a8`R)fDkX2>MWl}g?%3H8q z?C}Z>twQQMaWdEVxHnf?oZ=>-NJ*^ARQ6awj%z#q-M3ZhT>> zoip349$A7CbNGT{lP&ebHpgBDROYPCHc+C0TNrd!A){vTQ03yec95AJN|u<-Q_ERr zNKyTpRjR=Oy-)|@cW=5TI=-HK_=M89dU2BlBXi?W#s0K#QlYP}-&ZAFrBg1J&9{m= zJJNEjNv}~WWxK3VLeklZ^34!(qsod^JD@0$5IN9!o~F;SS_x6kk_K2ahm@c(c;v0RRDI%_3Q-qZ(27#2)8Y`yD)Em)j#l`tj z>uFAuMemQ!Mo`znxZ^ivuH>txf}5L~d#^UFKm(-Dbm-?y+V>;1l8-0`Z^R|1IZH!v zFcqV#s!G&K?Wu>;GV9CHuQQG2TKghyuc~b7F)-y7-X#}jMRaIZJ7pVx+^_DJNFEYG zl5-e+maAkjCS_onWj~U)u1{g7D2i(YIu_Wu6OeXKo9T4E2cYf!F{4ZK{d|TcZPc$H zq9@IqB_`rwI-z=_PYd(i#hUG7Q89t#i^(M1qKHu*dqPEZZEXdQwLI$Rmr^8hS2u*b zS8JqJQ7>k&hy&b9O1KHIr4ID-HPPseunFl}ZrZG@+~RVvx%jI1abA`-ZiJf51guxu zJ7*l85pdz58NbUA*LDMa-<+ep&R3-QffFp(J?WHz_RK{>GxgA^~<>j7w=4-50 zKOQAcy`}Aj+)*!FEJ6w%;a*xu9Ft_NF0GqRl7vtQzUh$Prpp%;)25&veSm><@9S4* zd&{&Q3|j)*ys*w=RdMw2z`7l%hjD!Ps|X&6O$#Rx5v^JD#6mlrm4-SKX~bpDeZ~Sc zHL4ZKo8tkd{*e)-(&xOpnm<1yRC@;XOH3VbhG&)vO-Kgc8hR^u6cfL9u)YvwPu8U$ zP9BP1SY4(Y7HsE^%h*aGA6`tiXzP`#qbaj{J?bDiU%hPN>&muYP~H&*$+OMtF?VS} zc_Tffje)A(ajH-QQAkFF4qBa@MdT_k+^2a~6Uq&7<}VlR3fEY{_6V~*ZsR0SsUBbg z2Y?_G%!y*vXk`P>tO?#L(Q{AjqZ0r|**=7%*aPW1-Whu@2PpSW*zWYJMC&2~`lHsF=7E6w^x`IJgyN{SG~Bsk>H8Ce?e114>DL z@6?zFA}A^R?LszrRwGcSWqtA6Mkwyin~$V|HGOSkKi10c!9<>TFsk9`F22m^3MADX zXu6dA26?RtKeOA6L(wt+D~R(b-fGIWWVZfbKd?__ML`wAzFfBM3S^MO<46Bb2X z8*w284JQ%K+!stAIzfCn-kZONY@%)p~h}5 zp!xJzC5O%OM^!1m2&;6LJ4pyDAK|d9dtJL^K- znXLbjzg{6w<#|Exb|vv~KZU)uqTZ#iyXSW(BJWdbN4Bb{)MRQxV!?~+lyob5vTG%m z%D52oBZF}iHlv7(3e-=AN;EyDq;qk;|2|d0Z;5=*nRYW~X*MBqTZs!w9OCukIPbCx zG)B6m8Xzle#`?2KU$=rD!OapG;rMX`5tuOTn|H=LV_)7YDZoM=;{1EPAiM;~xm%9w zqFqT(uGXVhr5nWq1s#7c(}zIu2lhuJ;1`r|S1gV^gXY5Q+HvF=2=89uR*^SU>KgNw zw2SWH;q!lPCyLA}g)y@5+!j&_vm$UMw`R%Rn(w}6XM|MyG=d9nNxHEooEPoghof$N z2=Dbl#tkYoC}gFh?%hAa7dI>yS>@V?H14m9kJ^80gl)l8Z#$ZFV9$n}+%eX(wc4MH zX6TajD{q)BwO`{-%qU;Bmqs%iLDS zFAdiHLD~@BK%x5R`41tyA#uB{ywknPS*oxj=&x7WXWdsUFFYFK27t1>DQE`2Q;xO(W47Fb>1j>ZoxqA?TO*(a(1m83XhTE zcLM?XM&iD^Lq^ye3>9xSHPC4}^U~#0^g8crEYnXy+CNioTP}B~I2B)E6P=>`o%AfS zXU0EdF)(shhe^5VUZQ+1EFyjrFolA4Ut(ZrRHz|sIPUwE`5`VYzMMIC1#S~Mrg&T? zD5RrQ&3Eg#RG$4q%8E7rH`A}1slM`$bbCjqUv?LILudB<3q-+JA|t4X24%ezb)Snu%Wc86ljyS}CWjpZno&@rsepzW)BF-0r@WplKb9&!yN|g8S#5dgM#KexA9N)J}BRaf(f`i>06N zumcmN=(an?N70Aw>ME0{+3I=Hmm*x>+jcj9#oR|%rr{+wzaa5QISL>JgGo3BB#&4P z7Q#mjcB99}g0|JP4r`lvxIUeop)PkoUNOg4?oK%~n9U57WMdKXS%3Fy8OqpA?q?f` z%nRC6i|1PSK7CQ(ak;l<-vR;FUT2&{65OHx!g*tmRHO@bW+Gl=`Ou6yJ z9=5k3WM$>|fY+YMhm`b^Apxg9K8mUcQVNoetu z#|lAeNg71n%QIX46w7DlTC7r66gRTxuqBtr!_J#UK?yzj1MN7NI*R|7In037?Mx7D zpt-JUGp*e&8Nkb`!;xKnV69fG@uUuQ*ea&0XuK6+Df8OK;<<++I;yuN!DP`sCr2D9%`EGAmTu$=J|TE=%Z+Bn!3|R7?z=s0FG% zg4F)?koNs9$L^YU6c>}{RF|(Ywif3$eybVp} z{6Vai3^W(_u8VjhN%lW9PjrO31>-V)YV(*G0uWB*&uEa^`5DkZ=lXuFMXSiaTm(=A z8ltE7V@&-&-~Kv<28lUFjzJ#ZE5=1^uPBuUwV4kOb5|4$Os?H5=kK3;*uKXp0WO>e z*TCAb=u7hiFy+8q+q9UiN!so8o&kO>N)GnM{W&3FdJ#xI!Pteg#f>`Zb=sdE;K@^zMpJ z3-zl_f|2kM-=FIpsy1oN=uNz>aeHhBP$E5GD6Qdc)Jj!TS(N}J18oKJlDNa#ELIa; zjuNn*3kh|J&J@#Su|*L;17$Uvnwz<9Md1l@)~sAvlc|u*hVAb^`sba`Z2JwdeqyL9 z%m-)aDmmY(_9oerCX?sfFWeHa8evYN2&h$+7H)mZ)XqslYJ|QwV5WXnii{wW#L22cW^td25YA!PG;8%fA*=H1{kWJ;z4eraRNXg} zD$%a%R)}<8k1=1pTFV}UC@U-1W&r-d1)xZSEjj*bIU%BCUbLi(pC8ZklkbZlpKj6-T?Ti)9i?0SFo6XgK9zSx~c^M!$=zfUG zAUq55h^-N$x!sS0+@h%E?}`1XwR6hpQj{w5uTkeWl=$lM?e3lIy5qh1|Kw$ZFL0Ah zLibV(KykA=00pFQw#R?e4fMjsI-%NGNVY!wgMu4kIMEA?e=DLk)&ljC_`LYROJtp1 z|IxQy8aFEme5XG-(}}Wt2k3=0Ze)z|Fd(i$3AL~2eCv}hfP(89vM#w?u~ zqsJ8u4BA9D>-YAe!hF}TKcN5H3n*VO(-js1<~kogTKXM51~Ul!yXn;LG8hfQ?f0_x z3k|tvG_yY_{xa{@eZ;2m913c$2aqS3KP3%hr_ z{H^SXki+lfBw}icd%ZR0@NHAHS2W{hhw$zA>cQpna?4IaZ)xNQ-Wn&hX?v6t8i_T= z7UJSmUilWCK}Z`cX;XG6ejobeiD% z_v-%(wCS(BJGM*0!c9WV=zHz*|3Ee^JAY~m?>pR`)tuRTgdU`Xemv!Hwgghx;b}^CK6KmaqGj6uJ2a6R165NKKb9@0xeV<;(8Rz4yaS$$9`y?2 zkuR8n{ZF{}UBw6#GT9hA`1BU`&=85(t!9(L<8$)!*>l`a8%jr5=B6)$XR9xN#zwNa zPmEQeC6*KM!ZR||>+=*Qv7Sl>1Y*=`om0+Ko{G+UfI7>PB(VZXr#+rV399>YZFy77 zIOM*$BY144SX59tRqR^lKKEf`uras9Uyy7au2JWjWU32@YSapSPD{TDD=Rs9(UP_~ zj*?1CmEKc#y76#E$G#%sv3pPPe5(AAKb+DAZn`^?S8?=eO_erfZ+>v~k~H8q1?MKQZluao@Pa@uum z$J+0aNh34Bzf=EcX=X1OX7LU~|X58j#+tJI9(26pY2C;efo!X*6! zNgs;H1Ji|F=i1iI%69r+z}US{j{BT*Z{o3w3ql>$SLrW}RBkPSC~0Ul2lPTv@P>0K z>+bND1<-LE28tNHymh(bSsp^Pq}pWJ2pTQ@rR2m7dKV|#h+MUb9@JoLIrzzqAD)BB*#yl zJ$2u>bgB<1D1KVgcuis9Xd4J0E785KLvpSV%g_c12>G8V!~-**p!(!rMW&Fk}H=kQT3EYVA2%A4xQmt}vMT;fB#`?6yW+6TeD7dsAav83Sizt#aGs-Npvs_#WC>`KOjM zAW`dJz$oy;EU0na?JwSM6nVDs{%Pqp2c+NOsBeZv&o(MA<3TvwSTgN7Yq}M-TDp7g zRJr3Y_j;Mg{H61CWN!zuJdo64yfWmJI0>rJLUD+BGO}%=^VH9(B?B78Ke2Zyq5;qSh752Eh6Xe`sk0Y03QWphvle8 zWf!#3Y~TH>20CS&$g20(ZnpS744~L{!!(OGAc+XHv9hI;z-8u=XX0ZnTv=W!GfP|R#&6fH+r+Ynv>QXkqes}fn1;tNmVtnw2lRf!NOHeYB4zsv!l^R@#Dr;MivuH&4fND#aBxT_wCZfGgFDh?QE0m(Jo%M~ zDMUB#-yHc2QzNOVUDqE% zaG`gjD_tg9#Pzx&!!d=%S%*@t#wxJQ0XS4swzhqNa?F3ggP1egckm#_^(S{m<0}mL z2+ar5t{uEy9FbjmB|+PFV%|PTCc>&`UY_|DhJhbNH74boJduIjdp2dbk+a4yeJ1yd zSAH+qcX>aZzAO0zD{l}K#v3&aQfM+8`Nbyu>|Cr9O?Yzrswk@3O5QWmVbmTH3WY;D zx?jXF6!JM}WNV$oudQ#OdaG%$^I#_ZY{LjiO5H%DG?6g~)qQJ`JScLTcioyfqgJ8I zVHt@!p%NSOgT2q$&Qj1@$c>^SlSDQsEE_&_wHm*i8^`*KUYm{L-M7$BC!s^joD`$Y z&Cs?kTI9tXqr>IF$PE}(ri_HYF74=B)~XpgTKRA>u>fsd7k#-O+5s#FLkjz2U?e+R z^eZVY$z<%TAX(qsFg0NB8+l=aY>NAB)=J<%V}ij{ej4nwPhy(m7E9LF9~LRI;l_)n zImX(amqlQaMtmaTaXoK3C4+vzeC%_pA=+z^xAYg8s4(!0EGjf;$akX>tqER`?H626 z`E~~hlCUEkAc^Ouu2V&MEc7NHg^DRVJKmYy7{6BVsQaP0{sN4^;Gxge)!q^O-73Vo z5jb@7yMIt2b8E5&DI(^cR}*rj-?Dfx{!p6k`2ZL`<=iQr4ad@H*082)EAM=C6GRde zL`u8*&LZJ$VUejqMG!$YNF`|ZW`~NGeTSPuHRoYilh;`J{b2wsz3xr*0IV~r=lv8;=!SvKsr zBZ~IC{+9Go_X6YD!7@;0K`nRVIQ-(L_E!}W(l|}W<(jj9tSUW!9-gKz{!zpZhhx-k z4p4rM;x>u_Z%Be@q0>5dho4m}uO8$Wo3KSMX&9(EK@RBd`+QSXSM9rbxbu2UV^({( zxQYJl<~^w?-Y8&i>2zv>{e<1*cvWM5a-zI;6QmWGX%)AAq)@D05%g2==A$%f{hfO^6WJb%i!<&?mlNc zP{rxfE?eNpHX5n#$ts zq0;ea_+yJ4n$MpP197J$oK&bg?}3SUm=V3%Y*sX#p%fNMN9$Bw_n$m)(4}N{Nky7`+eGz?BUlv1(5R-OCsQV?B%Z(~M)IfgI@i zI!-Z?v5pmcyO25|x4ogyWk}|lidufTCgxF4a9pi%{ZRpHHb;)it(CaAsn3X{X{7=* zDu(z)f7|&oO^u(8tIhS3yLZ&X^s8|@qg#w>`7`uuD-**8ejWw-7Z2|bDEDWH`KUyvkh;41xWHMp!+XMR6_M|vZta;Is~cS{ zMlSpZLf68?)1g|UYm|>i=wc}A;v;BZVovc$$?gDS07_O?$q#Rn3VpNqCB!a%njdRF zyz(Q_d%0%;7QB0s-onifo4$q4LVjO+q3$WCkPuRkhU++nXQbFn^F~_oH_w2vZ5V)k z7LM73;w$6a2578s!ndx3yj<6XQzM=lv#j2Skr`ws<7?j8Dohps8JeUpr<|2PW|Ea8 zzh){iqL-HVyLz5Ge2w50{l5YACh6~>Est4*XP%%HaF+M!4$%Xv@~!8_|KfBAEcgCF zJ`jxW|55dWPxL+fVMtPc?jg5|k$FssZAP*yBdvk>;VD(cg(n#|t=TB<% z81P(|ierHphv2J6%F6bG*zr8MiiP^dR%RSLAWrW7eI-n-U3W}vrR;RGMHz{;aF{yn z^kk~g%{wNB(vHvN=yPl0H6Wpz%|f;L`|dIuX#nqgF%}AP(#ls4KQ+(dT_fGIFwbcX z#9dHp^p5KQQHjQEpkbuWV%EmQY_Re(4kdO6X^-XvQYn`;SoB?ReoZ^E|OhRcM* z_S@$Vg9)bIw_B`t9D}C2Ox)5^I4j9H*7no#C-IAfx-Z^^&@XRnGpO~S9&iFmqMn2%tJYUx{LMkQ~&1% zR>3eBR9K{0#>eNflrwMGND625eAZ38?&CbVdq9$ib^m79JdmbHMl-!-SkoKfHlO8k zJNhNL841jmr}sm6dL!d}Jbou9sE-1A{?plg_Z}E};@((|;c~-WSP`eQXDq>g2$$8_ zb6k$j##!4_MmO0kosTcJZ`pF*6yZc>iZZ;Hex2kP# zAAwidV;1|~FQ;-YLf7qobii=)d?g$ib#;kw%F4|{24K}B>&2kG;AEM=JbjN zKo60rbpgy*&c5BxbFBioiok)Fon>nTieykkjO6s_{@0F^@b9b3R^4mG&Ny zgGrF!5+39AHS>b71z}FzFUYs*^LEc!$TfK|;n~%26$qoORLZ^>4Pdm>OrUsVTU8pA za6qLDYtm+JIa!<92w%m#ua$bi;f}AqMjUVY*MhN2AXb5Y-~y`A|m523xlNF8Zi^S1RGqm zt2d@>8D@RB1kUt6iTcByR`7-oQ;$W25JfW4cH{B&Dr9T}VeYN@KFHj3U@tof2gX2} z_yh!#DVqN8ubr6M4KmlgZM!M>uqibt-n|QNV7R<@B!Hi#ut3DAko$Q9GIIQd!o-%K zcq})EMnIr3H}?~YiHB9T36ipAf=eYQIbBc$I0{PT(l=p4e!+b9`y~)|vQW z3Jo86<+3~_D_-~CWUc}?N6OTXA7_1hhSL}4ieqa#_-pSWoyr5(CrV>29fkZLsZV_* z|L3~)@2RWtLuEVD;pClwfPhh}>u7NnLfVv1vq6Ch#t}QxF=1KtM}m(Wfnh8bR2B$>zvgMn>Od&BY75Abc)iW--jsYZSiWn5R#k z%v_>;n$8>6B;?y)wuIv0;0)*4YHN$}I^@nnFo!&Tzm5g=CsIw#&Dn`qiq;m7C$^?{ zL&zC#ddG((uScye96%Xkc|lbfNud?abrr4knnxl`LP~0;*38|pifKv*6z>V~~z!yGqZVsqT;XyH{LVIYV%>u70u_fCh(9xgm ziy!3VEQYJC1$1>6BNNmeHZ-eMLZ~9BR!rhcOe;02x27|_?gHQd z^fb-^HTXw5F91n5C!9r#*ff>%#^2d)e5rK{eG4#aArWDarCsvjc3#1283b4MpD)E6 z0|@;T%)x-|I12pL>7%IH9LEVYEiM48DvaIn&ha+93=eC)Va?mDTFHC61T zbH2b~)Z@r%K0nfu8w`hwmGx}H-FJ5^fhRpJ*HO-7IRWwwaG88s^t^z!+y*al{22b|DsGV(k|f zg@^GWA@9>d9cdM&p*LBp+ss%tE&>8>f`ShaW=H$Ou-EdjFzw*ZCkw}omkuQbSVut*OTKp2&o zavITzSM)19Oge?1hzK5M2rpfT!F22DMh5YQX8j}0zShXK+acx)?PGDgsB?fvmL%T; zaO_@g%DpQ^*(p}b9&mTSHaF^-eMg}L+kamwfgk?QmPdVtvnu-LBw+t%$1!+#f2wbU z>mfow_g{n*;S6W)`9FzS|EKG?|M9{7*M;GK-Qh2)+Z~(yB@OqXGn1_oPB`pVs^Px-C7We>x_aYfW#H|3O33m4`Xq*inPE>)!{x3L zgUw^=H3IeV$@Jway_PgCACqACyyMM_e}1PO!-hmAmB?YGt2>qDxF|??o4{?GV%u7( zahtgoZIC_UJX?(g82TO|XUAeV>Yh3@Thj7>GL*^UnSZu!lhS`|Z-Wt)5=m zNH-oD-juSsIu|La-r$HP2m>1#9o-zNW&L}Q2*=6ya)y9QBJNN&6bcL<)_j?D^%m7wtrV(N&;^madJ-lSZ0$uwA@~Qa>1~;re66?rd3Hs> zZph-?fj#hWHem;k&8n=l@RPNTN}V;{e>%RgwANkxaVV!^45C#JYNwqfHB1J97 z>mLI*q>3_prB7*fEP0LU3#)k1;0;%6zVuJuB}+SO?AooXsi?dg_9VzwO7%e_F$A9*gg zeu487$P_O(1ZEkjv%T82k-K8|yuJd8UTpD3LonOxJ4UV_=K#xcMfbaX!m~I3uo?)uUZ4-8$&yzyxv3Xd^(Nl ziFz0ADl|L;8_y#gF^cls(gtF0> zGx9m#gu1C?Fc^hKCs4kyzRu01SwHQ`-NeuOk!AzNMIa28p#UZy&iflrM^~1!%l?u< z5QfrN4JJNUBrbe2%*=0P89t74Ky$)R;@j*64-OZXQc6-s1l5i;pSiiYLVnOD`1Q^O zcUMN(?lxDQuly<)Bpo*T)M|~gR{}vD4oc!Sd#xI}$z~o`^~tenqFe7b?#vUE-~!C6N+P^>{YSmN2M7BGg0PO3 z$uc+Kttl!d7U=Ikc~(b|k}_YSk*x?<06vJn=}9QbBoFdo?vtR>x^VfnQ+}0J8R1j- z91tX(?#@*7iGbu{cA)Eod=3$m?sc1NzF>#>Hb?O`TdbRbNG#GWtsU11sR}SD;0e|Hj__z_wLP5Q`47| zqeqgsBWZ|~3sMOcdp$Lm;PIF^+~qrUA?&#^JHI@=5dml*7LV14K6rmX$pF`Drgkwc zH+LGmIAH2HS!y{_1sW{~9@;|s=J#qXKn1IX|H^zNwt`85;7;(!cVSt?mt`~&2pWiq zLj-6}fzQUv)@Qqu+0;-~`ImY-2{Pn#bTfT@{G5JaXJ_{b3S7W#bz}Y0ft!sjM7ZKg zLb~cLy*|3^=5oK#%n}L#xH^l)Tu1GTnDFe>w+70**BuPZ-L6$1=70Th!2I)cw)xL8 zBgn5ok0x_c%-{>c;!i0WjvW_Q`97}LY@B22?HMH}JO?&*w67~RF#mi4!G*nUp13a& zJHO6tbvDP7TG7=YG4+)T7{l|`Q9;A3?Ir$QmhxUMCD(nmHa9M#nmlSq9mM7}3uug$ zFQ)!eylt;65u-cm7D$sYq1re4I;Q+~U^xD>#V!G=Q@AFeN%f2x!UZol6!uB}d7xRkq%k}yG{hMdUFxae)fbNGVa)8M=tz}@l9@v2e+~ldF4@ElhMduUf#0sLgUaG7d>3}h87wr%A*~P4*2l2)Ni6OXZ*(%XySDnw@!UCWY78Sr4 zYZfTK6|0Sjcjgl=gSR^)fLWLxAGOnE-fXRQb|vX0y730E!v)&qkbXu$TmejrP`4An z?g2P5Akfm#H~f((V@PeH)XE`v^m^T~z4vlWI)r~M$sTo^4YM;*t&CC9=W)@}S}dMi z0|t@}nu(slx4l(}9YKkO>P&ac?P&c6m#!1a=sUxUbKYx>ed zR~Yq?H=j)f+1rfjFUL}~w_b01$EA~n3K{@wMMoQLJ4?0Bd?a{!{qM!BL$r8cb9D5X zmbMG&>(|GV6Wp#hS#ro#0EP3bCG*F2T#!KPl#Ba+As}7NDX?hO+08oN@&iZ@%=@fV zGB}T`-7a~DsScMrl{1r%+dO$FdfHDb>`qgvS}DnOno%d8ZI4E@04oA-mx+m)vYqCp zmMD648{=C`A}>Lp=p=Z7#RyOukbQ7~@~T&@oScLz)(QB&j-^^pA00iRdRXUnT0hm5 zZsrp?wLf{VxVoz9CUDfpx3>t}zJwpC75}mTo&x0|K>5{hx~x8dJh!pXSNxGyd=W^3 zGsHI6H%hIB%XKRTQa++Pqb0oJs-_Ra$i~hYdrpXMU>@#1G^bSz0G6VSb9B`E%2qSf znyGDlZqu;8#H@4p;r9A5on}#UuI3?di=a09JGA3I!_;Zcnuu~fIzqPNK6V8f#m^Cb zs%S~vy{Nyl*>~0eY}Wjh5|CKbsvLoUO@R*fs&peC4(+6+aC?E9>^H&iDRn-a=>Hr@pM9-Cy#?a+yByLGSUT?g-0r0FO-Ig&n@xlTT{Mu zV~~_ZEL|LXh2o&oTGWrF*QlkQmcxsh?%82(nlhZGt=HD;O5&V zUc_x)4Z-K%*p3xl4OQH4m$Y;bLzi@Sx1xxEGy@EcNH+`( z10o@fba!`m?2G&U-Ot|d@$UC{;&}J|>zRM_U}n~=wPww=uIu|f&(9g{P~D0nejF>n zaC&&g06Nc=X4)fz&8I&NXS!rf-lsA@GnNk1Ln>s_4)h77kY@qkx^{r-ah!S3r2Fsn zz9AU4Pe*HS6#NPQ;Ly-g3Le(yy}iKb(G>;q12E!(aSJrw7!!F46@@nd8lb<&?-fli z@e&uwaD!H;y~TZF@xtp%Nde{G|7Jrxr(T&;xC>6 ziOl9|`vG2O?A&>DC4=+sD4}QjUN2DKfiPFv9hDMhHQ@7w6gqVP-hz35Y779<0e;zF zceC+mKXg}C@(KBKufJ`(OBaeT7=6333|^Lf|6w(1JHSw7f0GRyyoga)dp3V6m%~g) zr!i-h$33q$cIwWG14=)P(7vGBaaBq6=C;0KKhBszdtgNdu#Iz+n#_NtVQUvhJeTtwbaePSD!Ymd7TzznCS@f8^xchP^XVB+uc-EtEr%K03e9ePtaSW&nlwa!-6WL3yNAzWyF!u&5z#t`1A>-R z9=M+#?(UV@Y{hq0{yh_U;kW8$|CIHA8ci3!&=+>}ux1R>`0f^XdBOz{ivw(|r>Nj= zrbO~ji+6<~v4@_`CpqYTdvBTKJ9kw|{%0N~(AZ@gMn;8}E`|hhyv3|*cd*Fui3Uh= zufJxl%KAzycUaOExp3@mQtw>)L$wX1^v@%0nFj)<@%+(zV261Im-N(>g1sVvB-Z=f z@<%HY$(MtIMYnmCK&V1=cQz$H_)~q_M}doDqJiM6M%z4(K9m?ma^FqS=UM?Cn~dhC>L?#XJMq(|5E2{hd2{?U)D?4LzDh^&$3 z9LKRcLpk->7Tizbc7(SD9^6i8g&u)&@&7{f&Uv*S zUyk2E{E-j`@Rz(CWzP$* zIZA-ayVyBQ0t)R~7gGjf0h9~rHs)D*q3?SmbP?o&c79x3q!{W!#=Ae$z&C}16Q!M) z2T~HNAuaoZjz=}!OPkW3B>YF`-L*k@oA})cNXwa@1E%%Qq9VUwuP+Rzg}7O%)d3hg zImt7RwGL;G(E^zZ0Qdi`a0n2fpq>3KBqUD}xrvZ648o6?Dur^ReH13Y(cC|YGVR5F zcxfDIPb~nVS~TI%v*BQ3Vlp+(K@&=9WA+}TBi6rfw;;&My?8_t z_${aqbW}TJzicLa#w&SNib=7SC%;4Ov zfL>q*2<6f2O;?&-o{n|O@jY@f8C31U`rc4{7^nQ3 zF5Tph1?bX_b9LsPC!TIPHPmc>Kq83MREcZ*C1LVS^@yE45x+ig%ztr0^JjbUEU;BR zUZn=Q7e!WkGle)$ZSy5y(p4FaA}X3H4p}xG8Fs#KwU(Ea)JA%s;Sh|9fohxk?rM9C zuj=M>1rsf;+te59!I@v)TBIZEY+2t9E^P%fW{P*e3brbwf8B6i-u=w-i&_>gN|->r z60Byc#+<}udfx1P5oQ!*#N}VThj|xcYqBP^zo>MN}sK@X#{=f z+y!Tecit3ys^;ZL`WCV;bD~kMpS9Cj2?SqoR@bGug=9LqoCz0C*`!K~>(UV0 z%gbs`;h*|iE@bhXzDK#fF4NUFpTQvAxbpz89Vbb{kS>Pa{GfIJ1zMq&mzh;iK-Gae zb>t3U0^`}jNd?4eO1%bR!HEJDvAL!8d-tITP%m=#61g*i)Ja$du^|VR4S}JzSp-+#k*3+WA3D zn}~YzA+>VnGW)l=QFKFU2nTx0c;OK4@gg;gn-IWm%Q&(PP@s7NYV&;S>y9Vbgnbho z{eINK{>C=bpGDGy8dv=lG5PD(y`yrgK<5Qi)N_|N74u9uiaMtUZvfB~?ZSmwxrWl; zsPN8fy+_ZmKEDdUE~b57Xz&)%^>4jhYt71U33I@xiRd#c1Zbj==l#7aKVPkFXy!C_ zbKYp3=L{qh+$NH2s*5Qo6oK+A`!b-=IVhA{4gYR02?D0EjxNNj7nJPZP(O@+H=G9r ze>NYZhW2z!0pBB=>-~_zq1>JO@*Jo3@3N3Ul`NKwOj503NK&{@#~6$d&|s=dGjN{aWOZvw=2QXPJMJ{7boE09 z;?k-BW_frBW|d#?5c^?Ovn0^dwwT&Zt5g&<(y#>N9s`7a6r6U65!7va+;kVoAn!v% zLZWO^?Jz)sl??2){`=J4@;^gQ$;S(dX<+`MqQ5{9xR7da{(J%-0X%o#A9b{|%lk}= z;OhLQ2jCW<*y-WNJn*JhEl#(GNP~2lz>S4PMGb0e2ik%DP9+wy^QrCv{-s5@BY}iO zn~T|qfnr0ltOKD%Jb5AE(#lK!2k4jq5F=x~4>68qt=Ojlk5m}YF-_5Rq{p=}>#-OZ zg2Vgl#x)vIgskO=tJc>S2ZmVe?eiBe=H;qOso+0Uy$++*oMZvztRyC;Z%6b!-h~5L zL73d|`2E`@euk?JG5()aW1vj9w%mqdx!oiklDsu&GVXn~jTs8@K{{;H`uBqLnssNb zMf1&%Th&$yGydq{l2MtjM=>zd)dhqQYT6h+XY1C5rfBrU zkBxf@ZMIee?yLiihgpxO%f>s6llFm?A)RKL?bha23=Hod+VpIx)z#+eZg*pYJ_%ry zP4+dp?{B(a)f7&OdelR|nxO1*JU7{KW#i&lKKc1aKo~3u5WS%_7yoahF}SvN6PhUc z)>-T#chr7Mt0Pil;zJrpV7dv2^=G)avJ=+wp|G5wgy=*oGczH=NC&WVJ`ZZ(GAgap zIiaGY-2A<#9GwkN`P`n{2G%3%vUMe9yUPXSt~M4|9_64m*_g!Ubu$-LVdGu3|5{=0 zp`rz&k(S*`G8%56xq#;}x&20ASX1&O1IdQUxO+s)Y;(Kv|x$!Y{S=b{;F zz4h#|coRf{g4(`uUT?aRn>c5`Tv7$CwVW&_a~(k_1Mmjt71MB#owPlPpe@r#u<4#~sdc`X zjt)$(W=V*TkAue}w)^tTH<--L*9>od^9odhDF97xV$lF-3X5rJB{VF{Cb2rAc5i){ zTc~k1*F$P+Sg_e|eg&TLcq}RxtilXwJhgg~=#Z@c2RQfm>EZStxQG06epv|`z2IYh zqVmm6$D2Qq=xo&y4@n12y9IBwY8*(N!O{(f5N`e12R=|Gsup{$Hd`V6q|Es#Nuw+Fpv!6*XtmXniHVKIL+lwlmn zBPA_84Dz3{%VbqTX&{_8Sd@aF&OV)6Ea{|_|7|Gj?mzgC9- zeaN@x|34_^1~2^YZ~3qD_1~AxU#Hv0L`?;n8iw_v`9KP!2`!w~}h-l#@1yVLPu z;MV1UME;0oujYGU>}-nu9@W?VHOt;FAgUZhINjDO^oaeK!RxsqlPSKx>CDg+cIjI} zvketZJ*vG1S%W}(cW?B8x<1Qs1B z&JxpEhSgy14-wNxyAky@Im##K%)BVbO;LotM3k|QTk zPC>g~fJKV(8R7cIU&}ZPMHH}mrxwqml%GXLqK}oP7g?2&pvH|GLoV?oA;pv!GS@g^ z!SwBCM@LTk=C|aKQ<2Cb&A*Q6wJ2qfoFtIy6G)Pty`Gh6YFsH5F)={<{C@_5L1;Sg-AnobNJ-3{;ujmx>HJZK zC$v?=MykDWpDE8J&V%DNmVG;~8P2*XDR?|rIFQZY6d6g9x>NC#N}u2T(Y1*mxudc@ zBYVyML)NPvY>}3F)@P|ITt#&oCjXPiN2YRUnS7VD>?adfwB8i{&5b-8EL5d!|J>w*gw*La1v+Bb#0f#Ghc9deq*JigO<( zwv#_k;#Y}j7chQb$c)Sb`@_w1qF}10BYJ#sIw0yHP3sC}cL4WGGm<5m`|Vzp{RG*H zFZAxI!hPWL!SAJ<9RtkUsb;%KFrmIdzaHuhfgRa1YDm-Q@x<ZyBAkQg9DQpd5fh*`-h!Icit$+eWcR4)bHadV~)D;!SlAw zOG@9}GB5HmA(>xT{@Mh3*s9~|B75H6#x{K~_(l5-=a}v$In#)GF@u9xd=VbA?;;N`Ohx{g`|d5?NLk| z2-Q7sQ`Ub$Zf+;kSYtGFOQ#Tm`C9OPcG#hF?9z5iLVJ0*&FgCk2Y-`@s$mAQ&zVqs?n zmG$x}{FFenR9V8xHaN0GmJ9c3>20N?EP31YGTVXqdMPs;XV9MOn(B(oVxXqCq|vLV zXFOCMTueeDFI;Ew!5(HtFdaKQi-aUM>@n;9NOeZV8KQ_G3V7Fidgl9DE%%=Bdkfi& z_fjgSc^L2E?&#*)hf5Ac2)xc@zB;LXd;346ZzS_9RKO1`o_=J<0sNavxHwQGN$GJx z(cINF+S&x|j<_2jAtBZlLvQgbOV63Ln6s1b=<&zlCkcKERu8Wg=9ER!ViaW<4*sMM z-d}LKc-*%>6#$O@_fJ;_a1N+_2<&9N49-}^hHgZDWN)sJccr|^U;ZG1p(ieOUax`hf)5^twE!UHVC;+AhrCKd%i*;MaXF^~s@bKWhFo_OH!GCXI5&!)fj&K{R z%(4=hvBu!0qnokS>>u=k=a`#w&-u3}9sMFl>lS!`O`GDW@_MD0=dLE)J$M9pbU+~a zsF9P4Ek|ddS}s^zvxz*Vq&Kla#P_u(hvkbY$NhXN!+?`AkmiQ`AbXxM$v2pZeT6Sb z+pP|;*^jrgwkCfjznu$eM3tgKt9*xV&+^;33yEYte@tj?VC1x4Ra@aQJi%`F+l-BE zU`b}V-N~1+_IOhdi1b77SXLxn1@a137^duL>sHaEB8y-_EIvBS!qOQ;>?55}JtygA2Mn+cFM4DVw(306f^pxkW zQ}6YHNI|}wlgFHL+hb!3Nm=PkHS6e^@OCDl7My2+@5tKtZKpgbaeLK$DqXreV2pHZ zRw4%dKVM~$3-}p(+U?lEPfO@nj z8g^I#us?8>$lxuj?#EZ=hI+&>-wbld_7ud!PnNhK_tD`3mkEyN@u6YR)YiA*CN;lC zi5!3WjW@8K6 zjzC(TQNDiZ&^G-_xfNT;gnDi2K`X&Rc*4;~Pr)dTKVb*N{Ns z0>BKc#_WqB{-x2#Y}1AF!oy#c_8`@&YY-p@@D>1aW&Jwcbb$I{cgoD}IU~6T;{eU0 zEZo_(CAp|Lwx!2d8O(YY))UUFz4oGAvLSzUuIOD|EnD_ir$5n9q&>ymH9BWV=qo2a z0dRIM_pTS9dOdMMrlh$rzKaI=u3O_FgD#~>O%;Tvi=0)s9;-b`nXI``G|}uZ5fGrT z-}#C23)6`~6%p>+D1p_F`yl5<8&|4xS5wpFURmrT7{f0Aj-Z!nImCS~7PjHw4Nsif zZp-CSDb(up7XX6Doixgwd3C9pk6l4&q0OIv*hbjo~;CB*0ccLvwdfak#7bMTTqT4NK46ip9rLCER076|0xBrYdH=wu!l%g>l9^K z=X^-Sv(94FDG-zrT?7SctG8~Kbzfxg&eEXYKvauFc`n~lEUt;Asw1ey_?}Fs)TA_c zX*I|@GX=sJb?PMN{A{n9uX0u`%u;)iWX3oid+SMMqEw*GKb|hkp}?3Ho}1c_23f0e zU*Js|55g(G>`#5OquDK-nNJDrxEWgaFe?ja7cNIhIFZ7mGyynE+L zGi0h%2}Z_pCQgx*VWnsqLMKSgS)mPwfRqPN$BIf3 zwJ6iynEnbXeM8svlUDh!dv1q)=^B@=@w|7weqqVnT>67T{>-~Jmsu}1tkh%Z)JByW z)U9zk>hHs;%4PS_FP2J2ch2743;SxN*zkz)v-bsmWMt&wk;+xlc=6f{XgpeJH~7_n zoUz&yvdJQaFwTN_Ik>tk^G&l{B|2hX zNp)^UoI*k4EFgM>+>cmK`Gw&!GH~VeJ5ACdnKH^qQrR#aC>Mcz%i22MD0E<1lZ@Z~ zdM;`OaitB?Rx+_If#nNgeh!Q_h>7|3GBt1~Db&~+nBs@YWxH0oT;jU{Q1uZz3x0zJ zXt)U2Ep|okeOjx})94n~$36fUEHgJFV^6-dU5owZS`)Wy?l zK5rH#fscGa3Dm-tcQPKfJ6sDfsJIzL!vm!f@Ug2-R-556fQ>#?b@f49pturb6t?ek zXswCCm^5TP5FNUi>_lh~2eN+5t9PpIo%*gv&^A2{ik zD@))`0*%a%(|MnDg0Q0?HpTSxXI3ThzANvp>$5w`^-2_4`Ys~WI^HgY_52VdP;ZRV z6=i2X*E~()W6v7xMV9;mbj~+if~(ie1!~rO$GdNRbLw=GZ^nP0evya+H-Tb+`44hC z9VNVJoTXd%!W74mEYJvS8YYpSNI*dSIHqW4?Dc59&qZ<#-F+=h+|)4kt!-ZWR?Ftp zm{1&9bTLDZ(U- zjEjnzTGhu2(MCZ*u?JFSMFoM9ycw z+)+*pWhpe$n+tFAcve?%twXzWE3~O&<%V2Yy0HACUFXu=JP-wXlgGZ0Oe3{<* za06&Qr8C)ketOq-!Otzeu}8&zQ-ZC=iYnL{;5&Sf5-f{+iA5>q7R_5XBmY zjL-RF;0Ee_AcFqE%>q<*<6rAHy(LU~%nw?Ha#^K>gTKFmd7TQds{w^68;o|;u7%?E z#wtin9m-jJmX!@ypxM8K^uh$IPUaR?o<^|17=jKct(SGGeNGT7OQyXu`7@;}AZvlO zOxU=8_iJ{$A%+|gfB2o@5WbTfnxTMruAGH=^+0?m2wCXgg2{aif{MYExhOz*dMuZ4hgpCz(s zU&)LkEJWuEPNr*LzDND?pTVTJ(t6D9g6uJUm=YSjFe#6Hq0}!;$IQ_0-c*Q@Pt&9w zbgbzr$E+DG&CM%bVGj)!o(U{OtDS2nHaMkQ2Y&&>Svuv-@)jnt;c_LzPbY`Ca@!F* zdsLn|Q5RWCz_4{#%^>_U?G?sR9J@(s8ge?cUZPA_%!-6+1rYb-lHLrqw%*P?^&I%Y z>a|lFU9)vnNz}#WCSdsUA;M`-WBbb&ED0**Yn6Jd1_u-Y-?j75dNQagDTnzs=1nRS zsTQO+!IcbQ1{rA`k909}wwl;%*>FXi(oe*KX=u=N!iUCLz~324%zf*%+1Y&IraPwg zr0pD}!VMNFe>(2y6M&h7tb>RtB^eufMxqf$qXcKwbs$O|uQ0Q+5$F4~UuijXI-GsC2#4Sgr8Y_@EqNRcbljlKyeE z*=~z(x6M>39F~DTWX=%HurZvIlr9QGz4GXXJz+n_c zBA~-{dkUaBSEtH?%gRJIRJ#*N@)F;AhuR7nu7BRv;bYX`PN23wTX$Y}-0$MS+6~6< z+8i!ls2fu@r^#433uZk~1~zV8{+j2@T(4Df?>Z}Lnt-43Zu!=fYqsak&%?6!a}FMH z5y{&Z^D0J0hy7xXUESTog)_4JJJYod#uH4H^46yE33k&P4uG6U#wQLaq9_OL5M zZ=FsLUlkKC_SDfEAir2PiW;iPi#q2$#Ub1|O5Go^RH3hOv^uHi=#~uahP64el|%OF z{R=(HwaFwa$jos$z7khp{df+@|o5?AWv&Rk-Q^7j(8YiU-Hsp?qpkVF3dN^rpRi!<$*A5{SyT1 zJ1nfup(Og5qciBobd;{`$Ia$ z%*sUFvOQxsCMF~8DnQ4+;G6A2mAoQ>?0JM|{)p}rVWXNN_)vImr6tV)T{Fjks?9-Q z&s(L`O@ACcb-rcai%cLr`dtbxJ&em%`y?qv(0?l*eO0@qA{8$r%RPM@Dw5Sid2wfb z^Uj+N1;+?M0SceyI4OL5bl%$XtNlMdOQNafkFmw1t*y6Ok91^WXz6`i+1SkgL^Hzh zY-!Q7wD7-v3u02r|LX701DlJPY(zxx+~=QO1I8Kf+dbP zT-QUyU|5BOR_1^?O#FIh`_rWj4gJZ$3@cGZK9r+Do3LfXlU6yGdqkKAJ`L=5>cMxG zLx=~#6j=RJ4afHB+d_3@{>ObsN)l(8sX({Zck?o~Gv}vnZtag`dFsDj`9B!P@WLg( zul>s&&G1!p`61GWL4abe0mrl_siC>q^P2&!mv~!qTzp({UAkL4xy|05;k^*J%l3XR z2D*1NxzY0AeGCkYte!;A(^aVpmx5I`1vJQwh9kj&_2)aNCu5mm8r7Q%PjaETl1lId z#Vt(@f^B+@Qtqwr2aoQ2Y{Lo z4wavuYzga~Pt`cZvH9jSDcK9hiZGw-%Jegryx|JzV&Wf*W&TAP;J)8Qg@$I2&dp1G zT##~eCDB`j0hT8Kg{jS@$CarKk_7gZ496#s9={&>EM7*GL`PwlG1x+TrW|KaH!8_# zDF-rNW$^9&tmG+Dc{dRQrQn{mj~CSK?dqbW;^3g?t@u1x?gA#nfb!VHny~~XM?{j+ zVmB_;L<{nzrk=H{~4`#9gN#m3juNpZAKz@$^J zelJRJR+X%Ur^8`Vc!xE*yUvY*l4?)kkH{NVNH~;kr z+)}G5WDKeB*qu7ql;?HTY)O5A#sG#qV=)KfobI61v`o#dWLc^L^DpykoX z{?W=Z%ae~^ce4Sbg?O3ENNkTNUPG2(lKF@$%hk(f1Gtt1IJO3(<^O7e?Z|xJ0+bR`DxOXC|$hDktA@F2|MW zSJxCM@p{f;KnoaMRl@sx)Kaa9np>~Os<_b5mgnhJL<0H z{%rLt{H63rJ(_(Rdng5w-3$eHMP>t|M*=w*m5LS z-@rh-#wpN-A9HKW({42US~aq)i0h`T)PZX6fh^F!3HpP)L*_8Rinfo9_PXA8Ms?gv zxqoiBcj-Rd^P{mbEV?F#JKrv5HOwpX9+xPnsh_HLL^BN`?9t%Klj1+pK5`RM)6gid zz2u-$p=6@8_#++>R01FY%u)@qbw>sf;n5^dp34&NMc=JL(>71&)^IS_9&b#)_tQT} z8(jJvf<8vR@B;^9?OJoU8b2Y6^tPv4{M#Qe%h`&nr)<1Xr2WC ze&7Qs3D~ z<}R1~K|ykRZ>Bo!sur*G%4thG_YH{H?9|JQo3__UBB@0UO{r7N5rJo7w@AF|r``jy z)7M;BGzf>O3g9ER%W@xZNe>KEk~FL0MIF5uzWU;fJA)=R*5&x%qpkQ9{xa4+Tm2Cz zW+LAE-=R=(txm=zF{=o8yxAiV%*(9I>Ny7~BPg^x{-NZRBw!yWtDyOK?UnM+LfoiC z%kD7cv6YNWnW3a@i5x59C%6z@R%ju!s#l!7kLWq2158AdEyuy!AktZv_oxz=- zWKAkj@;TN~yl>sLnx;o}Rch<;=uK~$g_uH-CDd0zPL6-gJxBeI$Ryzd+z;e$k2A2| zxYD}=F`?(6vP#!RAZb;O6vC;8%S zcGP(-oXo>cDfcUP1b|Vkz^;`^uU5>HpH4iv-fpPB6r~|7AgB?68SGL*TNg~wJ62am z%OV#Yz8t?jsWEuo@8Fyxf zX;@jMH5P#ElEZSm@2c^s<~#XEDrU^Bg2a_mHQv1&{X@q#_1Bfw1VFCdQNF^gt$TEW z(J{?o@l|H>Xk+O3Vz$9x===de(QC~b%@=FwcJ!(-F_qhseAhE;z&(AdV>ulc5&h-m zt!F1V_cQ`)f}2kzBrsU3%55mZkj8wba{Z}8n@Dd0&m0*1qbAvZNTH2PU4%KdaVi_^ zac}1oWvM|SVc+9->oFC~A0$YHV(TItaA5kdkX#g%%5K?0-G&5;67MifSDWI8I{c*G z{5s>v-rrA12~x%q;QTba_V)KLsotCQvvXUYD2FWcmrvYm@4cV@g%SM6%8r2RdY1ff z{fG}9p}Zg}(R=qUdf4+pQR*uQ?3)j519w;&@M)yp>KsSwsBcIuofhe36wOBuQrx{H9z9MV>sSw^d_Z@#|l* zphSG!T3hNq85#H!^7U(^U>$Vqvjr5VSKaL$F5@m>Q7OkPSDcxfd(Ir{ODi@82LY6$Tu&r|5R!FYczj~deTCTDScTq6StoLM>d+H^v`;xEj@ z63z~oGL(+K9;Z=KQnw$f?Xgx5(8CwQQ9D{EMRS2g!0S^((DR`?Dd)MK?k@2vDVPet zLvL>)5SmGN8CLN@Bo@SKzQHCd{g}Uv?_7%C{7eyA%*KZBFYr3s9Iij|2J5(Q# z{Gjr1G!w`cLOdiRD+}e`N7mPhiHX@x)+H^+9Ahe6Ip&9iln24rW-2jZ>6O+qZ048b z!2~_J2&bXA`vYbviW~%ObE24b)~kGde8s$c3@yYzWAb2JS^cx%1oM(4g&gW_*9uX_%W%@M{dCMuJuwMWE zgM%sz@Ixch)hi#??S1qQmpF3OqOcln^U@;*Qy3;Dw%Nyp%I!a+w*UO5Mgtj;gjpCkZvr zdSCm`>!Ky%*I02OWWxcu?iXQ+$(4uX9dPsl#%cx-DT%)dh_W$Tm}V1^6~qZ#g$&AZ zX@02w>}fH>06Kq~Y$$P<-UM9L3W>SnY%rTi0z&YHmOkFP;_C~hxV1_0pm)l`8LdFY;`)Z?PNyBoB0zy5LYu$A8 z^kQ|(+k7?fW~Gmf>C}6)i{t5otTnxO^M%GfXFu6G5wL5|WfWngpjzLyDX5;O*plFO z*?+sFaFr;P?09v2wcZ2E=(YH3NkbR-NBL%g0(pv4?^RjR9Zgzq1)_nCN*lz0!|($6-mRmu~hwuif8k?F$%rJ|&=7 zQnABR>TuP7bG@oyOU}4>*2!sh-yhiKy=%%BOj7|BI`3voSgC20+jqxi>+Z}(j2sxm z>CFrWGF6n1Iqn%eiyU>On0`g`Y>l>tGy>~zy6@%ipLQyKhY^KXo^Agx8FqPj37y4< zCoEcxb21v9UD$M{Haxf=7$|-wxboG%>eTJLZqM{}{>*N} zFNy1e{kP&5L~Bzp9=&*zTg1fRA>S4u(3*Vc6`jBc;J?n(oyswbXu|z;0!&Y!aC#9+ zi!#ufd|AOhlnzuwgEJmKum#sTnd#n5$be3UF6#I0=hVpUh?vdGA4>xF31w7m3CA1q z4)M|&S`^uB5p=nE>8dUMQqzZsLnpkgA#FtqS;;yU<}zVm;yfb!!)i317w3M4?Rlg$ z1U+67 zw7W8tD8%d4+=y^d?2JQB1pVR+>J2GJYELl4xh)hSq4r9?n;sAe&n_`DK67T+I; zs*RSG%;~BjoOaA5IG(7g=zJ~z$70WYEjCc$t>W9%!ta9Yhc2(Kz^S~vG@F>c{?+C= z`B*hqeQr3(bE?+GU?#Q{n{(W&TY2kUl3A`vwsO@FeR9g%Oud^AVd7uDxXU%9u;6wl zoUg@7O*;*3HAtVsWF>!Mxa*33l=Z}8yBS-HU93S->8gllR`$6{<6=@+i=|5mdF!n^ z2)w|?Y{&jUNeM{Lo4ujh4+s(T1N7@(l)|w-S$IUr z`jp#G?x7E+ctFT+TS`D}^0SJ!_>{|;&0ZJCUwGV9vEkl9wd)UqvHm3i_M-7ZKOGP& zrX2a{L5^!)FNPaP_xk>?uugK*W%u;;Uq^#-sw5z$ z8dN+;WdQe+ZC@(ECBc#_C}pU-!*sR0c53?NUqOv1GdR9irpU(`8oAf3QiN*SH^y+; z#^wfNj4tFd8@adfBOjA$od-n!?10Zhfg(tBH}AH_voLt6jQ)LG!*$_XDIIux*jXQt z``{SkhYpbtWO$1iXDsoa8s-llue>AvZ!eJ(K$AI{OR%3}rO;@x9r}k2J&PG$gmQ2N z-(O{z>ON6Apf&r4Bz?+q>QPksJl{ZwLreNX5PZ(fjm%iS9{3N&?Til%MW2z&fk8hx Q<#r#W#N^)btd^wvlRq?3LpVs)& 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

    |L`Mz=6o8XWM;;^uu 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 Qw;v!SCNEkn{PFAm1z>bg;s5{u literal 0 HcmV?d00001 diff --git a/output/resolution-ui-demo/allurerc.mjs b/output/resolution-ui-demo/allurerc.mjs new file mode 100644 index 00000000000..7c4b3cac510 --- /dev/null +++ b/output/resolution-ui-demo/allurerc.mjs @@ -0,0 +1,32 @@ +export default { + name: "Resolution UI Demo", + historyPath: "./output/resolution-ui-demo/history.jsonl", + resolutions: { + knownIssuesPath: "./output/resolution-ui-demo/known-issues.json", + links: { + jira: { + urlTemplate: "https://example.test/browse/%s", + nameTemplate: "%s" + } + }, + rules: [ + { resolution: "issue", messageRegexp: "BUG-101", issue: { id: "BUG-101", type: "jira" }, comment: "Checkout discount is not applied" }, + { resolution: "issue", messageRegexp: "BUG-102", issue: { id: "BUG-102", type: "jira" }, comment: "PayPal authorization timeout" }, + { resolution: "issue", messageRegexp: "BUG-103", issue: { id: "BUG-103", type: "jira" }, comment: "Refund processing leaves stale balance" }, + { resolution: "issue", messageRegexp: "BUG-104", issue: { id: "BUG-104", type: "jira" }, comment: "Search index is stale" }, + { resolution: "muted", messageRegexp: "MUTE-CDN", comment: "Muted external dependency" }, + { resolution: "accepted", messageRegexp: "ACCEPT-LEGACY", comment: "Accepted legacy behavior risk" } + ] + }, + plugins: { + awesome: { + options: { + reportName: "Resolution UI Demo", + open: false, + reportLanguage: "en", + groupBy: ["parentSuite", "suite", "story"], + publish: true + } + } + } +}; diff --git a/output/resolution-ui-demo/history.jsonl b/output/resolution-ui-demo/history.jsonl new file mode 100644 index 00000000000..59ebb382733 --- /dev/null +++ b/output/resolution-ui-demo/history.jsonl @@ -0,0 +1 @@ +{"uuid":"1adc41c2-2728-4909-8625-2665e31a2395","name":"Resolution UI Demo","timestamp":1788539050686,"knownTestCaseIds":["51609711b7904b9d30cc23ec15e6a2d2","202ebc8deba1db5ffb46c68058b1e710","9d548bbb2e93d70394e5661b9da12866","26df6def03cbee7aa023d110853b41bf","716bea711f5eed83b1db9551f7ea8dc4","8355cde98cfd5d929f83b471b3ae8299","318b821c70e89dced24bda3b25ca005e","a930f832c76ef071261927c794261374","3917b52e56481b0a76750bc913494885","69d7916ae3b55d34593eb69a7194277e"],"testResults":{"51609711b7904b9d30cc23ec15e6a2d2.d41d8cd98f00b204e9800998ecf8427e":{"id":"459c7999f440244b163b38e375fededd","name":"checkout applies discount for card payments","fullName":"demo.resolutions.Checkout.issue-checkout-card","environment":"default","status":"failed","message":"BUG-101 checkout discount was not applied","trace":"Demo trace for issue-checkout-card\n at demo/resolutions.spec.ts:20:7","start":1788523200000,"stop":1788523200120,"duration":120,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Checkout"},{"name":"feature","value":"Discounts"},{"name":"story","value":"issue"},{"name":"tag","value":"issue"}],"url":"","historyId":"51609711b7904b9d30cc23ec15e6a2d2.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"202ebc8deba1db5ffb46c68058b1e710.d41d8cd98f00b204e9800998ecf8427e":{"id":"9953167bc50f9ede04b1d8ac88713627","name":"checkout applies discount for wallet payments","fullName":"demo.resolutions.Checkout.issue-checkout-wallet","environment":"default","status":"failed","message":"BUG-101 checkout discount was not applied for wallet","trace":"Demo trace for issue-checkout-wallet\n at demo/resolutions.spec.ts:21:7","start":1788523201000,"stop":1788523201135,"duration":135,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Checkout"},{"name":"feature","value":"Discounts"},{"name":"story","value":"issue"},{"name":"tag","value":"issue"},{"name":"flaky","value":"true"}],"url":"","historyId":"202ebc8deba1db5ffb46c68058b1e710.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"9d548bbb2e93d70394e5661b9da12866.d41d8cd98f00b204e9800998ecf8427e":{"id":"68ea715b81d4e08694e3ceb2686e89c4","name":"paypal authorization succeeds","fullName":"demo.resolutions.Payments.issue-paypal","environment":"default","status":"broken","message":"BUG-102 paypal gateway timed out","trace":"Demo trace for issue-paypal\n at demo/resolutions.spec.ts:22:7","start":1788523202000,"stop":1788523202100,"duration":100,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Payments"},{"name":"feature","value":"Authorization"},{"name":"story","value":"issue"},{"name":"tag","value":"issue"}],"url":"","historyId":"9d548bbb2e93d70394e5661b9da12866.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"26df6def03cbee7aa023d110853b41bf.d41d8cd98f00b204e9800998ecf8427e":{"id":"8d7ce827ef8b49dc44c40e1b723989d1","name":"refund request restores profile balance","fullName":"demo.resolutions.Billing.issue-refund","environment":"default","status":"failed","message":"BUG-103 stale balance after refund","trace":"Demo trace for issue-refund\n at demo/resolutions.spec.ts:23:7","start":1788523203000,"stop":1788523203150,"duration":150,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Billing"},{"name":"feature","value":"Refunds"},{"name":"story","value":"issue"},{"name":"tag","value":"issue"}],"url":"","historyId":"26df6def03cbee7aa023d110853b41bf.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"716bea711f5eed83b1db9551f7ea8dc4.d41d8cd98f00b204e9800998ecf8427e":{"id":"eb2a76a56f5a633adb357267ded34b96","name":"product search returns fresh index","fullName":"demo.resolutions.Catalog.issue-search","environment":"default","status":"failed","message":"BUG-104 stale search index","trace":"Demo trace for issue-search\n at demo/resolutions.spec.ts:24:7","start":1788523204000,"stop":1788523204110,"duration":110,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Catalog"},{"name":"feature","value":"Search"},{"name":"story","value":"issue"},{"name":"tag","value":"issue"}],"url":"","historyId":"716bea711f5eed83b1db9551f7ea8dc4.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"8355cde98cfd5d929f83b471b3ae8299.d41d8cd98f00b204e9800998ecf8427e":{"id":"ea8ab66a8e64cb4702a5b859dc3212c2","name":"cdn healthcheck returns ok","fullName":"demo.resolutions.Infra.muted-cdn","environment":"default","status":"broken","message":"MUTE-CDN upstream timeout","trace":"Demo trace for muted-cdn\n at demo/resolutions.spec.ts:25:7","start":1788523205000,"stop":1788523205095,"duration":95,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Infra"},{"name":"feature","value":"External dependency"},{"name":"story","value":"muted"},{"name":"tag","value":"muted"}],"url":"","historyId":"8355cde98cfd5d929f83b471b3ae8299.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"318b821c70e89dced24bda3b25ca005e.d41d8cd98f00b204e9800998ecf8427e":{"id":"370546428d1feb42c41944a7616e4636","name":"webhook delivery reaches partner sandbox","fullName":"demo.resolutions.Integrations.muted-webhook","environment":"default","status":"failed","message":"MUTE-CDN partner sandbox timeout","trace":"Demo trace for muted-webhook\n at demo/resolutions.spec.ts:26:7","start":1788523206000,"stop":1788523206160,"duration":160,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Integrations"},{"name":"feature","value":"External dependency"},{"name":"story","value":"muted"},{"name":"tag","value":"muted"}],"url":"","historyId":"318b821c70e89dced24bda3b25ca005e.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"a930f832c76ef071261927c794261374.d41d8cd98f00b204e9800998ecf8427e":{"id":"41958966c014570f8dbaf64aedbb51ec","name":"analytics event includes legacy campaign id","fullName":"demo.resolutions.Analytics.accepted-analytics","environment":"default","status":"failed","message":"ACCEPT-LEGACY legacy campaign id omitted","trace":"Demo trace for accepted-analytics\n at demo/resolutions.spec.ts:27:7","start":1788523207000,"stop":1788523207080,"duration":80,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Analytics"},{"name":"feature","value":"Legacy risk"},{"name":"story","value":"accepted"},{"name":"tag","value":"accepted"}],"url":"","historyId":"a930f832c76ef071261927c794261374.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"3917b52e56481b0a76750bc913494885.d41d8cd98f00b204e9800998ecf8427e":{"id":"2c24c8c736451711ec6aacb72229249e","name":"checkout displays loyalty banner","fullName":"demo.resolutions.Checkout.unresolved-loyalty","environment":"default","status":"failed","message":"Unexpected missing loyalty banner","trace":"Demo trace for unresolved-loyalty\n at demo/resolutions.spec.ts:28:7","start":1788523208000,"stop":1788523208090,"duration":90,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Checkout"},{"name":"feature","value":"Loyalty"},{"name":"story","value":"unresolved"},{"name":"tag","value":"unresolved"}],"url":"","historyId":"3917b52e56481b0a76750bc913494885.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]},"69d7916ae3b55d34593eb69a7194277e.d41d8cd98f00b204e9800998ecf8427e":{"id":"7508ff515bcc3d08b9831f70bb6d63ab","name":"profile page loads successfully","fullName":"demo.resolutions.Profile.passed-baseline","environment":"default","status":"passed","start":1788523209000,"stop":1788523209070,"duration":70,"labels":[{"name":"parentSuite","value":"Resolution UI Demo"},{"name":"suite","value":"Profile"},{"name":"feature","value":"Baseline"},{"name":"story","value":"baseline"},{"name":"tag","value":"baseline"}],"url":"","historyId":"69d7916ae3b55d34593eb69a7194277e.d41d8cd98f00b204e9800998ecf8427e","reportLinks":[]}},"metrics":{},"url":""} diff --git a/output/resolution-ui-demo/known-issues.json b/output/resolution-ui-demo/known-issues.json new file mode 100644 index 00000000000..c3911b80f16 --- /dev/null +++ b/output/resolution-ui-demo/known-issues.json @@ -0,0 +1 @@ +{"resolutionIssues":[{"id":"BUG-101","type":"jira","comment":"Checkout discount is not applied","testResults":{"0f5be4597b1ecdf94cdb46d3fd04bf36":{"name":"checkout applies discount for card payments","fullName":"demo.resolutions.Checkout.issue-checkout-card","environment":"default","status":"failed","error":{"message":"BUG-101 checkout discount was not applied","trace":"Demo trace for issue-checkout-card\n at demo/resolutions.spec.ts:20:7"}},"3f38fe46f0a2c41750bee9ee926d1b59":{"name":"checkout applies discount for wallet payments","fullName":"demo.resolutions.Checkout.issue-checkout-wallet","environment":"default","status":"failed","error":{"message":"BUG-101 checkout discount was not applied for wallet","trace":"Demo trace for issue-checkout-wallet\n at demo/resolutions.spec.ts:21:7"}}}},{"id":"BUG-102","type":"jira","comment":"PayPal authorization timeout","testResults":{"4b020cbb2fbced0241fa4cef39c20a2e":{"name":"paypal authorization succeeds","fullName":"demo.resolutions.Payments.issue-paypal","environment":"default","status":"broken","error":{"message":"BUG-102 paypal gateway timed out","trace":"Demo trace for issue-paypal\n at demo/resolutions.spec.ts:22:7"}}}},{"id":"BUG-103","type":"jira","comment":"Refund processing leaves stale balance","testResults":{"6574d00540f8ea198081e0b0cdfbabc3":{"name":"refund request restores profile balance","fullName":"demo.resolutions.Billing.issue-refund","environment":"default","status":"failed","error":{"message":"BUG-103 stale balance after refund","trace":"Demo trace for issue-refund\n at demo/resolutions.spec.ts:23:7"}}}},{"id":"BUG-104","type":"jira","comment":"Search index is stale","testResults":{"9102e5b0ce8441c9d2fb60a343168d5c":{"name":"product search returns fresh index","fullName":"demo.resolutions.Catalog.issue-search","environment":"default","status":"failed","error":{"message":"BUG-104 stale search index","trace":"Demo trace for issue-search\n at demo/resolutions.spec.ts:24:7"}}}}]} diff --git a/packages/web-awesome/src/components/HotkeysProvider/index.tsx b/packages/web-awesome/src/components/HotkeysProvider/index.tsx index d13ac523b70..48f5af9fd96 100644 --- a/packages/web-awesome/src/components/HotkeysProvider/index.tsx +++ b/packages/web-awesome/src/components/HotkeysProvider/index.tsx @@ -176,28 +176,28 @@ const createBindings = (): HotkeyBinding[] => [ handler: () => goToReportRootTab(REPORT_ROOT_TAB.Categories), }, { - id: "report-tab-quality-gate", + id: "report-tab-resolution-categories", scope: "global", key: "3", - handler: () => goToReportRootTab(REPORT_ROOT_TAB.QualityGate), + handler: () => goToReportRootTab(REPORT_ROOT_TAB.ResolutionCategories), }, { - id: "report-tab-global-attachments", + id: "report-tab-quality-gate", scope: "global", key: "4", - handler: () => goToReportRootTab(REPORT_ROOT_TAB.GlobalAttachments), + handler: () => goToReportRootTab(REPORT_ROOT_TAB.QualityGate), }, { - id: "report-tab-global-errors", + id: "report-tab-global-attachments", scope: "global", key: "5", - handler: () => goToReportRootTab(REPORT_ROOT_TAB.GlobalErrors), + handler: () => goToReportRootTab(REPORT_ROOT_TAB.GlobalAttachments), }, { - id: "report-tab-resolution-categories", + id: "report-tab-global-errors", scope: "global", key: "6", - handler: () => goToReportRootTab(REPORT_ROOT_TAB.ResolutionCategories), + handler: () => goToReportRootTab(REPORT_ROOT_TAB.GlobalErrors), }, { id: "report-tab-next", diff --git a/packages/web-awesome/src/components/KeyboardShortcuts/shortcutsConfig.ts b/packages/web-awesome/src/components/KeyboardShortcuts/shortcutsConfig.ts index e0cce4033dc..e81d49ea0a1 100644 --- a/packages/web-awesome/src/components/KeyboardShortcuts/shortcutsConfig.ts +++ b/packages/web-awesome/src/components/KeyboardShortcuts/shortcutsConfig.ts @@ -27,10 +27,10 @@ export const shortcutGroups: ShortcutGroup[] = [ { binding: { key: "\\", code: "Backslash", modifiers: { ctrlOrMeta: true } }, labelKey: "items.toggleLayoutAlt" }, { binding: { key: "1" }, labelKey: "items.reportTabResults" }, { binding: { key: "2" }, labelKey: "items.reportTabCategories" }, - { binding: { key: "3" }, labelKey: "items.reportTabQualityGate" }, - { binding: { key: "4" }, labelKey: "items.reportTabGlobalAttachments" }, - { binding: { key: "5" }, labelKey: "items.reportTabGlobalErrors" }, - { binding: { key: "6" }, labelKey: "items.reportTabResolutionCategories" }, + { binding: { key: "3" }, labelKey: "items.reportTabResolutionCategories" }, + { binding: { key: "4" }, labelKey: "items.reportTabQualityGate" }, + { binding: { key: "5" }, labelKey: "items.reportTabGlobalAttachments" }, + { binding: { key: "6" }, labelKey: "items.reportTabGlobalErrors" }, { binding: { key: "Tab" }, labelKey: "items.reportTabNext" }, { binding: { key: "Tab", modifiers: { shift: true } }, labelKey: "items.reportTabPrev" }, ], diff --git a/packages/web-awesome/src/components/MainReport/index.tsx b/packages/web-awesome/src/components/MainReport/index.tsx index e0c119998f2..b1ba3a5d725 100644 --- a/packages/web-awesome/src/components/MainReport/index.tsx +++ b/packages/web-awesome/src/components/MainReport/index.tsx @@ -173,6 +173,20 @@ const MainReport = () => { ); }} /> + { + if (!resolutionCategories?.groups.length) { + return null; + } + + return ( + + {t("resolutionCategories")} + + ); + }} + /> { @@ -217,20 +231,6 @@ const MainReport = () => { ); }} /> - { - if (!resolutionCategories?.groups.length) { - return null; - } - - return ( - - {t("resolutionCategories")} - - ); - }} - />

    diff --git a/packages/web-awesome/src/components/ResolutionCategoriesList/index.tsx b/packages/web-awesome/src/components/ResolutionCategoriesList/index.tsx index 83fc91d3719..12119f024fd 100644 --- a/packages/web-awesome/src/components/ResolutionCategoriesList/index.tsx +++ b/packages/web-awesome/src/components/ResolutionCategoriesList/index.tsx @@ -1,8 +1,9 @@ import { type ResolutionCategory } from "@allurereport/core-api"; import { ArrowButton, SvgIcon, Text, TreeItem, allureIcons } from "@allurereport/web-components"; +import clsx from "clsx"; import type { FunctionalComponent } from "preact"; import { useState } from "preact/hooks"; -import type { AwesomeResolutionGroup, AwesomeResolutionTestResult } from "types"; +import type { ReportResolutionGroup, ReportResolutionTestResult } from "types"; import { useI18n } from "@/stores/locale"; import { navigateToTestResult } from "@/stores/router"; @@ -10,9 +11,10 @@ import { navigateToTestResult } from "@/stores/router"; import * as styles from "./styles.scss"; export type ResolutionCategoriesListProps = { - groups: AwesomeResolutionGroup[]; + groups: ReportResolutionGroup[]; showTests?: boolean; emptyText: string; + compact?: boolean; }; const resolutionIcons: Record = { @@ -22,7 +24,7 @@ const resolutionIcons: Record = { }; const getResolutionTitle = ( - group: AwesomeResolutionGroup, + group: ReportResolutionGroup, t: (key: string, options?: Record) => string, ) => { if (group.resolution === "issue") { @@ -36,69 +38,87 @@ export const ResolutionCategoriesList: FunctionalComponent { if (!groups.length) { return
    {emptyText}
    ; } return ( -