@crvy/rprtr 0.0.9 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/dist/{chunk-TS64TROX.js → chunk-35CZLYSW.js} +210 -58
- package/dist/{chunk-EJRLZZ22.js → chunk-43JLQN36.js} +45 -5
- package/dist/ci.d.ts +2 -0
- package/dist/ci.d.ts.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +7 -4
- package/dist/index.js +340 -46
- package/dist/report-utils.d.ts.map +1 -1
- package/dist/reporter-artifact-ops.d.ts +1 -3
- package/dist/reporter-artifact-ops.d.ts.map +1 -1
- package/dist/reporter.cjs +285 -198
- package/dist/reporter.d.ts +5 -3
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +81 -31
- package/dist/schemas.d.ts +210 -1
- package/dist/schemas.d.ts.map +1 -1
- package/dist/server/app.d.ts +6 -0
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/artifact-routes.d.ts +8 -0
- package/dist/server/artifact-routes.d.ts.map +1 -0
- package/dist/server/file-utils.d.ts.map +1 -1
- package/dist/server/handlers.d.ts +6 -2
- package/dist/server/handlers.d.ts.map +1 -1
- package/dist/server/routes.d.ts +2 -2
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/utils.d.ts +3 -0
- package/dist/server/utils.d.ts.map +1 -1
- package/dist/server.cjs +289 -115
- package/dist/server.js +2 -2
- package/dist/snapshot-path-resolver.d.ts +2 -0
- package/dist/snapshot-path-resolver.d.ts.map +1 -1
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19391,10 +19391,29 @@ var CrvyRprtrSuiteSchema = external_exports.lazy(
|
|
|
19391
19391
|
children: external_exports.record(external_exports.string(), external_exports.union([CrvyRprtrSuiteSchema, CrvyRprtrTestSchema])).optional()
|
|
19392
19392
|
})
|
|
19393
19393
|
);
|
|
19394
|
-
var
|
|
19394
|
+
var IncomingWebSocketMessageSchema = external_exports.object({
|
|
19395
19395
|
type: external_exports.enum(["test-begin", "test-end", "run-end", "approve", "sync"]),
|
|
19396
19396
|
data: external_exports.unknown()
|
|
19397
19397
|
});
|
|
19398
|
+
var WebSocketMessageSchema = external_exports.discriminatedUnion("type", [
|
|
19399
|
+
external_exports.object({ type: external_exports.literal("test-begin"), data: TestDataSchema }),
|
|
19400
|
+
external_exports.object({ type: external_exports.literal("test-update"), data: TestDataSchema }),
|
|
19401
|
+
external_exports.object({
|
|
19402
|
+
type: external_exports.literal("run-end"),
|
|
19403
|
+
data: external_exports.object({
|
|
19404
|
+
status: external_exports.enum(["passed", "failed", "skipped"]),
|
|
19405
|
+
removedTestIds: external_exports.array(external_exports.string())
|
|
19406
|
+
})
|
|
19407
|
+
}),
|
|
19408
|
+
external_exports.object({
|
|
19409
|
+
type: external_exports.literal("sync"),
|
|
19410
|
+
data: external_exports.object({
|
|
19411
|
+
tests: external_exports.record(external_exports.string(), TestDataSchema),
|
|
19412
|
+
isUpdateMode: external_exports.boolean().optional()
|
|
19413
|
+
})
|
|
19414
|
+
}),
|
|
19415
|
+
external_exports.object({ type: external_exports.literal("approve"), data: external_exports.unknown() })
|
|
19416
|
+
]);
|
|
19398
19417
|
var TestBeginDataSchema = external_exports.object({
|
|
19399
19418
|
id: external_exports.string(),
|
|
19400
19419
|
title: external_exports.string(),
|
|
@@ -19414,6 +19433,9 @@ var TestEndDataSchema = external_exports.object({
|
|
|
19414
19433
|
error: external_exports.string().optional(),
|
|
19415
19434
|
duration: external_exports.number().optional()
|
|
19416
19435
|
});
|
|
19436
|
+
var RunEndDataSchema = external_exports.object({
|
|
19437
|
+
status: external_exports.enum(["passed", "failed", "skipped"])
|
|
19438
|
+
});
|
|
19417
19439
|
var ReportDataSchema = external_exports.object({
|
|
19418
19440
|
isRunning: external_exports.boolean(),
|
|
19419
19441
|
tests: external_exports.record(external_exports.string(), TestDataSchema),
|
|
@@ -19678,19 +19700,269 @@ function treeifyTests(testsById) {
|
|
|
19678
19700
|
});
|
|
19679
19701
|
return rootSuite;
|
|
19680
19702
|
}
|
|
19681
|
-
|
|
19682
|
-
|
|
19683
|
-
|
|
19684
|
-
|
|
19685
|
-
|
|
19686
|
-
|
|
19687
|
-
|
|
19688
|
-
|
|
19689
|
-
|
|
19690
|
-
|
|
19691
|
-
|
|
19703
|
+
|
|
19704
|
+
// src/client/helpers/test-equality.ts
|
|
19705
|
+
function isTestDataEqual(a, b) {
|
|
19706
|
+
if (a === b) return true;
|
|
19707
|
+
if (a.id !== b.id) return false;
|
|
19708
|
+
if (a.title !== b.title) return false;
|
|
19709
|
+
if (a.browser !== b.browser) return false;
|
|
19710
|
+
if (a.skip !== b.skip) return false;
|
|
19711
|
+
if (a.status !== b.status) return false;
|
|
19712
|
+
if (a.retries !== b.retries) return false;
|
|
19713
|
+
if (!arraysShallowEqual(a.titlePath, b.titlePath ?? [])) return false;
|
|
19714
|
+
if (!approvedEqual(a.approved, b.approved)) return false;
|
|
19715
|
+
if (!resultsEqual(a.results, b.results)) return false;
|
|
19716
|
+
if (!attachmentsEqual(a.attachments, b.attachments)) return false;
|
|
19717
|
+
if (!locationsEqual(a.location, b.location)) return false;
|
|
19718
|
+
return true;
|
|
19719
|
+
}
|
|
19720
|
+
function arraysShallowEqual(a, b) {
|
|
19721
|
+
if (a === b) return true;
|
|
19722
|
+
if (a.length !== b.length) return false;
|
|
19723
|
+
for (let i = 0; i < a.length; i++) {
|
|
19724
|
+
if (a[i] !== b[i]) return false;
|
|
19725
|
+
}
|
|
19726
|
+
return true;
|
|
19727
|
+
}
|
|
19728
|
+
function approvedEqual(a, b) {
|
|
19729
|
+
if (a === b) return true;
|
|
19730
|
+
if (a === null || a === void 0 || b === null || b === void 0) return false;
|
|
19731
|
+
const aKeys = Object.keys(a);
|
|
19732
|
+
const bKeys = Object.keys(b);
|
|
19733
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
19734
|
+
for (const key2 of aKeys) {
|
|
19735
|
+
if (a[key2] !== b[key2]) return false;
|
|
19736
|
+
}
|
|
19737
|
+
return true;
|
|
19738
|
+
}
|
|
19739
|
+
function resultsEqual(a, b) {
|
|
19740
|
+
if (a === b) return true;
|
|
19741
|
+
if (a === void 0 || b === void 0) return false;
|
|
19742
|
+
if (a.length !== b.length) return false;
|
|
19743
|
+
for (let i = 0; i < a.length; i++) {
|
|
19744
|
+
const ai = a[i];
|
|
19745
|
+
const bi = b[i];
|
|
19746
|
+
if (ai === bi) continue;
|
|
19747
|
+
if (ai === void 0 || bi === void 0) return false;
|
|
19748
|
+
if (!resultEqual(ai, bi)) return false;
|
|
19749
|
+
}
|
|
19750
|
+
return true;
|
|
19751
|
+
}
|
|
19752
|
+
function resultEqual(a, b) {
|
|
19753
|
+
if (a === b) return true;
|
|
19754
|
+
if (a.status !== b.status) return false;
|
|
19755
|
+
if (a.retries !== b.retries) return false;
|
|
19756
|
+
if (a.error !== b.error) return false;
|
|
19757
|
+
if (a.duration !== b.duration) return false;
|
|
19758
|
+
if (!imagesEqual(a.images, b.images)) return false;
|
|
19759
|
+
if (!visualDeclarationsEqual(a.visualDeclarations, b.visualDeclarations)) return false;
|
|
19760
|
+
return true;
|
|
19761
|
+
}
|
|
19762
|
+
function imagesEqual(a, b) {
|
|
19763
|
+
if (a === b) return true;
|
|
19764
|
+
if (a === void 0 || b === void 0) return false;
|
|
19765
|
+
const aKeys = Object.keys(a);
|
|
19766
|
+
const bKeys = Object.keys(b);
|
|
19767
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
19768
|
+
for (const key2 of aKeys) {
|
|
19769
|
+
const ai = a[key2];
|
|
19770
|
+
const bi = b[key2];
|
|
19771
|
+
if (ai === bi) continue;
|
|
19772
|
+
if (ai === void 0 || bi === void 0) return false;
|
|
19773
|
+
if (ai.actual !== bi.actual) return false;
|
|
19774
|
+
if (ai.expect !== bi.expect) return false;
|
|
19775
|
+
if (ai.diff !== bi.diff) return false;
|
|
19776
|
+
if (ai.error !== bi.error) return false;
|
|
19777
|
+
if (ai.source !== bi.source) return false;
|
|
19778
|
+
}
|
|
19779
|
+
return true;
|
|
19780
|
+
}
|
|
19781
|
+
function visualDeclarationsEqual(a, b) {
|
|
19782
|
+
if (a === b) return true;
|
|
19783
|
+
if (a === void 0 || b === void 0) return false;
|
|
19784
|
+
if (a.length !== b.length) return false;
|
|
19785
|
+
for (let i = 0; i < a.length; i++) {
|
|
19786
|
+
const ai = a[i];
|
|
19787
|
+
const bi = b[i];
|
|
19788
|
+
if (ai === bi) continue;
|
|
19789
|
+
if (ai === void 0 || bi === void 0) return false;
|
|
19790
|
+
if (ai.visualName !== bi.visualName) return false;
|
|
19791
|
+
if (ai.kind !== bi.kind) return false;
|
|
19792
|
+
if (ai.kind === "named") {
|
|
19793
|
+
if (bi.kind !== "named") return false;
|
|
19794
|
+
if (ai.declaredName !== bi.declaredName) return false;
|
|
19795
|
+
if (ai.snapshotBaseName !== bi.snapshotBaseName) return false;
|
|
19796
|
+
}
|
|
19797
|
+
if (ai.occurrenceIndex !== bi.occurrenceIndex) return false;
|
|
19798
|
+
}
|
|
19799
|
+
return true;
|
|
19800
|
+
}
|
|
19801
|
+
function attachmentsEqual(a, b) {
|
|
19802
|
+
if (a === b) return true;
|
|
19803
|
+
if (a === void 0 || b === void 0) return false;
|
|
19804
|
+
if (a.length !== b.length) return false;
|
|
19805
|
+
for (let i = 0; i < a.length; i++) {
|
|
19806
|
+
const ai = a[i];
|
|
19807
|
+
const bi = b[i];
|
|
19808
|
+
if (ai === bi) continue;
|
|
19809
|
+
if (ai === void 0 || bi === void 0) return false;
|
|
19810
|
+
if (ai.name !== bi.name) return false;
|
|
19811
|
+
if (ai.path !== bi.path) return false;
|
|
19812
|
+
if (ai.contentType !== bi.contentType) return false;
|
|
19813
|
+
}
|
|
19814
|
+
return true;
|
|
19815
|
+
}
|
|
19816
|
+
function locationsEqual(a, b) {
|
|
19817
|
+
if (a === b) return true;
|
|
19818
|
+
if (a === void 0 || b === void 0) return false;
|
|
19819
|
+
return a.file === b.file && a.line === b.line;
|
|
19820
|
+
}
|
|
19821
|
+
function copyMutableFields(target, source2) {
|
|
19822
|
+
if (target.status !== source2.status) target.status = source2.status;
|
|
19823
|
+
if (target.skip !== source2.skip) target.skip = source2.skip;
|
|
19824
|
+
if (target.retries !== source2.retries) target.retries = source2.retries;
|
|
19825
|
+
if (!approvedEqual(target.approved, source2.approved)) target.approved = source2.approved;
|
|
19826
|
+
if (!resultsEqual(target.results, source2.results)) target.results = source2.results;
|
|
19827
|
+
if (!attachmentsEqual(target.attachments, source2.attachments)) target.attachments = source2.attachments;
|
|
19828
|
+
if (!locationsEqual(target.location, source2.location)) target.location = source2.location;
|
|
19829
|
+
}
|
|
19830
|
+
|
|
19831
|
+
// src/client/helpers/tree-sync.ts
|
|
19832
|
+
function collectOldTests(suite, parentPath, out) {
|
|
19833
|
+
for (const [key2, child2] of getChildrenEntries(suite.children)) {
|
|
19834
|
+
if (child2 === void 0) continue;
|
|
19835
|
+
if (isTest(child2)) {
|
|
19836
|
+
out.set(child2.id, { test: child2, parent: suite, parentPath, browserKey: key2 });
|
|
19837
|
+
} else {
|
|
19838
|
+
collectOldTests(child2, [...parentPath, key2], out);
|
|
19839
|
+
}
|
|
19840
|
+
}
|
|
19841
|
+
}
|
|
19842
|
+
function collectTestsById(suite) {
|
|
19843
|
+
const out = {};
|
|
19844
|
+
function walk(node) {
|
|
19845
|
+
for (const child2 of getChildrenArray(node.children)) {
|
|
19846
|
+
if (child2 === void 0) continue;
|
|
19847
|
+
if (isTest(child2)) {
|
|
19848
|
+
out[child2.id] = child2;
|
|
19849
|
+
} else {
|
|
19850
|
+
walk(child2);
|
|
19851
|
+
}
|
|
19852
|
+
}
|
|
19853
|
+
}
|
|
19854
|
+
walk(suite);
|
|
19855
|
+
return out;
|
|
19856
|
+
}
|
|
19857
|
+
function pathTokensFor(test) {
|
|
19858
|
+
const titlePath = test.titlePath ?? [];
|
|
19859
|
+
const title = test.title;
|
|
19860
|
+
const browser = test.browser ?? "";
|
|
19861
|
+
if (title === void 0 || title === "" || browser === "") return null;
|
|
19862
|
+
const pathParts = [...titlePath, title, browser].filter((p) => p !== void 0 && p !== "");
|
|
19863
|
+
const reversed = pathParts.reverse();
|
|
19864
|
+
const browserKey = reversed[0];
|
|
19865
|
+
if (browserKey === void 0) return null;
|
|
19866
|
+
return { suitePath: reversed.slice(1).reverse(), browserKey };
|
|
19867
|
+
}
|
|
19868
|
+
function ensureSuitePath(root10, path) {
|
|
19869
|
+
let suite = root10;
|
|
19870
|
+
for (const token of path) {
|
|
19871
|
+
suite.children = suite.children ?? {};
|
|
19872
|
+
const existing = suite.children[token];
|
|
19873
|
+
if (existing !== void 0 && !isTest(existing)) {
|
|
19874
|
+
suite = existing;
|
|
19875
|
+
continue;
|
|
19876
|
+
}
|
|
19877
|
+
const nextSuite = {
|
|
19878
|
+
path: [...suite.path, token],
|
|
19879
|
+
skip: false,
|
|
19880
|
+
opened: false,
|
|
19881
|
+
checked: true,
|
|
19882
|
+
indeterminate: false,
|
|
19883
|
+
children: {}
|
|
19884
|
+
};
|
|
19885
|
+
suite.children[token] = nextSuite;
|
|
19886
|
+
suite = nextSuite;
|
|
19887
|
+
}
|
|
19888
|
+
return suite;
|
|
19889
|
+
}
|
|
19890
|
+
function pruneEmptySuites(suite) {
|
|
19891
|
+
if (suite.children === void 0) return;
|
|
19892
|
+
for (const [key2, child2] of getChildrenEntries(suite.children)) {
|
|
19893
|
+
if (child2 === void 0 || isTest(child2)) continue;
|
|
19894
|
+
pruneEmptySuites(child2);
|
|
19895
|
+
if (getChildrenKeys(child2.children).length === 0) {
|
|
19896
|
+
delete suite.children?.[key2];
|
|
19897
|
+
}
|
|
19898
|
+
}
|
|
19899
|
+
}
|
|
19900
|
+
function updateTestInPlace(target, source2) {
|
|
19901
|
+
copyMutableFields(target, source2);
|
|
19902
|
+
}
|
|
19903
|
+
function recalcAncestorStatuses(root10, parentSuitePath) {
|
|
19904
|
+
for (let i = parentSuitePath.length; i > 0; i--) {
|
|
19905
|
+
const ancestorPath = parentSuitePath.slice(0, i);
|
|
19906
|
+
const ancestor = getSuiteByPath(root10, ancestorPath);
|
|
19907
|
+
if (ancestor === void 0 || isTest(ancestor)) continue;
|
|
19908
|
+
const childStatuses = getChildrenArray(ancestor.children).map(({ status }) => status);
|
|
19909
|
+
ancestor.status = childStatuses.length === 0 ? void 0 : childStatuses.reduce(calcStatus);
|
|
19910
|
+
}
|
|
19911
|
+
const rootChildStatuses = getChildrenArray(root10.children).map(({ status }) => status);
|
|
19912
|
+
root10.status = rootChildStatuses.length === 0 ? void 0 : rootChildStatuses.reduce(calcStatus);
|
|
19913
|
+
}
|
|
19914
|
+
function applyTestsToTree(target, testsById, oldTests, expectedIds, touchedSuitePaths) {
|
|
19915
|
+
let changed = false;
|
|
19916
|
+
for (const newTest of Object.values(testsById)) {
|
|
19917
|
+
if (newTest === void 0) continue;
|
|
19918
|
+
const tokens = pathTokensFor(newTest);
|
|
19919
|
+
if (tokens === null) continue;
|
|
19920
|
+
const oldEntry = oldTests.get(newTest.id);
|
|
19921
|
+
if (oldEntry !== void 0 && oldEntry.browserKey === tokens.browserKey) {
|
|
19922
|
+
if (!isTestDataEqual(oldEntry.test, newTest)) {
|
|
19923
|
+
const statusChanged = oldEntry.test.status !== newTest.status;
|
|
19924
|
+
updateTestInPlace(oldEntry.test, newTest);
|
|
19925
|
+
changed = true;
|
|
19926
|
+
if (statusChanged) {
|
|
19927
|
+
touchedSuitePaths.add(tokens.suitePath.join("\0"));
|
|
19928
|
+
}
|
|
19929
|
+
}
|
|
19930
|
+
} else {
|
|
19931
|
+
if (oldEntry !== void 0) {
|
|
19932
|
+
delete oldEntry.parent.children?.[oldEntry.browserKey];
|
|
19933
|
+
}
|
|
19934
|
+
const parent = ensureSuitePath(target, tokens.suitePath);
|
|
19935
|
+
parent.children = parent.children ?? {};
|
|
19936
|
+
parent.children[tokens.browserKey] = {
|
|
19937
|
+
...newTest,
|
|
19938
|
+
checked: oldEntry?.test.checked ?? true
|
|
19939
|
+
};
|
|
19940
|
+
changed = true;
|
|
19941
|
+
touchedSuitePaths.add(tokens.suitePath.join("\0"));
|
|
19942
|
+
}
|
|
19943
|
+
}
|
|
19944
|
+
for (const [id, oldEntry] of oldTests) {
|
|
19945
|
+
if (!expectedIds.has(id)) {
|
|
19946
|
+
delete oldEntry.parent.children?.[oldEntry.browserKey];
|
|
19947
|
+
touchedSuitePaths.add(oldEntry.parentPath.join("\0"));
|
|
19948
|
+
changed = true;
|
|
19692
19949
|
}
|
|
19693
19950
|
}
|
|
19951
|
+
return changed;
|
|
19952
|
+
}
|
|
19953
|
+
function syncTreeState(target, testsById) {
|
|
19954
|
+
const oldTests = /* @__PURE__ */ new Map();
|
|
19955
|
+
collectOldTests(target, [], oldTests);
|
|
19956
|
+
const expectedIds = new Set(Object.keys(testsById));
|
|
19957
|
+
const touchedSuitePaths = /* @__PURE__ */ new Set();
|
|
19958
|
+
const changed = applyTestsToTree(target, testsById, oldTests, expectedIds, touchedSuitePaths);
|
|
19959
|
+
for (const joinedPath of touchedSuitePaths) {
|
|
19960
|
+
recalcAncestorStatuses(target, joinedPath.split("\0"));
|
|
19961
|
+
}
|
|
19962
|
+
if (changed) {
|
|
19963
|
+
pruneEmptySuites(target);
|
|
19964
|
+
}
|
|
19965
|
+
return changed;
|
|
19694
19966
|
}
|
|
19695
19967
|
|
|
19696
19968
|
// src/client/helpers/suite.ts
|
|
@@ -20356,7 +20628,7 @@ function SideBySideView($$anchor, $$props) {
|
|
|
20356
20628
|
});
|
|
20357
20629
|
}
|
|
20358
20630
|
reset(div);
|
|
20359
|
-
template_effect(() => classes = set_class(div, 1, "flex gap-3 items-
|
|
20631
|
+
template_effect(() => classes = set_class(div, 1, "flex gap-3 items-center", null, classes, {
|
|
20360
20632
|
"flex-col": get2(isLandscape),
|
|
20361
20633
|
"flex-row": !get2(isLandscape)
|
|
20362
20634
|
}));
|
|
@@ -20445,7 +20717,7 @@ delegate(["click", "keydown"]);
|
|
|
20445
20717
|
var root_16 = from_html(`<div class="absolute w-full h-full flex"><img alt="Expected" class="max-w-full border border-green-500 invert"/></div>`);
|
|
20446
20718
|
var root_26 = from_html(`<img alt="Diff" class="border border-transparent max-w-full invert opacity-0"/>`);
|
|
20447
20719
|
var root_33 = from_html(`<div class="absolute w-full h-full flex"><img alt="Actual" class="max-w-full border border-red-500 mix-blend-difference invert"/></div>`);
|
|
20448
|
-
var root5 = from_html(`<div class="flex flex-col gap-3"><div class="flex flex-col bg-surface-panel rounded-md overflow-hidden w-fit max-w-full border-2 border-purple-500/60"><h3 class="m-0 px-3 py-2 text-xs font-bold bg-purple-500/25 text-purple-800 dark:text-purple-400 uppercase tracking-wider">Blend (Difference)</h3> <div class="p-2"><div class="relative flex invert"><!> <!> <!></div></div></div></div>`);
|
|
20720
|
+
var root5 = from_html(`<div class="flex flex-col gap-3 items-center"><div class="flex flex-col bg-surface-panel rounded-md overflow-hidden w-fit max-w-full border-2 border-purple-500/60"><h3 class="m-0 px-3 py-2 text-xs font-bold bg-purple-500/25 text-purple-800 dark:text-purple-400 uppercase tracking-wider">Blend (Difference)</h3> <div class="p-2"><div class="relative flex invert"><!> <!> <!></div></div></div></div>`);
|
|
20449
20721
|
function BlendView($$anchor, $$props) {
|
|
20450
20722
|
push($$props, true);
|
|
20451
20723
|
var div = root5();
|
|
@@ -20802,21 +21074,21 @@ var root_29 = from_html(`<div class="flex-1 flex items-center justify-center tex
|
|
|
20802
21074
|
var root8 = from_html(`<div class="flex h-dvh relative max-md:flex-col overflow-hidden"><!> <div class="flex-1 flex flex-col overflow-hidden min-w-0"><!></div> <div class="absolute top-3 right-3 max-md:top-1 max-md:right-1 z-10"><!></div></div>`);
|
|
20803
21075
|
function App($$anchor, $$props) {
|
|
20804
21076
|
push($$props, true);
|
|
20805
|
-
let tests =
|
|
21077
|
+
let tests = proxy($$props.initialTests);
|
|
20806
21078
|
let isRunning = false;
|
|
20807
21079
|
let openedTestPath = state(proxy([]));
|
|
20808
21080
|
let filter = state(proxy({ status: null, subStrings: [] }));
|
|
20809
21081
|
let viewMode = state(proxy(getViewMode()));
|
|
20810
21082
|
let focusedPath = state(proxy([]));
|
|
20811
21083
|
let isDark = state(localStorage.getItem("crvy-rprtr-theme") !== "light");
|
|
20812
|
-
let openedTest = user_derived(() => getTestByPath(
|
|
20813
|
-
let failedTests = user_derived(() => getFailedTests(
|
|
21084
|
+
let openedTest = user_derived(() => getTestByPath(tests, get2(openedTestPath)));
|
|
21085
|
+
let failedTests = user_derived(() => getFailedTests(tests).filter(hasScreenshots));
|
|
20814
21086
|
let retry = state(0);
|
|
20815
21087
|
let imageName = state("");
|
|
20816
21088
|
let testResult = user_derived(() => get2(openedTest)?.results?.[get2(retry) - 1] ?? null);
|
|
20817
21089
|
let currentImage = user_derived(() => get2(testResult)?.images?.[get2(imageName)] ?? null);
|
|
20818
21090
|
let canApprove = user_derived(() => $$props.approvalEnabled && Boolean(get2(openedTest)?.results?.[get2(retry) - 1]?.images && get2(openedTest).approved?.[get2(imageName)] !== get2(retry) - 1 && get2(openedTest).results[get2(retry) - 1]?.status !== "success"));
|
|
20819
|
-
let suiteList = user_derived(() => flattenSuite(filterTests(
|
|
21091
|
+
let suiteList = user_derived(() => flattenSuite(filterTests(tests, get2(filter))));
|
|
20820
21092
|
user_effect(() => {
|
|
20821
21093
|
if (get2(openedTest)) {
|
|
20822
21094
|
const r2 = get2(openedTest).results?.length ?? 0;
|
|
@@ -20839,14 +21111,14 @@ function App($$anchor, $$props) {
|
|
|
20839
21111
|
const handlePopState = (event2) => {
|
|
20840
21112
|
const state2 = event2.state;
|
|
20841
21113
|
if (state2?.testPath && Array.isArray(state2.testPath)) {
|
|
20842
|
-
openSuite(
|
|
21114
|
+
openSuite(tests, state2.testPath, true);
|
|
20843
21115
|
set(openedTestPath, state2.testPath, true);
|
|
20844
21116
|
}
|
|
20845
21117
|
};
|
|
20846
21118
|
window.addEventListener("popstate", handlePopState);
|
|
20847
21119
|
const testPath = getTestPathFromSearch();
|
|
20848
21120
|
if (testPath.length > 0) {
|
|
20849
|
-
openSuite(
|
|
21121
|
+
openSuite(tests, testPath, true);
|
|
20850
21122
|
set(openedTestPath, testPath, true);
|
|
20851
21123
|
}
|
|
20852
21124
|
return () => window.removeEventListener("popstate", handlePopState);
|
|
@@ -20880,18 +21152,18 @@ function App($$anchor, $$props) {
|
|
|
20880
21152
|
}
|
|
20881
21153
|
case "ArrowRight": {
|
|
20882
21154
|
if (get2(focusedPath).length === 0) return;
|
|
20883
|
-
const focused = getSuiteByPath(
|
|
21155
|
+
const focused = getSuiteByPath(tests, get2(focusedPath));
|
|
20884
21156
|
if (focused && !isTest(focused)) {
|
|
20885
|
-
openSuite(
|
|
21157
|
+
openSuite(tests, focused.path, true);
|
|
20886
21158
|
}
|
|
20887
21159
|
break;
|
|
20888
21160
|
}
|
|
20889
21161
|
case "ArrowLeft": {
|
|
20890
21162
|
if (get2(focusedPath).length === 0) return;
|
|
20891
|
-
const focused = getSuiteByPath(
|
|
21163
|
+
const focused = getSuiteByPath(tests, get2(focusedPath));
|
|
20892
21164
|
if (!focused) return;
|
|
20893
21165
|
if (!isTest(focused) && focused.opened) {
|
|
20894
|
-
openSuite(
|
|
21166
|
+
openSuite(tests, focused.path, false);
|
|
20895
21167
|
} else {
|
|
20896
21168
|
const parentPath = isTest(focused) ? getTestPath(focused) : focused.path;
|
|
20897
21169
|
set(focusedPath, parentPath.slice(0, -1), true);
|
|
@@ -20900,12 +21172,12 @@ function App($$anchor, $$props) {
|
|
|
20900
21172
|
}
|
|
20901
21173
|
case "Enter": {
|
|
20902
21174
|
if (get2(focusedPath).length === 0) return;
|
|
20903
|
-
const focused = getSuiteByPath(
|
|
21175
|
+
const focused = getSuiteByPath(tests, get2(focusedPath));
|
|
20904
21176
|
if (!focused) return;
|
|
20905
21177
|
if (isTest(focused) && focused.results?.length) {
|
|
20906
21178
|
handleOpenTest(focused);
|
|
20907
21179
|
} else if (!isTest(focused)) {
|
|
20908
|
-
openSuite(
|
|
21180
|
+
openSuite(tests, focused.path, !focused.opened);
|
|
20909
21181
|
}
|
|
20910
21182
|
break;
|
|
20911
21183
|
}
|
|
@@ -20913,10 +21185,10 @@ function App($$anchor, $$props) {
|
|
|
20913
21185
|
if (e.altKey) return;
|
|
20914
21186
|
if (get2(focusedPath).length === 0) return;
|
|
20915
21187
|
e.preventDefault();
|
|
20916
|
-
const focused = getSuiteByPath(
|
|
21188
|
+
const focused = getSuiteByPath(tests, get2(focusedPath));
|
|
20917
21189
|
if (!focused) return;
|
|
20918
21190
|
const path = isTest(focused) ? getTestPath(focused) : focused.path;
|
|
20919
|
-
checkSuite(
|
|
21191
|
+
checkSuite(tests, path, !focused.checked);
|
|
20920
21192
|
break;
|
|
20921
21193
|
}
|
|
20922
21194
|
}
|
|
@@ -20934,14 +21206,14 @@ function App($$anchor, $$props) {
|
|
|
20934
21206
|
const testPath = getTestPath(test);
|
|
20935
21207
|
setSearchParams(testPath);
|
|
20936
21208
|
set(focusedPath, testPath, true);
|
|
20937
|
-
openSuite(
|
|
21209
|
+
openSuite(tests, testPath, true);
|
|
20938
21210
|
set(openedTestPath, testPath, true);
|
|
20939
21211
|
}
|
|
20940
21212
|
function handleSuiteOpen(path, opened) {
|
|
20941
|
-
openSuite(
|
|
21213
|
+
openSuite(tests, path, opened);
|
|
20942
21214
|
}
|
|
20943
21215
|
function handleSuiteToggle(path, checked) {
|
|
20944
|
-
checkSuite(
|
|
21216
|
+
checkSuite(tests, path, checked);
|
|
20945
21217
|
}
|
|
20946
21218
|
function handleGoToNextFailed() {
|
|
20947
21219
|
if (get2(failedTests).length === 0) return;
|
|
@@ -20965,7 +21237,7 @@ function App($$anchor, $$props) {
|
|
|
20965
21237
|
const allApproved = Object.keys(result.images).every((name) => get2(openedTest).approved?.[name] === get2(retry) - 1);
|
|
20966
21238
|
if (allApproved) {
|
|
20967
21239
|
get2(openedTest).status = "approved";
|
|
20968
|
-
recalcSuiteStatuses(
|
|
21240
|
+
recalcSuiteStatuses(tests, getTestPath(get2(openedTest)));
|
|
20969
21241
|
}
|
|
20970
21242
|
}
|
|
20971
21243
|
return true;
|
|
@@ -20981,7 +21253,7 @@ function App($$anchor, $$props) {
|
|
|
20981
21253
|
async function handleApproveAllTests() {
|
|
20982
21254
|
const approvalResult = await $$props.onApproveAll();
|
|
20983
21255
|
if (!isBulkApprovalOptimisticSafe(approvalResult)) return;
|
|
20984
|
-
getAllTests(
|
|
21256
|
+
getAllTests(tests).forEach((test) => {
|
|
20985
21257
|
if (!test.results?.length) return;
|
|
20986
21258
|
const lastIdx = test.results.length - 1;
|
|
20987
21259
|
const lastResult = test.results[lastIdx];
|
|
@@ -20989,7 +21261,7 @@ function App($$anchor, $$props) {
|
|
|
20989
21261
|
test.approved = Object.fromEntries(Object.keys(lastResult.images).map((name) => [name, lastIdx]));
|
|
20990
21262
|
test.status = "approved";
|
|
20991
21263
|
});
|
|
20992
|
-
recalcAllSuiteStatuses(
|
|
21264
|
+
recalcAllSuiteStatuses(tests);
|
|
20993
21265
|
}
|
|
20994
21266
|
function handleStart() {
|
|
20995
21267
|
}
|
|
@@ -21020,24 +21292,46 @@ function App($$anchor, $$props) {
|
|
|
21020
21292
|
}
|
|
21021
21293
|
const wsProtocol = location.protocol === "https:" ? "wss:" : "ws:";
|
|
21022
21294
|
const ws = new WebSocket(`${wsProtocol}//${location.host}`);
|
|
21023
|
-
|
|
21024
|
-
const refresh = async () => {
|
|
21295
|
+
const handleMessage = (event2) => {
|
|
21025
21296
|
try {
|
|
21026
|
-
const
|
|
21027
|
-
const
|
|
21028
|
-
|
|
21029
|
-
|
|
21030
|
-
set(tests, newTree, true);
|
|
21297
|
+
const raw = JSON.parse(event2.data);
|
|
21298
|
+
const msg = safeParse3(WebSocketMessageSchema, raw);
|
|
21299
|
+
if (msg === null) return;
|
|
21300
|
+
applyClientMessage(msg);
|
|
21031
21301
|
} catch {
|
|
21032
21302
|
}
|
|
21033
21303
|
};
|
|
21034
|
-
|
|
21035
|
-
|
|
21036
|
-
|
|
21304
|
+
const applyClientMessage = (msg) => {
|
|
21305
|
+
switch (msg.type) {
|
|
21306
|
+
case "test-begin":
|
|
21307
|
+
case "test-update": {
|
|
21308
|
+
const current = collectTestsById(tests);
|
|
21309
|
+
current[msg.data.id] = msg.data;
|
|
21310
|
+
syncTreeState(tests, current);
|
|
21311
|
+
break;
|
|
21312
|
+
}
|
|
21313
|
+
case "run-end": {
|
|
21314
|
+
if (msg.data.removedTestIds.length === 0) break;
|
|
21315
|
+
const current = collectTestsById(tests);
|
|
21316
|
+
const next2 = {};
|
|
21317
|
+
const removed = new Set(msg.data.removedTestIds);
|
|
21318
|
+
for (const [id, data] of Object.entries(current)) {
|
|
21319
|
+
if (!removed.has(id)) next2[id] = data;
|
|
21320
|
+
}
|
|
21321
|
+
syncTreeState(tests, next2);
|
|
21322
|
+
break;
|
|
21323
|
+
}
|
|
21324
|
+
case "sync": {
|
|
21325
|
+
syncTreeState(tests, msg.data.tests);
|
|
21326
|
+
break;
|
|
21327
|
+
}
|
|
21328
|
+
case "approve":
|
|
21329
|
+
break;
|
|
21330
|
+
}
|
|
21037
21331
|
};
|
|
21332
|
+
ws.onmessage = handleMessage;
|
|
21038
21333
|
return () => {
|
|
21039
21334
|
ws.close();
|
|
21040
|
-
clearTimeout(timer);
|
|
21041
21335
|
};
|
|
21042
21336
|
});
|
|
21043
21337
|
var div = root8();
|
|
@@ -21046,7 +21340,7 @@ function App($$anchor, $$props) {
|
|
|
21046
21340
|
let $0 = user_derived(() => get2(openedTest)?.id);
|
|
21047
21341
|
Sidebar(node, {
|
|
21048
21342
|
get tests() {
|
|
21049
|
-
return
|
|
21343
|
+
return tests;
|
|
21050
21344
|
},
|
|
21051
21345
|
get selectedId() {
|
|
21052
21346
|
return get2($0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report-utils.d.ts","sourceRoot":"","sources":["../src/report-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"report-utils.d.ts","sourceRoot":"","sources":["../src/report-utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAMhE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAUzD;AASD,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,kBAAkB,EAAE,SAAS,qBAAqB,EAAE,GAAG,SAAS,GAC/D,SAAS,MAAM,EAAE,CAEnB;AAED,wBAAgB,sBAAsB,CACpC,kBAAkB,EAAE,SAAS,qBAAqB,EAAE,GAAG,SAAS,GAC/D,SAAS,qBAAqB,EAAE,GAAG,SAAS,CAE9C;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACvC,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CASjC;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,UAAU,EAAE,EACzB,kBAAkB,SAAkB,GACnC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkCjC;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAWrF"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { AttachmentData } from './reporter-utils.ts';
|
|
2
|
-
import {
|
|
2
|
+
import type { ResolvedBaselineTarget } from './snapshot-path-resolver.ts';
|
|
3
3
|
export type RunEvent = {
|
|
4
4
|
type: 'test-begin' | 'test-end' | 'run-end';
|
|
5
5
|
data: unknown;
|
|
6
6
|
};
|
|
7
|
-
export type BaselineResolverInput = Parameters<typeof resolveBaselineTargets>[0];
|
|
8
|
-
export type ResolvedBaselineTarget = ReturnType<typeof resolveBaselineTargets>[number];
|
|
9
7
|
export declare function encodeArtifactPathSegment(segment: string): string;
|
|
10
8
|
export declare function safeArtifactPath(name: string): string;
|
|
11
9
|
export declare function sanitizeId(id: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter-artifact-ops.d.ts","sourceRoot":"","sources":["../src/reporter-artifact-ops.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"reporter-artifact-ops.d.ts","sourceRoot":"","sources":["../src/reporter-artifact-ops.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAOzE,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAA;AAErF,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMjE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,sBAAsB,EAC9B,gBAAgB,EAAE,cAAc,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;IAAE,WAAW,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,GAC/E,OAAO,CAAC,cAAc,EAAE,CAAC,CAoC3B;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,QAAQ,EAAE,EACrB,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,QAAQ,EAAE,EACrB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAOf"}
|