@allurereport/web-classic 3.1.0 → 3.2.0

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.
Files changed (37) hide show
  1. package/dist/multi/app-d6b3181758d7bcaf59fb.js +2 -0
  2. package/dist/multi/manifest.json +22 -22
  3. package/dist/multi/{styles-88c7772c6bdc61325e60.css → styles-0a265e78e1a527b133dd.css} +2 -2
  4. package/dist/single/app-5b0e25f6b516905c3adc.js +2 -0
  5. package/dist/single/manifest.json +1 -1
  6. package/package.json +5 -6
  7. package/src/components/TestResult/TestResultDescription/index.tsx +60 -10
  8. package/src/components/TestResult/TestResultDescription/styles.scss +4 -0
  9. package/src/components/TestResult/TestResultOverview.tsx +2 -2
  10. package/src/stores/locale.ts +2 -1
  11. package/src/translations/constants.ts +24 -18
  12. package/src/utils/time.ts +16 -2
  13. package/types.d.ts +1 -1
  14. package/dist/multi/app-b491577c193a7caf8c74.js +0 -2
  15. package/dist/single/app-0a173e3f1e0c5c003891.js +0 -2
  16. /package/dist/multi/{10.app-b491577c193a7caf8c74.js → 10.app-d6b3181758d7bcaf59fb.js} +0 -0
  17. /package/dist/multi/{222.app-b491577c193a7caf8c74.js → 222.app-d6b3181758d7bcaf59fb.js} +0 -0
  18. /package/dist/multi/{26.app-b491577c193a7caf8c74.js → 26.app-d6b3181758d7bcaf59fb.js} +0 -0
  19. /package/dist/multi/{302.app-b491577c193a7caf8c74.js → 302.app-d6b3181758d7bcaf59fb.js} +0 -0
  20. /package/dist/multi/{304.app-b491577c193a7caf8c74.js → 304.app-d6b3181758d7bcaf59fb.js} +0 -0
  21. /package/dist/multi/{369.app-b491577c193a7caf8c74.js → 369.app-d6b3181758d7bcaf59fb.js} +0 -0
  22. /package/dist/multi/{389.app-b491577c193a7caf8c74.js → 389.app-d6b3181758d7bcaf59fb.js} +0 -0
  23. /package/dist/multi/{498.app-b491577c193a7caf8c74.js → 498.app-d6b3181758d7bcaf59fb.js} +0 -0
  24. /package/dist/multi/{60.app-b491577c193a7caf8c74.js → 60.app-d6b3181758d7bcaf59fb.js} +0 -0
  25. /package/dist/multi/{643.app-b491577c193a7caf8c74.js → 643.app-d6b3181758d7bcaf59fb.js} +0 -0
  26. /package/dist/multi/{671.app-b491577c193a7caf8c74.js → 671.app-d6b3181758d7bcaf59fb.js} +0 -0
  27. /package/dist/multi/{725.app-b491577c193a7caf8c74.js → 725.app-d6b3181758d7bcaf59fb.js} +0 -0
  28. /package/dist/multi/{770.app-b491577c193a7caf8c74.js → 770.app-d6b3181758d7bcaf59fb.js} +0 -0
  29. /package/dist/multi/{848.app-b491577c193a7caf8c74.js → 848.app-d6b3181758d7bcaf59fb.js} +0 -0
  30. /package/dist/multi/{853.app-b491577c193a7caf8c74.js → 853.app-d6b3181758d7bcaf59fb.js} +0 -0
  31. /package/dist/multi/{872.app-b491577c193a7caf8c74.js → 872.app-d6b3181758d7bcaf59fb.js} +0 -0
  32. /package/dist/multi/{895.app-b491577c193a7caf8c74.js → 895.app-d6b3181758d7bcaf59fb.js} +0 -0
  33. /package/dist/multi/{920.app-b491577c193a7caf8c74.js → 920.app-d6b3181758d7bcaf59fb.js} +0 -0
  34. /package/dist/multi/{979.app-b491577c193a7caf8c74.js → 979.app-d6b3181758d7bcaf59fb.js} +0 -0
  35. /package/dist/multi/{991.app-b491577c193a7caf8c74.js → 991.app-d6b3181758d7bcaf59fb.js} +0 -0
  36. /package/dist/multi/{app-b491577c193a7caf8c74.js.LICENSE.txt → app-d6b3181758d7bcaf59fb.js.LICENSE.txt} +0 -0
  37. /package/dist/single/{app-0a173e3f1e0c5c003891.js.LICENSE.txt → app-5b0e25f6b516905c3adc.js.LICENSE.txt} +0 -0
