@allurereport/web-awesome 3.0.0-beta.3 → 3.0.0-beta.5
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/.eslintrc.cjs +1 -1
- package/CONTRIBUTING.md +34 -0
- package/dist/multi/{141.app-b6362ca0.js → 141.app-71d7f77e.js} +1 -1
- package/dist/multi/222.app-71d7f77e.js +1 -0
- package/dist/multi/335.app-71d7f77e.js +1 -0
- package/dist/multi/{34.app-b6362ca0.js → 34.app-71d7f77e.js} +1 -1
- package/dist/multi/349.app-71d7f77e.js +1 -0
- package/dist/multi/378.app-71d7f77e.js +1 -0
- package/dist/multi/{406.app-b6362ca0.js → 406.app-71d7f77e.js} +1 -1
- package/dist/multi/476.app-71d7f77e.js +1 -0
- package/dist/multi/{53.app-b6362ca0.js → 53.app-71d7f77e.js} +1 -1
- package/dist/multi/{584.app-b6362ca0.js → 584.app-71d7f77e.js} +1 -1
- package/dist/multi/690.app-71d7f77e.js +1 -0
- package/dist/multi/{747.app-b6362ca0.js → 747.app-71d7f77e.js} +1 -1
- package/dist/multi/{767.app-b6362ca0.js → 767.app-71d7f77e.js} +1 -1
- package/dist/multi/{816.app-b6362ca0.js → 816.app-71d7f77e.js} +1 -1
- package/dist/multi/83.app-71d7f77e.js +1 -0
- package/dist/multi/{873.app-b6362ca0.js → 873.app-71d7f77e.js} +1 -1
- package/dist/multi/{920.app-b6362ca0.js → 920.app-71d7f77e.js} +1 -1
- package/dist/multi/{991.app-b6362ca0.js → 991.app-71d7f77e.js} +1 -1
- package/dist/multi/app-71d7f77e.js +2 -0
- package/dist/multi/manifest.json +20 -20
- package/dist/multi/{styles-b6362ca0.css → styles-71d7f77e.css} +6 -6
- package/dist/single/app-7aa8b012.js +2 -0
- package/dist/single/manifest.json +1 -1
- package/package.json +11 -4
- package/src/assets/scss/_common.scss +9 -0
- package/src/components/app/ArrowButton/index.tsx +3 -2
- package/src/components/app/BaseLayout/index.tsx +5 -5
- package/src/components/app/ReportBody/Filters.tsx +12 -10
- package/src/components/app/ReportBody/HeaderActions.tsx +3 -3
- package/src/components/app/ReportBody/SortBy.tsx +10 -10
- package/src/components/app/ReportBody/context.tsx +0 -1
- package/src/components/app/ReportHeader/index.tsx +1 -1
- package/src/components/app/Tabs/index.tsx +2 -3
- package/src/components/app/TestResult/TestResultDescription/index.tsx +3 -3
- package/src/components/app/TestResult/TestResultNavigation/index.tsx +34 -37
- package/src/components/app/TestResult/TestResultNavigation/styles.scss +1 -1
- package/src/components/app/TestResult/TestResultSteps/attachment.tsx +4 -6
- package/src/components/app/Tree/Tree.tsx +54 -101
- package/src/components/app/Tree/TreeHeader.tsx +13 -12
- package/src/components/app/Tree/TreeItem.tsx +3 -1
- package/src/components/app/Tree/index.tsx +31 -7
- package/src/components/app/Tree/styles.scss +9 -3
- package/src/components/commons/Menu/index.tsx +44 -19
- package/src/components/commons/SearchBox/index.tsx +8 -5
- package/src/components/commons/SuccessRatePieChart/styles.scss +0 -1
- package/src/components/commons/Toggle/index.tsx +3 -2
- package/src/components/commons/Tooltip/index.tsx +3 -3
- package/src/i18n/constants.ts +21 -2
- package/src/i18n/locales/am.json +3 -1
- package/src/i18n/locales/az.json +3 -1
- package/src/i18n/locales/de.json +3 -1
- package/src/i18n/locales/en.json +4 -2
- package/src/i18n/locales/es.json +3 -0
- package/src/i18n/locales/fr.json +3 -1
- package/src/i18n/locales/he.json +3 -1
- package/src/i18n/locales/it.json +3 -1
- package/src/i18n/locales/ja.json +3 -1
- package/src/i18n/locales/ka.json +3 -1
- package/src/i18n/locales/kr.json +3 -1
- package/src/i18n/locales/nl.json +3 -1
- package/src/i18n/locales/pl.json +3 -1
- package/src/i18n/locales/pt.json +3 -1
- package/src/i18n/locales/ru.json +3 -1
- package/src/i18n/locales/sv.json +3 -1
- package/src/i18n/locales/tr.json +3 -1
- package/src/i18n/locales/zh.json +4 -2
- package/src/index.html +1 -0
- package/src/stores/chart.ts +2 -2
- package/src/stores/testResults.ts +26 -4
- package/src/stores/tree.ts +98 -4
- package/src/types/globals.d.ts +6 -1
- package/src/utils/capitalize.ts +5 -3
- package/src/utils/treeFilters.ts +73 -120
- package/test/utils/treeFilters.test.ts +424 -0
- package/types.d.ts +25 -4
- package/vitest.config.ts +12 -0
- package/dist/multi/222.app-b6362ca0.js +0 -1
- package/dist/multi/335.app-b6362ca0.js +0 -1
- package/dist/multi/349.app-b6362ca0.js +0 -1
- package/dist/multi/378.app-b6362ca0.js +0 -1
- package/dist/multi/476.app-b6362ca0.js +0 -1
- package/dist/multi/690.app-b6362ca0.js +0 -1
- package/dist/multi/83.app-b6362ca0.js +0 -1
- package/dist/multi/app-b6362ca0.js +0 -2
- package/dist/single/app-57ae0a60.js +0 -2
- /package/dist/multi/{app-b6362ca0.js.LICENSE.txt → app-71d7f77e.js.LICENSE.txt} +0 -0
- /package/dist/single/{app-57ae0a60.js.LICENSE.txt → app-7aa8b012.js.LICENSE.txt} +0 -0
package/src/i18n/locales/he.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "הפוך"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "
|
|
63
|
+
"no-results": "אין תוצאות",
|
|
64
|
+
"no-tests-found": "לא נמצאו תוצאות",
|
|
65
|
+
"clear-filters": "נקה מסננים",
|
|
64
66
|
"no-attachments-results": "לא נמצאה מידע על קבצים מצורפים",
|
|
65
67
|
"no-history-results": "לא נמצאה מידע על היסטוריה",
|
|
66
68
|
"no-retries-results": "לא נמצאה מידע על נסיונות חוזרים"
|
package/src/i18n/locales/it.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "Invertito"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "Nessun risultato
|
|
63
|
+
"no-results": "Nessun risultato",
|
|
64
|
+
"no-tests-found": "Nessun risultato trovato",
|
|
65
|
+
"clear-filters": "Cancella i filtri",
|
|
64
66
|
"no-attachments-results": "Nessuna informazione sugli allegati disponibile",
|
|
65
67
|
"no-history-results": "Nessuna informazione sulla cronologia disponibile",
|
|
66
68
|
"no-retries-results": "Nessuna informazione sui ritentativi disponibile"
|
package/src/i18n/locales/ja.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "逆順"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "
|
|
63
|
+
"no-results": "結果がありません",
|
|
64
|
+
"no-tests-found": "結果が見つかりません",
|
|
65
|
+
"clear-filters": "フィルターをクリア",
|
|
64
66
|
"no-attachments-results": "添付ファイル情報が利用できません",
|
|
65
67
|
"no-history-results": "履歴情報が利用できません",
|
|
66
68
|
"no-retries-results": "再試行情報が利用できません"
|
package/src/i18n/locales/ka.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "შებრუნებული"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "შედეგები არ
|
|
63
|
+
"no-results": "შედეგები არ არის",
|
|
64
|
+
"no-tests-found": "შედეგები არ მოიძებნა",
|
|
65
|
+
"clear-filters": "ფილტრების გასუფთავება",
|
|
64
66
|
"no-attachments-results": "დანართების ინფორმაცია არ არის ხელმისაწვდომი",
|
|
65
67
|
"no-history-results": "ისტორიის ინფორმაცია არ არის ხელმისაწვდომი",
|
|
66
68
|
"no-retries-results": "ხელახალი ცდების ინფორმ���ცია არ არის ხელმისაწვდომი"
|
package/src/i18n/locales/kr.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "역순"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "
|
|
63
|
+
"no-results": "결과 없음",
|
|
64
|
+
"no-tests-found": "결과를 찾을 수 없음",
|
|
65
|
+
"clear-filters": "필터 지우기",
|
|
64
66
|
"no-attachments-results": "첨부파일 정보를 사용할 수 없습니다",
|
|
65
67
|
"no-history-results": "기록 정보를 사용할 수 없습니다",
|
|
66
68
|
"no-retries-results": "재시도 정보를 사용할 수 없습니다"
|
package/src/i18n/locales/nl.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "Omgekeerd"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "Geen resultaten
|
|
63
|
+
"no-results": "Geen resultaten",
|
|
64
|
+
"no-tests-found": "Geen resultaten gevonden",
|
|
65
|
+
"clear-filters": "Filters wissen",
|
|
64
66
|
"no-attachments-results": "Geen bijlageninformatie beschikbaar",
|
|
65
67
|
"no-history-results": "Geen geschiedenisinformatie beschikbaar",
|
|
66
68
|
"no-retries-results": "Geen herhalingsinformatie beschikbaar"
|
package/src/i18n/locales/pl.json
CHANGED
|
@@ -57,7 +57,9 @@
|
|
|
57
57
|
"status-desc-short": "Domyślnie"
|
|
58
58
|
},
|
|
59
59
|
"empty": {
|
|
60
|
-
"no-results": "
|
|
60
|
+
"no-results": "Brak wyników",
|
|
61
|
+
"no-tests-found": "Nie znaleziono wyników",
|
|
62
|
+
"clear-filters": "Wyczyść filtry",
|
|
61
63
|
"no-attachments-results": "Brak dostępnych informacji o załącznikach",
|
|
62
64
|
"no-history-results": "Brak dostępnych informacji o historii",
|
|
63
65
|
"no-retries-results": "Brak dostępnych informacji o ponownych próbach"
|
package/src/i18n/locales/pt.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "Invertido"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "
|
|
63
|
+
"no-results": "Sem resultados",
|
|
64
|
+
"no-tests-found": "Nenhum resultado encontrado",
|
|
65
|
+
"clear-filters": "Limpar filtros",
|
|
64
66
|
"no-attachments-results": "Nenhuma informação de anexos disponível",
|
|
65
67
|
"no-history-results": "Nenhuma informação de histórico disponível",
|
|
66
68
|
"no-retries-results": "Nenhuma informação de repetições disponível"
|
package/src/i18n/locales/ru.json
CHANGED
|
@@ -57,7 +57,9 @@
|
|
|
57
57
|
"status-desc-short": "По обычному"
|
|
58
58
|
},
|
|
59
59
|
"empty": {
|
|
60
|
-
"no-results": "
|
|
60
|
+
"no-results": "Нет результатов",
|
|
61
|
+
"no-tests-found": "Результаты не найдены",
|
|
62
|
+
"clear-filters": "Очистить фильтры",
|
|
61
63
|
"no-attachments-results": "Информация о вложениях отсутствует",
|
|
62
64
|
"no-history-results": "Информация об истории отсутствует",
|
|
63
65
|
"no-retries-results": "Информация о перезапусках отсутствует"
|
package/src/i18n/locales/sv.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "Omvänd"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "Inga resultat
|
|
63
|
+
"no-results": "Inga resultat",
|
|
64
|
+
"no-tests-found": "Inga resultat hittades",
|
|
65
|
+
"clear-filters": "Rensa filter",
|
|
64
66
|
"no-attachments-results": "Ingen bilaga information tillgänglig",
|
|
65
67
|
"no-history-results": "Ingen historik information tillgänglig",
|
|
66
68
|
"no-retries-results": "Ingen omtagningar information tillgänglig"
|
package/src/i18n/locales/tr.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "Ters"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "Sonuç
|
|
63
|
+
"no-results": "Sonuç yok",
|
|
64
|
+
"no-tests-found": "Sonuç bulunamadı",
|
|
65
|
+
"clear-filters": "Filtreleri temizle",
|
|
64
66
|
"no-attachments-results": "Ek bilgisi mevcut değil",
|
|
65
67
|
"no-history-results": "Geçmiş bilgisi mevcut değil",
|
|
66
68
|
"no-retries-results": "Tekrar deneme bilgisi mevcut değil"
|
package/src/i18n/locales/zh.json
CHANGED
|
@@ -60,7 +60,9 @@
|
|
|
60
60
|
"status-desc-short": "反转"
|
|
61
61
|
},
|
|
62
62
|
"empty": {
|
|
63
|
-
"no-results": "
|
|
63
|
+
"no-results": "没有结果",
|
|
64
|
+
"no-tests-found": "未找到结果",
|
|
65
|
+
"clear-filters": "清除过滤器",
|
|
64
66
|
"no-attachments-results": "没有附件信息",
|
|
65
67
|
"no-history-results": "没有历史信息",
|
|
66
68
|
"no-retries-results": "没有重试信息"
|
|
@@ -112,4 +114,4 @@
|
|
|
112
114
|
"errors": {
|
|
113
115
|
"missedAttachment": "未找到附件"
|
|
114
116
|
}
|
|
115
|
-
}
|
|
117
|
+
}
|
package/src/index.html
CHANGED
package/src/stores/chart.ts
CHANGED
|
@@ -21,12 +21,12 @@ export const fetchPieChartData = async () => {
|
|
|
21
21
|
pieChartStore.value = {
|
|
22
22
|
data: res,
|
|
23
23
|
error: undefined,
|
|
24
|
-
loading: false
|
|
24
|
+
loading: false,
|
|
25
25
|
};
|
|
26
26
|
} catch (err) {
|
|
27
27
|
pieChartStore.value = {
|
|
28
28
|
error: err.message,
|
|
29
|
-
loading: false
|
|
29
|
+
loading: false,
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
};
|
|
@@ -9,6 +9,30 @@ export const testResultStore = signal<StoreSignalState<Record<string, AllureAwes
|
|
|
9
9
|
data: undefined,
|
|
10
10
|
});
|
|
11
11
|
|
|
12
|
+
export const testResultNavStore = signal<StoreSignalState<string[]>>({
|
|
13
|
+
loading: true,
|
|
14
|
+
error: undefined,
|
|
15
|
+
data: undefined,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const fetchTestResultNav = async () => {
|
|
19
|
+
try {
|
|
20
|
+
const data = await fetchReportJsonData<string[]>("widgets/nav.json");
|
|
21
|
+
|
|
22
|
+
testResultNavStore.value = {
|
|
23
|
+
data,
|
|
24
|
+
error: undefined,
|
|
25
|
+
loading: false,
|
|
26
|
+
};
|
|
27
|
+
} catch (err) {
|
|
28
|
+
testResultNavStore.value = {
|
|
29
|
+
...testResultNavStore.value,
|
|
30
|
+
error: err.message,
|
|
31
|
+
loading: false,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
12
36
|
export const fetchTestResult = async (testResultId: string) => {
|
|
13
37
|
if (!testResultId || testResultStore.value.data?.[testResultId]) {
|
|
14
38
|
return;
|
|
@@ -18,12 +42,10 @@ export const fetchTestResult = async (testResultId: string) => {
|
|
|
18
42
|
...testResultStore.value,
|
|
19
43
|
loading: true,
|
|
20
44
|
error: undefined,
|
|
21
|
-
}
|
|
45
|
+
};
|
|
22
46
|
|
|
23
47
|
try {
|
|
24
|
-
const data = await fetchReportJsonData<AllureAwesomeTestResult>(
|
|
25
|
-
`data/test-results/${testResultId}.json`,
|
|
26
|
-
);
|
|
48
|
+
const data = await fetchReportJsonData<AllureAwesomeTestResult>(`data/test-results/${testResultId}.json`);
|
|
27
49
|
|
|
28
50
|
testResultStore.value = {
|
|
29
51
|
data: { ...testResultStore.value.data, [testResultId]: data },
|
package/src/stores/tree.ts
CHANGED
|
@@ -1,14 +1,108 @@
|
|
|
1
1
|
import { fetchReportJsonData } from "@allurereport/web-commons";
|
|
2
|
-
import { signal } from "@preact/signals";
|
|
2
|
+
import { computed, signal } from "@preact/signals";
|
|
3
3
|
import type { StoreSignalState } from "@/stores/types";
|
|
4
|
+
import { createRecursiveTree, isRecursiveTreeEmpty } from "@/utils/treeFilters";
|
|
5
|
+
import type {AllureAwesomeStatus, AllureAwesomeTree, AllureAwesomeTreeGroup} from "../../types";
|
|
4
6
|
|
|
5
|
-
export
|
|
7
|
+
export type TreeSortBy = "order" | "duration" | "status" | "alphabet";
|
|
8
|
+
export type TreeDirection = "asc" | "desc";
|
|
9
|
+
export type TreeFilters = "flaky" | "retry" | "new";
|
|
10
|
+
export type TreeFiltersState = {
|
|
11
|
+
query: string;
|
|
12
|
+
status: AllureAwesomeStatus;
|
|
13
|
+
filter: Record<TreeFilters, boolean>;
|
|
14
|
+
sortBy: TreeSortBy;
|
|
15
|
+
direction: TreeDirection;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const treeStore = signal<StoreSignalState<AllureAwesomeTree>>({
|
|
6
19
|
loading: true,
|
|
7
20
|
error: undefined,
|
|
8
21
|
data: undefined,
|
|
9
22
|
});
|
|
10
23
|
|
|
11
|
-
export const
|
|
24
|
+
export const noTests = computed(() => !Object.keys(treeStore?.value?.data?.leavesById).length);
|
|
25
|
+
|
|
26
|
+
export const treeFiltersStore = signal<TreeFiltersState>({
|
|
27
|
+
query: "",
|
|
28
|
+
status: "total",
|
|
29
|
+
filter: {
|
|
30
|
+
flaky: false,
|
|
31
|
+
retry: false,
|
|
32
|
+
new: false,
|
|
33
|
+
},
|
|
34
|
+
sortBy: "order",
|
|
35
|
+
direction: "asc",
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const filteredTree = computed(() => {
|
|
39
|
+
const { root, leavesById, groupsById } = treeStore.value.data;
|
|
40
|
+
|
|
41
|
+
return createRecursiveTree({
|
|
42
|
+
group: root as AllureAwesomeTreeGroup,
|
|
43
|
+
leavesById,
|
|
44
|
+
groupsById,
|
|
45
|
+
filterOptions: treeFiltersStore.value,
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export const noTestsFound = computed(() => {
|
|
50
|
+
return isRecursiveTreeEmpty(filteredTree.value);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export const clearTreeFilters = () => {
|
|
54
|
+
treeFiltersStore.value = {
|
|
55
|
+
query: "",
|
|
56
|
+
status: "total",
|
|
57
|
+
filter: {
|
|
58
|
+
flaky: false,
|
|
59
|
+
retry: false,
|
|
60
|
+
new: false,
|
|
61
|
+
},
|
|
62
|
+
sortBy: "order",
|
|
63
|
+
direction: "asc",
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const setTreeQuery = (query: string) => {
|
|
68
|
+
treeFiltersStore.value = {
|
|
69
|
+
...treeFiltersStore.value,
|
|
70
|
+
query,
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const setTreeStatus = (status: AllureAwesomeStatus) => {
|
|
75
|
+
treeFiltersStore.value = {
|
|
76
|
+
...treeFiltersStore.value,
|
|
77
|
+
status,
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const setTreeSortBy = (sortBy: TreeSortBy) => {
|
|
82
|
+
treeFiltersStore.value = {
|
|
83
|
+
...treeFiltersStore.value,
|
|
84
|
+
sortBy,
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const setTreeDirection = (direction: TreeDirection) => {
|
|
89
|
+
treeFiltersStore.value = {
|
|
90
|
+
...treeFiltersStore.value,
|
|
91
|
+
direction,
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const setTreeFilter = (filterKey: TreeFilters, value: boolean) => {
|
|
96
|
+
treeFiltersStore.value = {
|
|
97
|
+
...treeFiltersStore.value,
|
|
98
|
+
filter: {
|
|
99
|
+
...treeFiltersStore.value.filter,
|
|
100
|
+
[filterKey]: value,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const fetchTreeData = async () => {
|
|
12
106
|
treeStore.value = {
|
|
13
107
|
...treeStore.value,
|
|
14
108
|
loading: true,
|
|
@@ -16,7 +110,7 @@ export const fetchTreeData = async (treeName: string) => {
|
|
|
16
110
|
};
|
|
17
111
|
|
|
18
112
|
try {
|
|
19
|
-
const res = await fetchReportJsonData(
|
|
113
|
+
const res = await fetchReportJsonData<AllureAwesomeTree>("widgets/tree.json");
|
|
20
114
|
|
|
21
115
|
treeStore.value = {
|
|
22
116
|
data: res,
|
package/src/types/globals.d.ts
CHANGED
package/src/utils/capitalize.ts
CHANGED
package/src/utils/treeFilters.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { TreeFiltersState } from "@/stores/tree";
|
|
2
|
+
import type { AllureAwesomeRecursiveTree, AllureAwesomeTree, AllureAwesomeTreeGroup } from "../../types";
|
|
3
3
|
|
|
4
4
|
const statusOrder = {
|
|
5
5
|
failed: 1,
|
|
@@ -9,142 +9,95 @@ const statusOrder = {
|
|
|
9
9
|
unknown: 5,
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
leaves,
|
|
14
|
-
leavesById,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
export const filterLeaves = (
|
|
13
|
+
leaves: string[] = [],
|
|
14
|
+
leavesById: AllureAwesomeTree["leavesById"],
|
|
15
|
+
filterOptions?: TreeFiltersState,
|
|
16
|
+
) => {
|
|
17
|
+
const filteredLeaves = [...leaves]
|
|
18
|
+
.map((leafId) => leavesById[leafId])
|
|
19
|
+
.filter((leaf) => {
|
|
20
|
+
const queryMatched = !filterOptions?.query || leaf.name.toLowerCase().includes(filterOptions.query.toLowerCase());
|
|
21
|
+
const statusMatched =
|
|
22
|
+
!filterOptions?.status || filterOptions?.status === "total" || leaf.status === filterOptions.status;
|
|
23
|
+
const flakyMatched = !filterOptions?.filter?.flaky || leaf.flaky;
|
|
24
|
+
const retryMatched = !filterOptions?.filter?.retry || leaf.retry;
|
|
25
|
+
// TODO: at this moment we don't have a new field implementation even in the generator
|
|
26
|
+
// const newMatched = !filterOptions?.filter?.new || leaf.new;
|
|
27
|
+
|
|
28
|
+
return [queryMatched, statusMatched, flakyMatched, retryMatched].every(Boolean);
|
|
29
|
+
});
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
if (!filterOptions) {
|
|
32
|
+
return filteredLeaves;
|
|
33
|
+
}
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
leavesById,
|
|
32
|
-
filterOptions,
|
|
33
|
-
}: {
|
|
34
|
-
leavesFiltered: string[];
|
|
35
|
-
leavesById: DefaultTreeData["leavesById"];
|
|
36
|
-
filterOptions: ReportContentContextValue;
|
|
37
|
-
}) => {
|
|
38
|
-
leavesFiltered.sort((a, b) => {
|
|
39
|
-
const leafA = leavesById[a];
|
|
40
|
-
const leafB = leavesById[b];
|
|
41
|
-
const filterDirection = filterOptions.direction === "asc";
|
|
35
|
+
return filteredLeaves.sort((a, b) => {
|
|
36
|
+
const asc = filterOptions.direction === "asc";
|
|
42
37
|
|
|
43
38
|
switch (filterOptions.sortBy) {
|
|
39
|
+
case "order":
|
|
40
|
+
return asc ? a.groupOrder - b.groupOrder : b.groupOrder - a.groupOrder;
|
|
44
41
|
case "duration":
|
|
45
|
-
return
|
|
46
|
-
? (leafA.duration || 0) - (leafB.duration || 0)
|
|
47
|
-
: (leafB.duration || 0) - (leafA.duration || 0);
|
|
42
|
+
return asc ? (a.duration || 0) - (b.duration || 0) : (b.duration || 0) - (a.duration || 0);
|
|
48
43
|
case "alphabet":
|
|
49
|
-
return
|
|
44
|
+
return asc ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
|
|
50
45
|
case "status": {
|
|
51
|
-
const statusA = statusOrder[
|
|
52
|
-
const statusB = statusOrder[
|
|
53
|
-
|
|
46
|
+
const statusA = statusOrder[a.status] || statusOrder.unknown;
|
|
47
|
+
const statusB = statusOrder[b.status] || statusOrder.unknown;
|
|
48
|
+
|
|
49
|
+
return asc ? statusA - statusB : statusB - statusA;
|
|
54
50
|
}
|
|
55
51
|
default:
|
|
56
52
|
return 0;
|
|
57
53
|
}
|
|
58
54
|
});
|
|
59
|
-
|
|
60
|
-
if (filterOptions.direction === "desc" && ["order"].includes(filterOptions.sortBy as string)) {
|
|
61
|
-
leavesFiltered.reverse();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return leavesFiltered;
|
|
65
55
|
};
|
|
66
56
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Fills the given tree from generator and returns recursive tree which includes leaves data instead of their IDs
|
|
59
|
+
* Filters leaves when `filterOptions` property is provided
|
|
60
|
+
* @param payload
|
|
61
|
+
*/
|
|
62
|
+
export const createRecursiveTree = (payload: {
|
|
63
|
+
group: AllureAwesomeTreeGroup;
|
|
64
|
+
groupsById: AllureAwesomeTree["groupsById"];
|
|
65
|
+
leavesById: AllureAwesomeTree["leavesById"];
|
|
66
|
+
filterOptions?: TreeFiltersState;
|
|
67
|
+
}): AllureAwesomeRecursiveTree => {
|
|
68
|
+
const { group, groupsById, leavesById, filterOptions } = payload;
|
|
69
|
+
const groupLeaves = group.leaves ?? [];
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
...group,
|
|
73
|
+
// FIXME: don't have any idea, why eslint marks next line as unsafe because it actually has a correct type
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
75
|
+
leaves: filterLeaves(groupLeaves, leavesById, filterOptions),
|
|
76
|
+
trees: group?.groups
|
|
77
|
+
?.filter((groupId) => {
|
|
78
|
+
const subGroup = groupsById[groupId];
|
|
79
|
+
|
|
80
|
+
return subGroup?.leaves?.length || subGroup?.groups?.length;
|
|
81
|
+
})
|
|
82
|
+
?.map((groupId) =>
|
|
83
|
+
createRecursiveTree({
|
|
84
|
+
group: groupsById[groupId],
|
|
85
|
+
groupsById,
|
|
92
86
|
leavesById,
|
|
93
|
-
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
leavesFiltered = filterByQuery({
|
|
98
|
-
leaves: leavesFiltered,
|
|
99
|
-
leavesById,
|
|
100
|
-
query: filterOptions.query,
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
leavesFiltered = filterByTestType({ leaves: leavesFiltered, leavesById, filterTypes: filterOptions.filter });
|
|
104
|
-
|
|
105
|
-
leavesFiltered = sortedLeaves({ leavesFiltered, leavesById, filterOptions });
|
|
106
|
-
|
|
107
|
-
return leavesFiltered;
|
|
87
|
+
filterOptions,
|
|
88
|
+
}),
|
|
89
|
+
),
|
|
90
|
+
};
|
|
108
91
|
};
|
|
109
92
|
|
|
110
|
-
export const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
statusFilter?: string,
|
|
115
|
-
filterOptions?: ReportContentContextValue,
|
|
116
|
-
): string[] => {
|
|
117
|
-
const gro = groups.filter((groupId) => {
|
|
118
|
-
const group = groupsById?.[groupId];
|
|
119
|
-
const groupLeaves = filterLeaves((group?.leaves as string[]) || [], leavesById, statusFilter, filterOptions);
|
|
120
|
-
const filteredSubGroups = group?.groups?.filter((subGroupId: number) => {
|
|
121
|
-
const subGroup = groupsById?.[subGroupId] as { leaves: string[]; groups: string[] };
|
|
122
|
-
return (
|
|
123
|
-
filterLeaves(subGroup?.leaves || [], leavesById, statusFilter, filterOptions).length > 0 ||
|
|
124
|
-
filterGroups(subGroup?.groups || [], groupsById, leavesById, statusFilter, filterOptions).length > 0
|
|
125
|
-
);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
return groupLeaves.length > 0 || (filteredSubGroups && filteredSubGroups.length > 0);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
const sortedGroups = gro.sort((a, b) => {
|
|
132
|
-
const leafA = groupsById[a];
|
|
133
|
-
const leafB = groupsById[b];
|
|
134
|
-
const filterDirection = filterOptions.direction === "asc";
|
|
135
|
-
|
|
136
|
-
switch (filterOptions.sortBy) {
|
|
137
|
-
case "alphabet": {
|
|
138
|
-
return filterDirection ? leafA.name.localeCompare(leafB.name) : leafB.name.localeCompare(leafA.name);
|
|
139
|
-
}
|
|
140
|
-
default:
|
|
141
|
-
return 0;
|
|
142
|
-
}
|
|
143
|
-
});
|
|
93
|
+
export const isRecursiveTreeEmpty = (tree: AllureAwesomeRecursiveTree) => {
|
|
94
|
+
if (!tree.trees?.length && !tree.leaves?.length) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
144
97
|
|
|
145
|
-
if (
|
|
146
|
-
|
|
98
|
+
if (tree.leaves?.length) {
|
|
99
|
+
return false;
|
|
147
100
|
}
|
|
148
101
|
|
|
149
|
-
return
|
|
102
|
+
return tree.trees?.every((subTree) => isRecursiveTreeEmpty(subTree));
|
|
150
103
|
};
|