@allurereport/core-api 3.21.0 → 3.22.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.
@@ -105,7 +105,7 @@ export declare const matchCategoryMatcher: (matcher: Matcher, d: CategoryMatchin
105
105
  export declare const matchCategory: (categories: CategoryDefinition[], d: CategoryMatchingData) => CategoryDefinition | undefined;
106
106
  export declare const extractErrorMatchingData: (tr: Pick<TestResult, "status" | "labels" | "error" | "flaky" | "duration" | "transition" | "environment">) => CategoryMatchingData;
107
107
  export declare const buildEnvironmentSortOrder: (environmentNames: string[], defaultEnvironmentName: string) => Map<string, number>;
108
- export declare const compareNumbers: (left: number, right: number) => 0 | 1 | -1;
108
+ export declare const compareNumbers: (left: number, right: number) => 1 | -1 | 0;
109
109
  export declare const compareStrings: (left: string, right: string) => number;
110
110
  export declare const isMissingValue: (value: string | undefined) => boolean;
111
111
  export declare const getGroupSortKey: (groupKey: string | undefined, groupValue: string | undefined, environmentOrderMap?: Map<string, number>) => GroupSortKey;
package/dist/ci.d.ts CHANGED
@@ -21,6 +21,8 @@ export interface CiDescriptor {
21
21
  jobRunUrl: string;
22
22
  jobRunName: string;
23
23
  jobRunBranch: string;
24
+ pipelineRunName?: string;
25
+ pipelineRunUrl?: string;
24
26
  pullRequestName: string;
25
27
  pullRequestUrl: string;
26
28
  provider?: GitProvider;
@@ -28,4 +30,6 @@ export interface CiDescriptor {
28
30
  sourceBranch?: string;
29
31
  targetBranch?: string;
30
32
  pullRequest?: GitPullRequestRef;
33
+ commitSha?: string;
34
+ commitUrl?: string;
31
35
  }
package/dist/config.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export type DefaultLabelsConfig = Record<string, string | string[]>;
2
2
  export type FlakyDetectionConfig = {
3
3
  historyDepth?: number;
4
+ stabilizationPeriod?: number;
4
5
  includePassedTests?: boolean;
5
6
  };
6
7
  export declare const parseIntegerConfigValue: (value: unknown, minValue?: number) => number | undefined;
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export * from "./ci.js";
4
4
  export * from "./gitFlow.js";
5
5
  export type * from "./environment.js";
6
6
  export type * from "./history.js";
7
- export type * from "./resolutions.js";
7
+ export * from "./resolutions.js";
8
8
  export type * from "./metadata.js";
9
9
  export * from "./metrics.js";
10
10
  export type * from "./model.js";
@@ -25,6 +25,7 @@ export * from "./utils/status.js";
25
25
  export * from "./utils/successRate.js";
26
26
  export * from "./utils/environment.js";
27
27
  export * from "./utils/history.js";
28
+ export * from "./utils/flaky.js";
28
29
  export * from "./utils/identity.js";
29
30
  export * from "./utils/strings.js";
30
31
  export * from "./utils/dictionary.js";
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./constants.js";
2
2
  export * from "./ci.js";
3
3
  export * from "./gitFlow.js";
4
+ export * from "./resolutions.js";
4
5
  export * from "./metrics.js";
5
6
  export * from "./config.js";
6
7
  export * from "./static.js";
@@ -16,6 +17,7 @@ export * from "./utils/status.js";
16
17
  export * from "./utils/successRate.js";
17
18
  export * from "./utils/environment.js";
18
19
  export * from "./utils/history.js";
20
+ export * from "./utils/flaky.js";
19
21
  export * from "./utils/identity.js";
20
22
  export * from "./utils/strings.js";
21
23
  export * from "./utils/dictionary.js";
package/dist/model.d.ts CHANGED
@@ -57,6 +57,7 @@ export interface TestResult {
57
57
  known: boolean;
58
58
  resolution?: ResolutionCategory;
59
59
  resolutionComment?: string;
60
+ resolutionExpiresAt?: string;
60
61
  transition?: TestStatusTransition;
61
62
  retryHash: string | null;
62
63
  isRetry: boolean;
@@ -1,6 +1,7 @@
1
1
  import type { TestLink } from "./metadata.js";
2
- import type { TestError, TestStatus } from "./model.js";
2
+ import type { TestError, TestResult, TestStatus } from "./model.js";
3
3
  export type ResolutionCategory = "issue" | "muted" | "accepted";
4
+ export type MutedResolutionState = "active" | "outdated" | "permanent";
4
5
  export interface ResolutionLinkTemplate {
5
6
  nameTemplate?: string;
6
7
  urlTemplate: string;
@@ -22,8 +23,19 @@ export interface IssueResolutionRule extends ResolutionMatcher {
22
23
  export interface IgnoredResolutionRule extends ResolutionMatcher {
23
24
  resolution: "muted" | "accepted";
24
25
  comment: string;
26
+ expiresAt?: string;
27
+ }
28
+ export interface MutedResolutionRule extends IgnoredResolutionRule {
29
+ resolution: "muted";
30
+ }
31
+ export interface AcceptedResolutionRule extends IgnoredResolutionRule {
32
+ resolution: "accepted";
25
33
  }
26
34
  export type ResolutionRule = IssueResolutionRule | IgnoredResolutionRule;
35
+ type ResolutionStateSource = Pick<TestResult, "resolution" | "resolutionExpiresAt">;
36
+ export declare const parseResolutionExpiresAt: (value: string) => number | undefined;
37
+ export declare const getMutedResolutionState: (testResult: ResolutionStateSource, now?: number) => MutedResolutionState | undefined;
38
+ export declare const isIgnoredResolution: (testResult: ResolutionStateSource, now?: number) => boolean;
27
39
  export interface ResolutionsConfig {
28
40
  knownIssuesPath?: string;
29
41
  links?: Record<string, ResolutionLinkTemplate>;
@@ -48,3 +60,4 @@ export interface KnownIssueRecord extends ResolutionIssue {
48
60
  export interface KnownIssuesFile {
49
61
  resolutionIssues: KnownIssueRecord[];
50
62
  }
63
+ export {};
@@ -1 +1,39 @@
1
- export {};
1
+ export const parseResolutionExpiresAt = (value) => {
2
+ const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-](\d{2}):(\d{2}))$/.exec(value);
3
+ if (!match) {
4
+ return undefined;
5
+ }
6
+ const [, yearValue, monthValue, dayValue, hourValue, minuteValue, secondValue, offsetHour, offsetMinute] = match;
7
+ const year = Number(yearValue);
8
+ const month = Number(monthValue);
9
+ const day = Number(dayValue);
10
+ const hour = Number(hourValue);
11
+ const minute = Number(minuteValue);
12
+ const second = Number(secondValue);
13
+ const leapYear = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
14
+ const daysInMonth = [31, leapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1];
15
+ if (year <= 0 ||
16
+ daysInMonth === undefined ||
17
+ day < 1 ||
18
+ day > daysInMonth ||
19
+ hour > 23 ||
20
+ minute > 59 ||
21
+ second > 59 ||
22
+ (offsetHour !== undefined && (Number(offsetHour) > 23 || Number(offsetMinute) > 59))) {
23
+ return undefined;
24
+ }
25
+ const timestamp = new Date(value).getTime();
26
+ return Number.isFinite(timestamp) ? timestamp : undefined;
27
+ };
28
+ export const getMutedResolutionState = (testResult, now = Date.now()) => {
29
+ if (testResult.resolution !== "muted") {
30
+ return undefined;
31
+ }
32
+ if (testResult.resolutionExpiresAt === undefined) {
33
+ return "permanent";
34
+ }
35
+ const expiresAt = parseResolutionExpiresAt(testResult.resolutionExpiresAt);
36
+ return expiresAt === undefined || now >= expiresAt ? "outdated" : "active";
37
+ };
38
+ export const isIgnoredResolution = (testResult, now = Date.now()) => testResult.resolution === "accepted" ||
39
+ (testResult.resolution === "muted" && getMutedResolutionState(testResult, now) !== "outdated");
@@ -0,0 +1,5 @@
1
+ import type { FlakyDetectionConfig } from "../config.js";
2
+ import type { HistoryTestResult } from "../history.js";
3
+ import type { TestResult } from "../model.js";
4
+ export type FlakinessOptions = Pick<FlakyDetectionConfig, "historyDepth" | "stabilizationPeriod">;
5
+ export declare const getTestFlakiness: (current: TestResult, history: (HistoryTestResult | undefined)[], options?: FlakinessOptions) => boolean | undefined;
@@ -0,0 +1,44 @@
1
+ const SIGNIFICANT_STATUSES = new Set(["passed", "failed", "broken"]);
2
+ export const getTestFlakiness = (current, history, options = {}) => {
3
+ const { historyDepth = 10, stabilizationPeriod = 5 } = options;
4
+ if (historyDepth === -1 || !SIGNIFICANT_STATUSES.has(current.status)) {
5
+ return undefined;
6
+ }
7
+ const statuses = [];
8
+ for (const result of history) {
9
+ if (result === undefined) {
10
+ break;
11
+ }
12
+ if (result.id === current.id || !SIGNIFICANT_STATUSES.has(result.status)) {
13
+ continue;
14
+ }
15
+ statuses.push(result.status);
16
+ if (historyDepth > 0 && statuses.length === historyDepth) {
17
+ break;
18
+ }
19
+ }
20
+ if (statuses.length === 0) {
21
+ return undefined;
22
+ }
23
+ statuses.reverse();
24
+ statuses.push(current.status);
25
+ const period = historyDepth > 0 ? Math.min(stabilizationPeriod, historyDepth + 1) : stabilizationPeriod;
26
+ let anchor = 0;
27
+ let streak = 0;
28
+ for (let index = 0; index < statuses.length; index++) {
29
+ streak = index > 0 && statuses[index] === statuses[index - 1] ? streak + 1 : 1;
30
+ if (streak >= period) {
31
+ anchor = index;
32
+ }
33
+ }
34
+ let changes = 0;
35
+ for (let index = anchor + 1; index < statuses.length; index++) {
36
+ if (statuses[index] !== statuses[index - 1]) {
37
+ changes++;
38
+ }
39
+ }
40
+ if (changes <= 1) {
41
+ return false;
42
+ }
43
+ return !(changes === 2 && statuses[anchor] === "passed" && current.status === "passed");
44
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/core-api",
3
- "version": "3.21.0",
3
+ "version": "3.22.1",
4
4
  "description": "Allure Core API",
5
5
  "keywords": [
6
6
  "allure"
@@ -21,25 +21,27 @@
21
21
  "scripts": {
22
22
  "build": "run clean && tsc --project ./tsconfig.json",
23
23
  "clean": "rimraf ./dist",
24
- "test": "rimraf ./out && vitest run",
24
+ "test": "rimraf out && vp test run",
25
25
  "test:unit": "yarn test",
26
- "lint": "oxlint --import-plugin src test features stories",
27
- "lint:fix": "oxlint --import-plugin --fix src test features stories"
26
+ "lint": "vp lint --import-plugin src test features stories",
27
+ "lint:fix": "vp lint --import-plugin --fix src test features stories"
28
28
  },
29
29
  "dependencies": {
30
30
  "d3-shape": "^3.2.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@allurereport/test-config": "3.21.0",
33
+ "@allurereport/common-config": "3.22.1",
34
34
  "@types/d3-shape": "^3.1.8",
35
35
  "@types/node": "^20",
36
- "@vitest/coverage-istanbul": "^4.1.0",
36
+ "@vitest/coverage-istanbul": "5.0.4",
37
37
  "@vitest/runner": "^2",
38
- "@vitest/snapshot": "^5.0.1",
38
+ "@vitest/snapshot": "5.0.4",
39
39
  "allure-js-commons": "^3",
40
40
  "allure-vitest": "^3",
41
41
  "rimraf": "^6",
42
42
  "typescript": "^5",
43
- "vitest": "^4.1.0"
43
+ "vite": "@voidzero-dev/vite-plus-core@1.2.0",
44
+ "vite-plus": "1.2.0",
45
+ "vitest": "5.0.4"
44
46
  }
45
47
  }