@@ -1,3 +1,3 @@
1
1
  {
2
- "main.js": "app-0a173e3f1e0c5c003891.js"
2
+ "main.js": "app-5b0e25f6b516905c3adc.js"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/web-classic",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "The static files for Allure Classic Report",
5
5
  "keywords": [
6
6
  "allure",
@@ -31,10 +31,10 @@
31
31
  "IE 11"
32
32
  ],
33
33
  "dependencies": {
34
- "@allurereport/charts-api": "3.1.0",
35
- "@allurereport/core-api": "3.1.0",
36
- "@allurereport/web-commons": "3.1.0",
37
- "@allurereport/web-components": "3.1.0",
34
+ "@allurereport/charts-api": "3.2.0",
35
+ "@allurereport/core-api": "3.2.0",
36
+ "@allurereport/web-commons": "3.2.0",
37
+ "@allurereport/web-components": "3.2.0",
38
38
  "@preact/signals": "^2.6.1",
39
39
  "clsx": "^2.1.1",
40
40
  "d3-shape": "^3.2.0",
@@ -42,7 +42,6 @@
42
42
  "md5": "^2.3.0",
43
43
  "preact": "^10.28.2",
44
44
  "prismjs": "^1.30.0",
45
- "reset.css": "^2.0.2",
46
45
  "split.js": "^1.6.5"
47
46
  },
48
47
  "devDependencies": {
@@ -1,25 +1,75 @@
1
- import { Text } from "@allurereport/web-components";
1
+ import { proseStyles, resolveCssVarDeclarations, sanitizeIframeHtml, themeStore } from "@allurereport/web-commons";
2
2
  import type { FunctionalComponent } from "preact";
3
- import { useState } from "preact/hooks";
3
+ import { useEffect, useMemo, useState } from "preact/hooks";
4
4
  import type { ClassicTestResult } from "types";
5
5
  import { MetadataButton } from "@/components/MetadataButton";
6
6
  import * as styles from "./styles.scss";
7
7
 
8
8
  export type TestResultDescriptionProps = {
9
- description: ClassicTestResult["description"];
9
+ descriptionHtml: ClassicTestResult["descriptionHtml"];
10
10
  };
11
11
 
12
- export const TestResultDescription: FunctionalComponent<TestResultDescriptionProps> = ({ description }) => {
13
- const [isOpen, setIsOpen] = useState<boolean>(true);
12
+ const MIN_HEIGHT = 120;
13
+
14
+ export const TestResultDescription: FunctionalComponent<TestResultDescriptionProps> = ({ descriptionHtml }) => {
15
+ const [isOpen, setIsOpen] = useState(true);
16
+ const [blobUrl, setBlobUrl] = useState("");
17
+ const [height, setHeight] = useState(MIN_HEIGHT);
18
+ const currentTheme = themeStore.value.current;
19
+
20
+ const sanitized = useMemo(() => (descriptionHtml ? sanitizeIframeHtml(descriptionHtml) : ""), [descriptionHtml]);
21
+
22
+ useEffect(() => {
23
+ if (!sanitized) {
24
+ setBlobUrl("");
25
+ return;
26
+ }
27
+
28
+ const iframeThemeVars = resolveCssVarDeclarations(proseStyles);
29
+
30
+ const html = `<!DOCTYPE html>
31
+ <html data-theme="${currentTheme}">
32
+ <head>
33
+ <meta charset="utf-8">
34
+ <style>:root {${iframeThemeVars}}</style>
35
+ <style>${proseStyles}</style>
36
+ </head>
37
+ <body>${sanitized}</body>
38
+ </html>`;
39
+
40
+ const blob = new Blob([html], { type: "text/html" });
41
+ const url = URL.createObjectURL(blob);
42
+ setBlobUrl(url);
43
+
44
+ return () => URL.revokeObjectURL(url);
45
+ }, [currentTheme, sanitized]);
46
+
47
+ const handleLoad = (e: Event) => {
48
+ const iframe = e.currentTarget as HTMLIFrameElement;
49
+ const documentElement = iframe.contentDocument?.documentElement;
50
+ const body = iframe.contentDocument?.body;
51
+ const scrollHeight = Math.max(documentElement?.scrollHeight ?? 0, body?.scrollHeight ?? 0);
52
+ setHeight(Math.max(scrollHeight, MIN_HEIGHT));
53
+ };
14
54
 
15
55
  return (
16
- <div className={styles["test-result-description"]}>
56
+ <div className={styles["test-result-description"]} data-testid="test-result-description">
17
57
  <div className={styles["test-result-description-wrapper"]}>
18
- <MetadataButton title={"Description"} setIsOpen={setIsOpen} isOpened={isOpen} />
58
+ <MetadataButton title="Description" setIsOpen={setIsOpen} isOpened={isOpen} />
19
59
  {isOpen && (
20
- <Text tag={"p"} className={styles["test-result-description-text"]}>
21
- {description || "Description mock"}
22
- </Text>
60
+ <div className={styles["test-result-description-text"]}>
61
+ {blobUrl && (
62
+ <iframe
63
+ data-testid="test-result-description-frame"
64
+ src={blobUrl}
65
+ width="100%"
66
+ height={String(height)}
67
+ style={{ border: 0 }}
68
+ sandbox="allow-same-origin"
69
+ onLoad={handleLoad}
70
+ />
71
+ )}
72
+ </div>
23
73
  )}
24
74
  </div>
25
75
  </div>
@@ -9,4 +9,8 @@
9
9
 
10
10
  .test-result-description-text {
11
11
  padding-top: 10px;
12
+
13
+ iframe {
14
+ display: block;
15
+ }
12
16
  }
@@ -15,7 +15,7 @@ export type TestResultOverviewProps = {
15
15
  };
16
16
 
17
17
  export const TestResultOverview: FunctionalComponent<TestResultOverviewProps> = ({ testResult }) => {
18
- const { error, parameters, groupedLabels, links, description, setup, steps, teardown } = testResult || {};
18
+ const { error, parameters, groupedLabels, links, descriptionHtml, setup, steps, teardown } = testResult || {};
19
19
 
20
20
  return (
21
21
  <>
@@ -29,7 +29,7 @@ export const TestResultOverview: FunctionalComponent<TestResultOverviewProps> =
29
29
  <TestResultMetadata testResult={testResult} />
30
30
  )}
31
31
  {Boolean(links?.length) && <TestResultLinks links={links} />}
32
- {Boolean(description) && <TestResultDescription description={description} />}
32
+ {Boolean(descriptionHtml) && <TestResultDescription descriptionHtml={descriptionHtml} />}
33
33
  <div className={styles["test-results"]}>
34
34
  {Boolean(setup?.length) && <TestResultSetup setup={setup} />}
35
35
  {Boolean(steps?.length) && <TestResultSteps steps={steps} />}
@@ -52,7 +52,8 @@ i18next
52
52
  callback: (errorValue: unknown, translations: Record<string, string> | null) => void,
53
53
  ) => {
54
54
  try {
55
- const resources = await import(`@/translations/${language}.json`);
55
+ const loadLocale = language === "en-iso" ? "en" : language;
56
+ const resources = await import(`@/translations/${loadLocale}.json`);
56
57
  callback(null, (resources[namespace] as Record<string, string>) || null);
57
58
  } catch (error) {
58
59
  callback(error, null);
@@ -1,5 +1,6 @@
1
1
  export const AVAILABLE_LOCALES = [
2
2
  "en",
3
+ "en-iso",
3
4
  "ru",
4
5
  "pl",
5
6
  "es",
@@ -31,92 +32,97 @@ export const LANG_LOCALE: Record<
31
32
  iso: string;
32
33
  }
33
34
  > = {
34
- en: {
35
+ "en": {
35
36
  short: "Eng",
36
37
  full: "English",
37
38
  iso: "en-US",
38
39
  },
39
- ru: {
40
+ "en-iso": {
41
+ short: "En ISO",
42
+ full: "English (ISO-8601)",
43
+ iso: "en-CA",
44
+ },
45
+ "ru": {
40
46
  short: "Ру",
41
47
  full: "Русский",
42
48
  iso: "ru-RU",
43
49
  },
44
- pl: {
50
+ "pl": {
45
51
  short: "Pl",
46
52
  full: "Polski",
47
53
  iso: "pl-PL",
48
54
  },
49
- es: {
55
+ "es": {
50
56
  short: "Es",
51
57
  full: "Español",
52
58
  iso: "es-ES",
53
59
  },
54
- pt: {
60
+ "pt": {
55
61
  short: "Pt",
56
62
  full: "Português",
57
63
  iso: "pt-PT",
58
64
  },
59
- de: {
65
+ "de": {
60
66
  short: "De",
61
67
  full: "Deutsch",
62
68
  iso: "de-DE",
63
69
  },
64
- am: {
70
+ "am": {
65
71
  short: "Am",
66
72
  full: "Հայերեն",
67
73
  iso: "hy-AM",
68
74
  },
69
- az: {
75
+ "az": {
70
76
  short: "Az",
71
77
  full: "Azərbaycan",
72
78
  iso: "az-AZ",
73
79
  },
74
- fr: {
80
+ "fr": {
75
81
  short: "Fr",
76
82
  full: "Français",
77
83
  iso: "fr-FR",
78
84
  },
79
- it: {
85
+ "it": {
80
86
  short: "It",
81
87
  full: "Italiano",
82
88
  iso: "it-IT",
83
89
  },
84
- ja: {
90
+ "ja": {
85
91
  short: "Ja",
86
92
  full: "日本語",
87
93
  iso: "ja-JP",
88
94
  },
89
- he: {
95
+ "he": {
90
96
  short: "He",
91
97
  full: "עברית",
92
98
  iso: "he-IL",
93
99
  },
94
- ka: {
100
+ "ka": {
95
101
  short: "Ka",
96
102
  full: "ქართული",
97
103
  iso: "ka-GE",
98
104
  },
99
- kr: {
105
+ "kr": {
100
106
  short: "Kr",
101
107
  full: "한국어",
102
108
  iso: "kr-KR",
103
109
  },
104
- nl: {
110
+ "nl": {
105
111
  short: "Nl",
106
112
  full: "Nederlands",
107
113
  iso: "nl-NL",
108
114
  },
109
- sv: {
115
+ "sv": {
110
116
  short: "Sv",
111
117
  full: "Svenska",
112
118
  iso: "sv-SE",
113
119
  },
114
- tr: {
120
+ "tr": {
115
121
  short: "Tr",
116
122
  full: "Türkçe",
117
123
  iso: "tr-TR",
118
124
  },
119
- zh: {
125
+ "zh": {
120
126
  short: "Zh",
121
127
  full: "中文",
122
128
  iso: "zh-CN",
package/src/utils/time.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { useI18n } from "@/stores/locale";
1
+ import { getLocaleDateTimeOverride } from "@allurereport/web-commons";
2
+ import { currentLocale, currentLocaleIso, useI18n } from "@/stores/locale";
2
3
 
3
4
  const defaultOptions: Intl.DateTimeFormatOptions = {
4
5
  month: "numeric",
@@ -12,6 +13,19 @@ const defaultOptions: Intl.DateTimeFormatOptions = {
12
13
 
13
14
  export const timestampToDate = (timestamp: number, options = defaultOptions) => {
14
15
  const date = new Date(timestamp);
16
+ // eslint-disable-next-line react-hooks/rules-of-hooks
15
17
  const { t } = useI18n("ui");
16
- return new Intl.DateTimeFormat("en-US", options).format(date).replace(",", ` ${t("at")}`);
18
+ const kind = options.second ? "dateTime" : options.hour || options.minute ? "dateTimeNoSeconds" : "date";
19
+ const override = getLocaleDateTimeOverride(currentLocale.value, kind);
20
+ const formatter = new Intl.DateTimeFormat(override?.locale ?? (currentLocaleIso.value as string), {
21
+ ...options,
22
+ ...(override?.options ?? {}),
23
+ });
24
+ const formatted = formatter.format(date);
25
+
26
+ if (override?.includeAtSeparator === false || override?.stripComma) {
27
+ return formatted.replace(",", "");
28
+ }
29
+
30
+ return formatted.replace(",", ` ${t("at")}`);
17
31
  };
package/types.d.ts CHANGED
@@ -21,7 +21,7 @@ export type ClassicReportOptions = {
21
21
  logo?: string;
22
22
  theme?: "light" | "dark" | "auto";
23
23
  groupBy?: string[];
24
- reportLanguage?: "en";
24
+ reportLanguage?: string;
25
25
  createdAt: number;
26
26
  reportUuid: string;
27
27
  allureVersion?: string;