@allurereport/web-awesome 3.0.0-beta.10 → 3.0.0-beta.11
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/dist/multi/{141.app-d01d0c66.js → 141.app-f4b5d260.js} +1 -1
- package/dist/multi/{222.app-d01d0c66.js → 222.app-f4b5d260.js} +1 -1
- package/dist/multi/335.app-f4b5d260.js +1 -0
- package/dist/multi/{34.app-d01d0c66.js → 34.app-f4b5d260.js} +1 -1
- package/dist/multi/{349.app-d01d0c66.js → 349.app-f4b5d260.js} +1 -1
- package/dist/multi/378.app-f4b5d260.js +1 -0
- package/dist/multi/{406.app-d01d0c66.js → 406.app-f4b5d260.js} +1 -1
- package/dist/multi/457.app-f4b5d260.js +1 -0
- package/dist/multi/{53.app-d01d0c66.js → 53.app-f4b5d260.js} +1 -1
- package/dist/multi/{584.app-d01d0c66.js → 584.app-f4b5d260.js} +1 -1
- package/dist/multi/{690.app-d01d0c66.js → 690.app-f4b5d260.js} +1 -1
- package/dist/multi/{747.app-d01d0c66.js → 747.app-f4b5d260.js} +1 -1
- package/dist/multi/{767.app-d01d0c66.js → 767.app-f4b5d260.js} +1 -1
- package/dist/multi/{816.app-d01d0c66.js → 816.app-f4b5d260.js} +1 -1
- package/dist/multi/{83.app-d01d0c66.js → 83.app-f4b5d260.js} +1 -1
- package/dist/multi/{873.app-d01d0c66.js → 873.app-f4b5d260.js} +1 -1
- package/dist/multi/{920.app-d01d0c66.js → 920.app-f4b5d260.js} +1 -1
- package/dist/multi/{991.app-d01d0c66.js → 991.app-f4b5d260.js} +1 -1
- package/dist/multi/app-f4b5d260.js +2 -0
- package/dist/multi/{app-d01d0c66.js.LICENSE.txt → app-f4b5d260.js.LICENSE.txt} +0 -8
- package/dist/multi/manifest.json +20 -20
- package/dist/multi/{styles-d01d0c66.css → styles-f4b5d260.css} +32 -30
- package/dist/single/app-b182550e.js +2 -0
- package/dist/single/{app-6596cb08.js.LICENSE.txt → app-b182550e.js.LICENSE.txt} +0 -8
- package/dist/single/manifest.json +1 -1
- package/package.json +4 -4
- package/src/assets/scss/palette.scss +391 -391
- package/src/assets/scss/theme.scss +9 -1
- package/src/assets/scss/vars.scss +0 -1
- package/src/components/BaseLayout/styles.scss +10 -2
- package/src/components/EnvironmentPicker/index.tsx +51 -0
- package/src/components/EnvironmentPicker/styles.scss +9 -0
- package/src/components/Footer/FooterLogo.tsx +1 -2
- package/src/components/Header/index.tsx +4 -2
- package/src/components/LanguagePicker/index.tsx +1 -1
- package/src/components/MainReport/styles.scss +2 -1
- package/src/components/Metadata/index.tsx +6 -4
- package/src/components/MetadataButton/index.tsx +12 -4
- package/src/components/MetadataButton/styles.scss +3 -0
- package/src/components/ReportBody/index.tsx +3 -2
- package/src/components/ReportHeader/ReportHeaderLogo.tsx +6 -2
- package/src/components/ReportHeader/ReportHeaderPie.tsx +1 -2
- package/src/components/ReportMetadata/MetadataSummary.tsx +53 -63
- package/src/components/ReportMetadata/index.tsx +50 -3
- package/src/components/SideBySide/styles.scss +2 -3
- package/src/components/SplitLayout/index.tsx +2 -2
- package/src/components/SplitLayout/styles.scss +2 -1
- package/src/components/TestResult/TestStepsEmpty/index.tsx +2 -2
- package/src/components/TestResult/{TestResultAttachmentsView → TrAttachmentsView}/index.tsx +4 -4
- package/src/components/TestResult/{TestResultDescription → TrDescription}/index.tsx +2 -2
- package/src/components/TestResult/{TestResultDropdown → TrDropdown}/index.tsx +1 -1
- package/src/components/TestResult/{TestResultEmpty → TrEmpty}/index.tsx +6 -6
- package/src/components/TestResult/TrEnvironmentItem/index.tsx +82 -0
- package/src/components/TestResult/TrEnvironmentItem/styles.scss +60 -0
- package/src/components/TestResult/TrEnvironmentsView/index.tsx +64 -0
- package/src/components/TestResult/TrEnvironmentsView/styles.scss +11 -0
- package/src/components/TestResult/TrError/TrDiff.tsx +3 -5
- package/src/components/TestResult/TrError/index.tsx +21 -6
- package/src/components/TestResult/TrError/styles.scss +92 -2
- package/src/components/TestResult/{TestResultHeader/TestResultBreadcrumbs.tsx → TrHeader/TrBreadcrumbs.tsx} +3 -3
- package/src/components/TestResult/{TestResultHeader → TrHeader}/index.tsx +6 -4
- package/src/components/TestResult/{TestResultHistory/TestResultHistoryItem.tsx → TrHistory/TrHistoryItem.tsx} +3 -3
- package/src/components/TestResult/{TestResultHistory → TrHistory}/index.tsx +5 -5
- package/src/components/TestResult/{TestResultInfo/TestResultInfoStatuses.tsx → TrInfo/TrInfoStatuses.tsx} +1 -1
- package/src/components/TestResult/{TestResultInfo → TrInfo}/index.tsx +37 -23
- package/src/components/TestResult/{TestResultLinks → TrLinks}/index.tsx +6 -6
- package/src/components/TestResult/{TestResultMetadata → TrMetadata}/index.tsx +4 -4
- package/src/components/TestResult/{TestResultNavigation → TrNavigation}/index.tsx +3 -2
- package/src/components/TestResult/TrOverview.tsx +47 -0
- package/src/components/TestResult/{TestResultParameters → TrParameters}/index.tsx +2 -2
- package/src/components/TestResult/{TestResultPrevStatuses → TrPrevStatuses}/index.tsx +6 -6
- package/src/components/TestResult/TrPwTraces/PwTrace.tsx +34 -0
- package/src/components/TestResult/TrPwTraces/PwTraceButton.tsx +33 -0
- package/src/components/TestResult/TrPwTraces/index.tsx +29 -0
- package/src/components/TestResult/TrPwTraces/styles.scss +20 -0
- package/src/components/TestResult/{TestResultRetriesView/TestResultRetriesItem.tsx → TrRetriesView/TrRetriesItem.tsx} +3 -3
- package/src/components/TestResult/{TestResultRetriesView → TrRetriesView}/index.tsx +4 -6
- package/src/components/TestResult/{TestResultSetup → TrSetup}/index.tsx +11 -11
- package/src/components/TestResult/{TestResultSeverity → TrSeverity}/index.tsx +1 -1
- package/src/components/TestResult/{TestResultStatus → TrStatus}/index.tsx +3 -2
- package/src/components/TestResult/{TestResultSteps/testResultAttachment.tsx → TrSteps/TrAttachment.tsx} +10 -7
- package/src/components/TestResult/{TestResultSteps/testResultAttachmentInfo.tsx → TrSteps/TrAttachmentInfo.tsx} +8 -8
- package/src/components/TestResult/{TestResultSteps/testResultStep.tsx → TrSteps/TrStep.tsx} +22 -13
- package/src/components/TestResult/{TestResultSteps/testResultStepInfo.tsx → TrSteps/TrStepInfo.tsx} +2 -2
- package/src/components/TestResult/{TestResultSteps → TrSteps}/index.tsx +8 -8
- package/src/components/TestResult/{TestResultSteps → TrSteps}/styles.scss +2 -1
- package/src/components/TestResult/{TestResultSteps → TrSteps}/wrongAttachment.tsx +1 -1
- package/src/components/TestResult/{TestResultTabs → TrTabs}/index.tsx +6 -6
- package/src/components/TestResult/{TestResultTeardown → TrTeardown}/index.tsx +11 -11
- package/src/components/TestResult/index.tsx +42 -30
- package/src/components/TestResult/styles.scss +2 -1
- package/src/components/Tree/index.tsx +94 -15
- package/src/components/Tree/styles.scss +16 -1
- package/src/i18n/constants.ts +3 -3
- package/src/i18n/locales/az.json +12 -2
- package/src/i18n/locales/de.json +11 -2
- package/src/i18n/locales/en.json +11 -2
- package/src/i18n/locales/es.json +11 -2
- package/src/i18n/locales/fr.json +11 -2
- package/src/i18n/locales/he.json +11 -2
- package/src/i18n/locales/{am.json → hy.json} +11 -2
- package/src/i18n/locales/it.json +11 -2
- package/src/i18n/locales/ja.json +11 -2
- package/src/i18n/locales/ka.json +11 -2
- package/src/i18n/locales/kr.json +11 -2
- package/src/i18n/locales/nl.json +11 -2
- package/src/i18n/locales/pl.json +11 -2
- package/src/i18n/locales/pt.json +10 -2
- package/src/i18n/locales/ru.json +11 -2
- package/src/i18n/locales/sv.json +11 -2
- package/src/i18n/locales/tr.json +11 -2
- package/src/i18n/locales/zh.json +11 -2
- package/src/index.tsx +36 -33
- package/src/stores/chart.ts +3 -3
- package/src/stores/env.ts +88 -0
- package/src/stores/locale.ts +2 -1
- package/src/stores/stats.ts +52 -7
- package/src/stores/testResults.ts +6 -6
- package/src/stores/tree.ts +48 -17
- package/src/stores/variables.ts +38 -0
- package/dist/multi/335.app-d01d0c66.js +0 -1
- package/dist/multi/378.app-d01d0c66.js +0 -1
- package/dist/multi/476.app-d01d0c66.js +0 -1
- package/dist/multi/app-d01d0c66.js +0 -2
- package/dist/single/app-6596cb08.js +0 -2
- package/src/components/ReportLogo/index.tsx +0 -16
- package/src/components/ReportLogo/styles.scss +0 -20
- package/src/components/ReportLogoFull/index.tsx +0 -20
- package/src/components/ReportLogoFull/styles.scss +0 -7
- package/src/components/TestResult/TestResultOverview.tsx +0 -43
- /package/src/components/TestResult/{TestResultAttachmentsView → TrAttachmentsView}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultDescription → TrDescription}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultDropdown → TrDropdown}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultEmpty → TrEmpty}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultHeader → TrHeader}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultHistory → TrHistory}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultInfo → TrInfo}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultLinks → TrLinks}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultMetadata → TrMetadata}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultNavigation → TrNavigation}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultParameters → TrParameters}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultPrevStatuses → TrPrevStatuses}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultRetriesView → TrRetriesView}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultSeverity → TrSeverity}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultStatus → TrStatus}/styles.scss +0 -0
- /package/src/components/TestResult/{TestResultTabs → TrTabs}/styles.scss +0 -0
package/src/index.tsx
CHANGED
|
@@ -3,18 +3,19 @@ import { Spinner, SvgIcon, allureIcons } from "@allurereport/web-components";
|
|
|
3
3
|
import "@allurereport/web-components/index.css";
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import { render } from "preact";
|
|
6
|
-
import { useEffect } from "preact/hooks";
|
|
6
|
+
import { useEffect, useState } from "preact/hooks";
|
|
7
7
|
import "@/assets/scss/index.scss";
|
|
8
8
|
import { BaseLayout } from "@/components/BaseLayout";
|
|
9
9
|
import { ModalComponent } from "@/components/Modal";
|
|
10
10
|
import { SplitLayout } from "@/components/SplitLayout";
|
|
11
|
-
import {
|
|
11
|
+
import { fetchEnvStats, fetchReportStats, getLocale, getTheme, waitForI18next } from "@/stores";
|
|
12
12
|
import { fetchPieChartData } from "@/stores/chart";
|
|
13
|
+
import { currentEnvironment, environmentsStore, fetchEnvironments } from "@/stores/env";
|
|
13
14
|
import { fetchEnvInfo } from "@/stores/envInfo";
|
|
14
15
|
import { getLayout, isLayoutLoading, isSplitMode } from "@/stores/layout";
|
|
15
16
|
import { handleHashChange, route } from "@/stores/router";
|
|
16
17
|
import { fetchTestResult, fetchTestResultNav } from "@/stores/testResults";
|
|
17
|
-
import {
|
|
18
|
+
import { fetchEnvTreesData } from "@/stores/tree";
|
|
18
19
|
import { isMac } from "@/utils/isMac";
|
|
19
20
|
import * as styles from "./styles.scss";
|
|
20
21
|
|
|
@@ -26,28 +27,40 @@ const Loader = () => {
|
|
|
26
27
|
</div>
|
|
27
28
|
);
|
|
28
29
|
};
|
|
30
|
+
|
|
29
31
|
const App = () => {
|
|
32
|
+
const [prefetched, setPrefetched] = useState(false);
|
|
30
33
|
const { id: testResultId } = route.value;
|
|
34
|
+
const prefetchData = async () => {
|
|
35
|
+
const fns = [ensureReportDataReady, fetchReportStats, fetchPieChartData, fetchEnvironments, fetchEnvInfo];
|
|
31
36
|
|
|
32
|
-
useEffect(() => {
|
|
33
37
|
if (globalThis) {
|
|
34
|
-
getLocale();
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
fns.unshift(getLocale, getLayout as () => Promise<void>, getTheme as () => Promise<void>);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
await waitForI18next;
|
|
42
|
+
await Promise.all(fns.map((fn) => fn(currentEnvironment.value)));
|
|
43
|
+
|
|
44
|
+
if (currentEnvironment.value) {
|
|
45
|
+
await fetchEnvTreesData([currentEnvironment.value]);
|
|
46
|
+
} else {
|
|
47
|
+
await fetchEnvTreesData(environmentsStore.value.data);
|
|
48
|
+
await fetchEnvStats(environmentsStore.value.data);
|
|
37
49
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
50
|
+
|
|
51
|
+
setPrefetched(true);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
prefetchData();
|
|
56
|
+
}, [currentEnvironment.value]);
|
|
44
57
|
|
|
45
58
|
useEffect(() => {
|
|
46
59
|
if (testResultId) {
|
|
47
60
|
fetchTestResult(testResultId);
|
|
48
|
-
fetchTestResultNav();
|
|
61
|
+
fetchTestResultNav(currentEnvironment.value);
|
|
49
62
|
}
|
|
50
|
-
}, [testResultId]);
|
|
63
|
+
}, [testResultId, currentEnvironment]);
|
|
51
64
|
|
|
52
65
|
useEffect(() => {
|
|
53
66
|
handleHashChange();
|
|
@@ -60,9 +73,13 @@ const App = () => {
|
|
|
60
73
|
|
|
61
74
|
return (
|
|
62
75
|
<div className={styles.main}>
|
|
63
|
-
<Loader />
|
|
64
|
-
{
|
|
65
|
-
|
|
76
|
+
{!prefetched && <Loader />}
|
|
77
|
+
{prefetched && (
|
|
78
|
+
<>
|
|
79
|
+
{isSplitMode.value ? <SplitLayout /> : <BaseLayout />}
|
|
80
|
+
<ModalComponent />
|
|
81
|
+
</>
|
|
82
|
+
)}
|
|
66
83
|
</div>
|
|
67
84
|
);
|
|
68
85
|
};
|
|
@@ -79,18 +96,4 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
79
96
|
}
|
|
80
97
|
});
|
|
81
98
|
|
|
82
|
-
(
|
|
83
|
-
await waitForI18next;
|
|
84
|
-
if (globalThis) {
|
|
85
|
-
await getLocale();
|
|
86
|
-
getLayout();
|
|
87
|
-
getTheme();
|
|
88
|
-
}
|
|
89
|
-
await ensureReportDataReady();
|
|
90
|
-
await fetchStats();
|
|
91
|
-
await fetchEnvInfo();
|
|
92
|
-
await fetchPieChartData();
|
|
93
|
-
await fetchTreeData();
|
|
94
|
-
|
|
95
|
-
render(<App />, rootElement);
|
|
96
|
-
})();
|
|
99
|
+
render(<App />, rootElement);
|
package/src/stores/chart.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fetchReportJsonData } from "@allurereport/web-commons";
|
|
2
2
|
import { signal } from "@preact/signals";
|
|
3
|
-
import { StoreSignalState } from "@/stores/types";
|
|
3
|
+
import type { StoreSignalState } from "@/stores/types";
|
|
4
4
|
|
|
5
5
|
export const pieChartStore = signal<StoreSignalState<any>>({
|
|
6
6
|
loading: true,
|
|
@@ -8,7 +8,7 @@ export const pieChartStore = signal<StoreSignalState<any>>({
|
|
|
8
8
|
data: undefined,
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
-
export const fetchPieChartData = async () => {
|
|
11
|
+
export const fetchPieChartData = async (env: string) => {
|
|
12
12
|
pieChartStore.value = {
|
|
13
13
|
...pieChartStore.value,
|
|
14
14
|
loading: true,
|
|
@@ -16,7 +16,7 @@ export const fetchPieChartData = async () => {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
|
-
const res = await fetchReportJsonData("widgets/
|
|
19
|
+
const res = await fetchReportJsonData(env ? `widgets/${env}/pie_chart.json` : "widgets/pie_chart.json");
|
|
20
20
|
|
|
21
21
|
pieChartStore.value = {
|
|
22
22
|
data: res,
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type TestEnvGroup } from "@allurereport/core-api";
|
|
2
|
+
import { fetchReportJsonData } from "@allurereport/web-commons";
|
|
3
|
+
import { effect, signal } from "@preact/signals";
|
|
4
|
+
import type { StoreSignalState } from "@/stores/types";
|
|
5
|
+
import { loadFromLocalStorage } from "@/utils/loadFromLocalStorage";
|
|
6
|
+
|
|
7
|
+
export const environmentsStore = signal<StoreSignalState<string[]>>({
|
|
8
|
+
loading: false,
|
|
9
|
+
error: undefined,
|
|
10
|
+
data: [],
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const testEnvGroupsStore = signal<StoreSignalState<Record<string, TestEnvGroup>>>({
|
|
14
|
+
loading: false,
|
|
15
|
+
error: undefined,
|
|
16
|
+
data: {},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const collapsedEnvironments = signal<string[]>(loadFromLocalStorage<string[]>("collapsedEnvironments", []));
|
|
20
|
+
|
|
21
|
+
export const currentEnvironment = signal<string>(loadFromLocalStorage<string>("currentEnvironment", ""));
|
|
22
|
+
|
|
23
|
+
export const setCurrentEnvironment = (env: string) => {
|
|
24
|
+
currentEnvironment.value = env;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const fetchEnvironments = async () => {
|
|
28
|
+
environmentsStore.value = {
|
|
29
|
+
...environmentsStore.value,
|
|
30
|
+
loading: true,
|
|
31
|
+
error: undefined,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const res = await fetchReportJsonData<string[]>("widgets/environments.json");
|
|
36
|
+
|
|
37
|
+
environmentsStore.value = {
|
|
38
|
+
data: res,
|
|
39
|
+
error: undefined,
|
|
40
|
+
loading: false,
|
|
41
|
+
};
|
|
42
|
+
} catch (e) {
|
|
43
|
+
environmentsStore.value = {
|
|
44
|
+
...environmentsStore.value,
|
|
45
|
+
error: e.message,
|
|
46
|
+
loading: false,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const fetchTestEnvGroup = async (id: string) => {
|
|
52
|
+
if (testEnvGroupsStore.value.data[id]) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
testEnvGroupsStore.value = {
|
|
57
|
+
...testEnvGroupsStore.value,
|
|
58
|
+
loading: true,
|
|
59
|
+
error: undefined,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const res = await fetchReportJsonData<TestEnvGroup | undefined>(`data/test-env-groups/${id}.json`);
|
|
64
|
+
|
|
65
|
+
testEnvGroupsStore.value = {
|
|
66
|
+
data: {
|
|
67
|
+
...testEnvGroupsStore.value.data,
|
|
68
|
+
[id]: res,
|
|
69
|
+
},
|
|
70
|
+
error: undefined,
|
|
71
|
+
loading: false,
|
|
72
|
+
};
|
|
73
|
+
} catch (e) {
|
|
74
|
+
testEnvGroupsStore.value = {
|
|
75
|
+
...testEnvGroupsStore.value,
|
|
76
|
+
error: e.message,
|
|
77
|
+
loading: false,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
effect(() => {
|
|
83
|
+
localStorage.setItem("currentEnvironment", JSON.stringify(currentEnvironment.value));
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
effect(() => {
|
|
87
|
+
localStorage.setItem("collapsedEnvironments", JSON.stringify([...collapsedEnvironments.value]));
|
|
88
|
+
});
|
package/src/stores/locale.ts
CHANGED
|
@@ -22,10 +22,11 @@ const namespaces = [
|
|
|
22
22
|
"errors",
|
|
23
23
|
"split",
|
|
24
24
|
"modal",
|
|
25
|
+
"environments",
|
|
25
26
|
];
|
|
26
27
|
|
|
27
28
|
export const currentLocale = signal<LangLocale>("en" as LangLocale);
|
|
28
|
-
export const currentLocaleIso = computed(() => LANG_LOCALE[currentLocale.value].iso);
|
|
29
|
+
export const currentLocaleIso = computed(() => LANG_LOCALE[currentLocale.value]?.iso ?? LANG_LOCALE.en.iso);
|
|
29
30
|
export const currentLocaleIsRTL = computed(() => ["ar", "he", "fa"].includes(currentLocale.value));
|
|
30
31
|
|
|
31
32
|
export const getLocale = async () => {
|
package/src/stores/stats.ts
CHANGED
|
@@ -2,8 +2,9 @@ import type { Statistic } from "@allurereport/core-api";
|
|
|
2
2
|
import { fetchReportJsonData } from "@allurereport/web-commons";
|
|
3
3
|
import { signal } from "@preact/signals";
|
|
4
4
|
import type { StoreSignalState } from "@/stores/types";
|
|
5
|
+
import type { AwesomeTree } from "../../types";
|
|
5
6
|
|
|
6
|
-
export const
|
|
7
|
+
export const reportStatsStore = signal<StoreSignalState<Statistic>>({
|
|
7
8
|
loading: true,
|
|
8
9
|
error: undefined,
|
|
9
10
|
data: {
|
|
@@ -11,26 +12,70 @@ export const statsStore = signal<StoreSignalState<Statistic>>({
|
|
|
11
12
|
},
|
|
12
13
|
});
|
|
13
14
|
|
|
14
|
-
export const
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
export const statsByEnvStore = signal<StoreSignalState<Record<string, Statistic>>>({
|
|
16
|
+
loading: true,
|
|
17
|
+
error: undefined,
|
|
18
|
+
data: {},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export const fetchReportStats = async () => {
|
|
22
|
+
reportStatsStore.value = {
|
|
23
|
+
...reportStatsStore.value,
|
|
17
24
|
loading: true,
|
|
18
25
|
error: undefined,
|
|
19
26
|
};
|
|
20
27
|
|
|
21
28
|
try {
|
|
22
|
-
const res = await fetchReportJsonData<Statistic>("widgets/
|
|
29
|
+
const res = await fetchReportJsonData<Statistic>("widgets/statistic.json");
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
reportStatsStore.value = {
|
|
25
32
|
data: res,
|
|
26
33
|
error: undefined,
|
|
27
34
|
loading: false,
|
|
28
35
|
};
|
|
29
36
|
} catch (err) {
|
|
30
|
-
|
|
37
|
+
reportStatsStore.value = {
|
|
31
38
|
data: { total: 0 },
|
|
32
39
|
error: err.message,
|
|
33
40
|
loading: false,
|
|
34
41
|
};
|
|
35
42
|
}
|
|
36
43
|
};
|
|
44
|
+
|
|
45
|
+
export const fetchEnvStats = async (envs: string[]) => {
|
|
46
|
+
const envsToFetch = envs.filter((env) => !statsByEnvStore.value.data?.[env]);
|
|
47
|
+
|
|
48
|
+
// all envs have already been fetched
|
|
49
|
+
if (envsToFetch.length === 0) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
statsByEnvStore.value = {
|
|
54
|
+
...statsByEnvStore.value,
|
|
55
|
+
loading: true,
|
|
56
|
+
error: undefined,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const data = await Promise.all(
|
|
61
|
+
envsToFetch.map((env) => fetchReportJsonData<AwesomeTree>(`widgets/${env}/statistic.json`)),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
statsByEnvStore.value = {
|
|
65
|
+
data: envs.reduce((acc, env, index) => {
|
|
66
|
+
return {
|
|
67
|
+
...acc,
|
|
68
|
+
[env]: data[index],
|
|
69
|
+
};
|
|
70
|
+
}, {}),
|
|
71
|
+
loading: false,
|
|
72
|
+
error: undefined,
|
|
73
|
+
};
|
|
74
|
+
} catch (err) {
|
|
75
|
+
statsByEnvStore.value = {
|
|
76
|
+
...statsByEnvStore.value,
|
|
77
|
+
error: err.message,
|
|
78
|
+
loading: false,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
};
|
|
@@ -3,25 +3,25 @@ import { signal } from "@preact/signals";
|
|
|
3
3
|
import { type AwesomeTestResult } from "../../types";
|
|
4
4
|
import { type StoreSignalState } from "./types";
|
|
5
5
|
|
|
6
|
-
export type
|
|
6
|
+
export type TrStoreState = Record<string, AwesomeTestResult>;
|
|
7
7
|
|
|
8
|
-
export type
|
|
8
|
+
export type TrNavStoreState = string[];
|
|
9
9
|
|
|
10
|
-
export const testResultStore = signal<StoreSignalState<
|
|
10
|
+
export const testResultStore = signal<StoreSignalState<TrStoreState>>({
|
|
11
11
|
loading: true,
|
|
12
12
|
error: undefined,
|
|
13
13
|
data: undefined,
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
export const testResultNavStore = signal<StoreSignalState<
|
|
16
|
+
export const testResultNavStore = signal<StoreSignalState<TrNavStoreState>>({
|
|
17
17
|
loading: true,
|
|
18
18
|
error: undefined,
|
|
19
19
|
data: undefined,
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
export const fetchTestResultNav = async () => {
|
|
22
|
+
export const fetchTestResultNav = async (env?: string) => {
|
|
23
23
|
try {
|
|
24
|
-
const data = await fetchReportJsonData<string[]>("widgets/nav.json");
|
|
24
|
+
const data = await fetchReportJsonData<string[]>(env ? `widgets/${env}/nav.json` : "widgets/nav.json");
|
|
25
25
|
|
|
26
26
|
testResultNavStore.value = {
|
|
27
27
|
data,
|
package/src/stores/tree.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { fetchReportJsonData } from "@allurereport/web-commons";
|
|
2
|
+
import type { RecursiveTree } from "@allurereport/web-components/global";
|
|
2
3
|
import { computed, effect, signal } from "@preact/signals";
|
|
3
4
|
import type { AwesomeStatus, AwesomeTree, AwesomeTreeGroup } from "types";
|
|
4
5
|
import type { StoreSignalState } from "@/stores/types";
|
|
@@ -16,16 +17,19 @@ export type TreeFiltersState = {
|
|
|
16
17
|
direction: TreeDirection;
|
|
17
18
|
};
|
|
18
19
|
|
|
19
|
-
export const treeStore = signal<StoreSignalState<AwesomeTree
|
|
20
|
+
export const treeStore = signal<StoreSignalState<Record<string, AwesomeTree>>>({
|
|
20
21
|
loading: true,
|
|
21
22
|
error: undefined,
|
|
22
23
|
data: undefined,
|
|
23
24
|
});
|
|
24
25
|
|
|
25
|
-
export const noTests = computed(() =>
|
|
26
|
+
export const noTests = computed(() => {
|
|
27
|
+
return Object.values(treeStore?.value?.data ?? {}).every(
|
|
28
|
+
({ leavesById }) => !leavesById || !Object.keys(leavesById).length,
|
|
29
|
+
);
|
|
30
|
+
});
|
|
26
31
|
|
|
27
|
-
const
|
|
28
|
-
export const collapsedTrees = signal(new Set(loadedFromLS as string[]));
|
|
32
|
+
export const collapsedTrees = signal(new Set(loadFromLocalStorage<string[]>("collapsedTrees", [])));
|
|
29
33
|
|
|
30
34
|
effect(() => {
|
|
31
35
|
localStorage.setItem("collapsedTrees", JSON.stringify([...collapsedTrees.value]));
|
|
@@ -66,18 +70,30 @@ effect(() => {
|
|
|
66
70
|
});
|
|
67
71
|
|
|
68
72
|
export const filteredTree = computed(() => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
return Object.entries(treeStore.value.data).reduce(
|
|
74
|
+
(acc, [key, value]) => {
|
|
75
|
+
if (!value) {
|
|
76
|
+
return acc;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const { root, leavesById, groupsById } = value;
|
|
80
|
+
const tree = createRecursiveTree({
|
|
81
|
+
group: root as AwesomeTreeGroup,
|
|
82
|
+
leavesById,
|
|
83
|
+
groupsById,
|
|
84
|
+
filterOptions: treeFiltersStore.value,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return Object.assign(acc, {
|
|
88
|
+
[key]: tree,
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
{} as Record<string, RecursiveTree>,
|
|
92
|
+
);
|
|
77
93
|
});
|
|
78
94
|
|
|
79
95
|
export const noTestsFound = computed(() => {
|
|
80
|
-
return
|
|
96
|
+
return Object.values(filteredTree.value).every(isRecursiveTreeEmpty);
|
|
81
97
|
});
|
|
82
98
|
|
|
83
99
|
export const clearTreeFilters = () => {
|
|
@@ -132,7 +148,14 @@ export const setTreeFilter = (filterKey: TreeFilters, value: boolean) => {
|
|
|
132
148
|
};
|
|
133
149
|
};
|
|
134
150
|
|
|
135
|
-
export const
|
|
151
|
+
export const fetchEnvTreesData = async (envs: string[]) => {
|
|
152
|
+
const envsToFetch = envs.filter((env) => !treeStore.value.data?.[env]);
|
|
153
|
+
|
|
154
|
+
// all envs have already been fetched
|
|
155
|
+
if (envsToFetch.length === 0) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
136
159
|
treeStore.value = {
|
|
137
160
|
...treeStore.value,
|
|
138
161
|
loading: true,
|
|
@@ -140,12 +163,20 @@ export const fetchTreeData = async () => {
|
|
|
140
163
|
};
|
|
141
164
|
|
|
142
165
|
try {
|
|
143
|
-
const
|
|
166
|
+
const data = await Promise.all(
|
|
167
|
+
envsToFetch.map((env) => fetchReportJsonData<AwesomeTree>(`widgets/${env}/tree.json`)),
|
|
168
|
+
);
|
|
144
169
|
|
|
145
170
|
treeStore.value = {
|
|
146
|
-
data:
|
|
147
|
-
|
|
171
|
+
data: envs.reduce(
|
|
172
|
+
(acc, env, index) => ({
|
|
173
|
+
...acc,
|
|
174
|
+
[env]: data[index],
|
|
175
|
+
}),
|
|
176
|
+
{},
|
|
177
|
+
),
|
|
148
178
|
loading: false,
|
|
179
|
+
error: undefined,
|
|
149
180
|
};
|
|
150
181
|
} catch (e) {
|
|
151
182
|
treeStore.value = {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { fetchReportJsonData } from "@allurereport/web-commons";
|
|
2
|
+
import { signal } from "@preact/signals";
|
|
3
|
+
import type { StoreSignalState } from "@/stores/types";
|
|
4
|
+
|
|
5
|
+
export type Variables = Record<string, any>;
|
|
6
|
+
|
|
7
|
+
export const variables = signal<StoreSignalState<Record<string, Variables>>>({
|
|
8
|
+
loading: false,
|
|
9
|
+
error: undefined,
|
|
10
|
+
data: undefined,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const fetchVariables = async (env: string = "default") => {
|
|
14
|
+
variables.value = {
|
|
15
|
+
...variables.value,
|
|
16
|
+
loading: true,
|
|
17
|
+
error: undefined,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const res = await fetchReportJsonData<string[]>(env ? `widgets/${env}/variables.json` : "widgets/variables.json");
|
|
22
|
+
|
|
23
|
+
variables.value = {
|
|
24
|
+
data: {
|
|
25
|
+
...variables.value.data,
|
|
26
|
+
[env]: res,
|
|
27
|
+
},
|
|
28
|
+
error: undefined,
|
|
29
|
+
loading: false,
|
|
30
|
+
};
|
|
31
|
+
} catch (e) {
|
|
32
|
+
variables.value = {
|
|
33
|
+
...variables.value,
|
|
34
|
+
error: e.message,
|
|
35
|
+
loading: false,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_allurereport_web_awesome=self.webpackChunk_allurereport_web_awesome||[]).push([[335],{335:function(e){e.exports=JSON.parse('{"statuses":{"passed":"успешный","failed":"неуспешный","broken":"сломанный","skipped":"пропущенный","unknown":"неизвестный","total":"все"},"testSummary":{"all":"Все тесты","flaky":"Flaky тесты","retry":"Повторные тесты","new":"Новые тесты"},"tabs":{"total":"Все"},"search":{"search":"Поиск","search-placeholder":"Название или ID"},"filters":{"more-filters":"Фильтры","enable-filter":"Включить фильтр по \\"{filter}\\"","flaky":"Нестабильные","retry":"Повторенные","new":"Новые"},"sort-by":{"sort-by-text":"Сортировать по:","sort-by-category":"Сортировать по","direction-category":"Направление"},"sort-by.values":{"order":"Порядок","alphabet":"Название","duration":"Длительность","status":"Статус"},"sort-by.directions":{"order-asc":"Поздние – Ранние","order-desc":"Ранние – Поздние","order-asc-short":"Поздние","order-desc-short":"Ранние","alphabet-asc":"Я – А","alphabet-desc":"А – Я","alphabet-asc-short":"Я – А","alphabet-desc-short":"Я – А","duration-asc":"9 – 1","duration-desc":"1 – 9","duration-asc-short":"9 – 1","duration-desc-short":"1 – 9","status-asc":"Инвертировано","status-desc":"Как в списке фильтра","status-asc-short":"Инвертировано","status-desc-short":"По обычному"},"empty":{"no-results":"Нет результатов","no-tests-found":"Результаты не найдены","clear-filters":"Очистить фильтры","no-attachments-results":"Информация о вложениях отсутствует","no-history-results":"Информация об истории отсутствует","no-retries-results":"Информация о перезапусках отсутствует","no-test-steps-results":"Нет информации о шагах тестирования","no-test-case-results":"Нет результатов тест-кейсов"},"severity":{"name":"Важность","blocker":"блокер","critical":"критическая","normal":"обычная","minor":"невысокая","trivial":"минимальная"},"execution":{"body":"Тело теста","name":"Выполнение","setup":"Подготовка","teardown":"Завершение"},"ui":{"labels":"Лейблы","metadata":"Метаданные","parameters":"Параметры","description":"Описание","links":"Ссылки","overview":"Обзор","history":"История","attachments":"Вложения","retries":"Перезапуски","error":"Ошибка","goToStep":"Перейти к шагу","showLess":"Показать меньше","showMore":"Показать больше","copy":"Скопировать","at":"в"},"controls":{"newTabAttachment":"Открыть в новой вкладке","downloadAttachment":"Загрузить вложение","nextTR":"Следующий тест","prevTR":"Предыдущий тест","backto":"Вернуться на","clipboard":"Скопировать в буфер обмена","clipboardError":"Ошибка. Скорее всего ваш браузер не поддерживает данную функциональность","clipboardSuccess":"Значение успешно скопировано","collapse":"Свернуть","expand":"Развернуть","fullscreen":"На весь экран","language":"Сменить язык","openInNewTab":"Открыть в новой вкладке","openPreview":"Открыть предпросмотр","noSelectedTR":"Нет выбранного результата теста","comparison":"Сравнение","showDiff":"Показать разницу","viewMode":"Режим просмотра","unified":"Объединённый","side-by-side":"Рядом","compareBy":"Сравнивать по","chars":"символам","words":"словам","lines":"строкам","actual":"Фактическое","expected":"Ожидаемое"},"errors":{"missedAttachment":"Вложение не найдено"}}')}}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_allurereport_web_awesome=self.webpackChunk_allurereport_web_awesome||[]).push([[378],{378:function(e){e.exports=JSON.parse('{"statuses":{"passed":"წარმატებული","failed":"წარუმატებელი","broken":"დამტვრეული","skipped":"გამოტოვებული","unknown":"უცნობი","total":"ჯამი","flakyTests":"არასტაბილური","newTests":"ახალი","retryTests":"ხელახალი ცდა"},"testSummary":{"all":"ყველა ტესტი","flaky":"არასტაბილური ტესტი","retry":"ხელახალი ტესტი","new":"ახალი ტესტი"},"tabs":{"total":"ყველა"},"search":{"search":"ძებნა","search-placeholder":"სახელი ან ID"},"filters":{"more-filters":"დამატებითი ფილტრები","enable-filter":"ჩართეთ ფილტრი \\"{filter}\\"","flaky":"არასტაბილური","retry":"ხელახალი","new":"ახალი"},"sort-by":{"sort-by-text":"დალაგება:","sort-by-category":"დალაგება","direction-category":"მიმართულება"},"sort-by.values":{"order":"შეკვეთა","alphabet":"ანბანი","duration":"ხანგრძლივობა","status":"სტატუსი"},"sort-by.directions":{"order-desc":"ბოლო – პირველი","order-asc":"პირველი – ბოლო","order-asc-short":"პირველი","order-desc-short":"ბოლო","alphabet-asc":"ა – ჰ","alphabet-desc":"ჰ – ა","alphabet-asc-short":"ა – ჰ","alphabet-desc-short":"ჰ – ა","duration-asc":"1 – 9","duration-desc":"9 – 1","duration-asc-short":"1 – 9","duration-desc-short":"9 – 1","status-asc":"როგორც ფილტრის სიაში","status-desc":"შებრუნებული","status-asc-short":"ჩვეულებრივი","status-desc-short":"შებრუნებული"},"empty":{"no-results":"შედეგები არ არის","no-tests-found":"შედეგები არ მოიძებნა","clear-filters":"ფილტრების გასუფთავება","no-attachments-results":"დანართების ინფორმაცია არ არის ხელმისაწვდომი","no-history-results":"ისტორიის ინფორმაცია არ არის ხელმისაწვდომი","no-retries-results":"ხელახალი ცდების ინფორმ���ცია არ არის ხელმისაწვდომი","no-test-steps-results":"ტესტის ნაბიჯების ინფორმაცია ხელმისაწვდომი არ არის","no-test-case-results":"ტესტის შემთხვევის შედეგები არ არის"},"severity":{"blocker":"ბლოკერი","critical":"კრიტიკული","normal":"ჩვეულებრივი","minor":"მნიშვნელობა","trivial":"უმნიშვნელო"},"execution":{"name":"შესრულება","body":"ტესტის შინაარსი","setup":"მომზადება","teardown":"დასრულება"},"ui":{"labels":"ლეიბლები","metadata":"მეტამონაცემები","parameters":"პარამეტრები","description":"აღწერა","links":"ბმულები","overview":"მიმოხილვა","history":"ისტორია","attachments":"დანართები","retries":"ხელახალი ცდები","error":"შეცდომა","goToStep":"გადადით საფეხურზე","showLess":"ნაკლების ჩვენება","showMore":"მეტის ჩვენება","copy":"კოპირება","at":"ზე"},"controls":{"newTabAttachment":"დანართის გახსნა ახალ ჩანართში","nextTR":"შემდეგი ტესტის შედეგი","prevTR":"წინა ტესტის შედეგი","downloadAttachment":"დანართის ჩამოტვირთვა","backto":"უკან დაბრუნება","clipboard":"კოპირება ბუფერში","clipboardError":"ბუფერში კოპირება ვერ მოხერხდა. შესაძლოა, ფუნქცია არ იყოს მხარდაჭერილი თქვენს ბრაუზერში","clipboardSuccess":"წარმატებით დაკოპირდა","collapse":"ჩაკეცვა","expand":"გახსნა","fullscreen":"სრულ ეკრანზე","language":"ენის შეცვლა","openInNewTab":"გახსნა ახალ ჩანართში","openPreview":"გახსენი წინასწარი დათვალიერება","noSelectedTR":"არჩეული ტესტის შედეგი არ არის","comparison":"შედარება","showDiff":"მაჩვენე განსხვავება","viewMode":"ნახვის რეჟიმი","unified":"გაერთიანებული","side-by-side":"გვერდიგვერდ","compareBy":"შედარება","chars":"სიმბოლოები","words":"სიტყვები","lines":"ხაზები","actual":"ნამდვილი","expected":"მოსალოდნელი"},"errors":{"missedAttachment":"დანართი ვერ მოიძებნა"}}')}}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_allurereport_web_awesome=self.webpackChunk_allurereport_web_awesome||[]).push([[476],{476:function(e){e.exports=JSON.parse('{"statuses":{"passed":"անցած","failed":"ձախողված","broken":"կոտրված","skipped":"բաց թողնված","unknown":"անհայտ","total":"ընդհանուր","flakyTests":"անհուսալի","newTests":"նոր","retryTests":"կրկնություն"},"testSummary":{"all":"Բոլոր թեստերը","flaky":"Անհուսալի թեստեր","retry":"Կրկնված թեստեր","new":"Նոր թեստեր"},"tabs":{"total":"Բոլոր"},"search":{"search":"Որոնում","search-placeholder":"Անվանում կամ ID"},"filters":{"more-filters":"Լրացուցիչ ֆիլտրեր","enable-filter":"Միացնել \\"{filter}\\" ֆիլտրը","flaky":"Անհուսալի","retry":"Կրկնություն","new":"Նոր"},"sort-by":{"sort-by-text":"Դասավորել ըստ:","sort-by-category":"Դասավորել ըստ","direction-category":"Ուղղություն"},"sort-by.values":{"order":"Կարգ","alphabet":"Այբուբեն","duration":"Տևողություն","status":"Կարգավիճակ"},"sort-by.directions":{"order-desc":"Վերջինը – Առաջինը","order-asc":"Առաջինը – Վերջինը","order-asc-short":"Առաջինը","order-desc-short":"Վերջինը","alphabet-asc":"Ա – Ֆ","alphabet-desc":"Ֆ – Ա","alphabet-asc-short":"Ա – Ֆ","alphabet-desc-short":"Ֆ – Ա","duration-asc":"1 – 9","duration-desc":"9 – 1","duration-asc-short":"1 – 9","duration-desc-short":"9 – 1","status-asc":"Ինչպես ֆիլտրերի ցանկում","status-desc":"Հակադարձված","status-asc-short":"Սովորական","status-desc-short":"Հակադարձված"},"empty":{"no-results":"Ոչ մի արդյունք","no-tests-found":"Արդյունքներ չեն գտնվել","clear-filters":"Մաքրել ֆիլտրները","no-attachments-results":"Կցորդների մասին տեղեկություններ չկան","no-history-results":"Պատմության մասին տեղեկություններ չկան","no-retries-results":"Կրկնությունների մասին տեղեկություններ չկան","no-test-steps-results":"Թեստի քայլերի մասին տեղեկատվությունը հասանելի չէ։","no-test-case-results":"Թեստի դեպքերի արդյունքներ չկան։"},"severity":{"blocker":"արգելափակում","critical":"կրիտիկական","normal":"նորմալ","minor":"աննշան","trivial":"աննշան"},"execution":{"name":"Կատարում","body":"Թեստի մարմին","setup":"Պատրաստում","teardown":"Ավարտում"},"ui":{"labels":"Պիտակներ","metadata":"Մետատվյալներ","parameters":"Պարամետրեր","description":"Նկարագրություն","links":"Հղումներ","overview":"Ակնարկ","history":"Պատմություն","attachments":"Կցորդներ","retries":"Կրկնություններ","error":"Սխալ","goToStep":"Գնալ քայլին","showLess":"Ցուցադրել պակաս","showMore":"Ցուցադրել ավելին","copy":"Պատճենել","at":"է"},"controls":{"newTabAttachment":"Բացել նոր ներդիրում","nextTR":"Հաջորդ թեստի արդյունքը","prevTR":"Նախորդ թեստի արդյունքը","downloadAttachment":"Ներբեռնել կցորդը","backto":"Վերադառնալ","clipboard":"Պատճենել սեղմատախտակին","clipboardError":"Սխալ. Հավանաբար ձեր զննարկիչը չի աջակցում այս գործառույթին","clipboardSuccess":"Հաջողությամբ պատճենվեց","collapse":"Կծկել","expand":"Ընդլայնել","fullscreen":"Լրիվ էկրան","language":"Փոխել լեզուն","openInNewTab":"Բացել նոր ներդիրում","openPreview":"Բացել նախադիտումը","noSelectedTR":"Ընտրված թեստի արդյունք չկա","comparison":"Համեմատություն","showDiff":"Ցուցադրել տարբերությունը","viewMode":"Դիտման ռեժիմ","unified":"Միավորված","side-by-side":"Կողք կողքի","compareBy":"Համեմատել ըստ","chars":"սիմվոլներ","words":"բառեր","lines":"տողեր","actual":"Իրական","expected":"Սպասվող"},"errors":{"missedAttachment":"Կցորդը չի գտնվել"}}')}}]);
|