Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 35 additions & 35 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
"url": "git+https://github.com/joomcode/e2ed.git"
},
"dependencies": {
"@playwright/test": "1.55.0",
"@playwright/test": "1.56.0",
"create-locator": "0.0.27",
"get-modules-graph": "0.0.11",
"sort-json-keys": "1.0.3"
},
"devDependencies": {
"@playwright/browser-chromium": "1.55.0",
"@types/node": "24.3.0",
"@playwright/browser-chromium": "1.56.0",
"@types/node": "24.7.0",
"@typescript-eslint/eslint-plugin": "7.18.0",
"@typescript-eslint/parser": "7.18.0",
"assert-modules-support-case-insensitive-fs": "1.0.1",
Expand All @@ -45,7 +45,7 @@
"eslint-plugin-typescript-sort-keys": "3.3.0",
"husky": "9.1.7",
"prettier": "3.6.2",
"typescript": "5.9.2"
"typescript": "5.9.3"
},
"peerDependencies": {
"@types/node": ">=20",
Expand Down
4 changes: 2 additions & 2 deletions src/actions/asserts/assertUrlMatchRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import {assertValueIsDefined, assertValueIsNotNull} from '../../utils/asserts';
import {log} from '../../utils/log';

import type {Route} from '../../Route';
import type {Url} from '../../types/internal';
import type {MaybePromise, Url} from '../../types/internal';

type MaybeUrlOrPath = Url | string | null | undefined;

/**
* Asserts that url or url path (which can be wrapped in a promise) match route.
*/
export const assertUrlMatchRoute = async (
maybeUrlOrPath: MaybeUrlOrPath | Promise<MaybeUrlOrPath>,
maybeUrlOrPath: MaybePromise<MaybeUrlOrPath>,
route: Route<unknown>,
): Promise<void> => {
const {routeParams} = route;
Expand Down
5 changes: 5 additions & 0 deletions src/types/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ export type LogEvent = Readonly<{
type: LogEventType;
}>;

/**
* Log event with children (for groupping of `TestRun` steps).
*/
export type LogEventWithChildren = LogEvent & Readonly<{children: readonly LogEventWithChildren[]}>;

/**
* EndTestRun event (on closing test).
* @internal
Expand Down
4 changes: 4 additions & 0 deletions src/types/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ declare global {
class?: string;
}
>;
} & {
button: {popovertarget?: string};
input: {popovertarget?: string};
meta: {charset?: string};
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type {ConsoleMessage, ConsoleMessageType} from './console';
export type {UtcTimeInMs} from './date';
export type {DeepMutable, DeepPartial, DeepReadonly, DeepRequired} from './deep';
export type {E2edPrintedFields, JsError} from './errors';
export type {LogEvent, Onlog, TestRunEvent} from './events';
export type {LogEvent, LogEventWithChildren, Onlog, TestRunEvent} from './events';
export type {Fn, MergeFunctions} from './fn';
export type {
FullMocksConfig,
Expand Down
2 changes: 1 addition & 1 deletion src/types/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export type {E2edEnvironment} from './environment';
export type {E2edPrintedFields, JsError} from './errors';
/** @internal */
export type {GlobalErrorType, MaybeWithIsTestRunBroken} from './errors';
export type {LogEvent, Onlog, TestRunEvent} from './events';
export type {LogEvent, LogEventWithChildren, Onlog, TestRunEvent} from './events';
/** @internal */
export type {EndTestRunEvent, FullEventsData} from './events';
export type {Fn, MergeFunctions} from './fn';
Expand Down
3 changes: 1 addition & 2 deletions src/types/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type {EndE2edReason, ExitCode, TestRunStatus} from '../constants/internal
import type {ApiStatistics} from './apiStatistics';
import type {FullPackConfig} from './config';
import type {UtcTimeInMs} from './date';
import type {SafeHtml} from './html';
import type {TestFilePath} from './paths';
import type {StartInfo} from './startInfo';
import type {FullTestRun, LiteTestRun, RunHash, RunId} from './testRun';
Expand Down Expand Up @@ -99,7 +98,7 @@ export type ReportClientState = {
readonly fullTestRuns: readonly FullTestRun[];
readonly internalDirectoryName: string;
lengthOfReadedJsonReportDataParts: number;
readonly locator: LocatorFunction<SafeHtml>;
readonly locator: LocatorFunction;
readonly pathToScreenshotsDirectoryForReport: string | null;
readonly readJsonReportDataObservers: MutationObserver[];
reportClientData?: ReportClientData;
Expand Down
6 changes: 3 additions & 3 deletions src/utils/getDurationWithUnits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
* Get the duration of time interval in hours, minutes, seconds and milliseconds.
* `getDurationWithUnits(1213)` = `'1s 213ms'`.
* Should be a pure function without dependencies in the form of a function declaration,
* because it is used in the JS code of HTML report.
* because it is used in the JS client code of HTML report.
*/
export function getDurationWithUnits(durationInMs: number): string {
export const getDurationWithUnits = (durationInMs: number): string => {
const msInSecond = 1_000;
const timeMultiplicator = 60;

Expand Down Expand Up @@ -37,4 +37,4 @@ export function getDurationWithUnits(durationInMs: number): string {
}

return parts.slice(0, 2).join(' ') || '0ms';
}
};
12 changes: 6 additions & 6 deletions src/utils/parse/parseValueAsJsonIfNeeded.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ type Return = Readonly<{hasParseError: boolean; value: unknown}>;

/**
* Parses `unknown` value as JSON, if needed.
* If `isoValueInJsonFormat` is `true`, then parses value as JSON and saves parse error.
* If `isoValueInJsonFormat` is `false`, then returns value as is.
* If `isoValueInJsonFormat` is `undefined`, then safely tries to parse value as JSON.
* If `isValueInJsonFormat` is `true`, then parses value as JSON and saves parse error.
* If `isValueInJsonFormat` is `false`, then returns value as is.
* If `isValueInJsonFormat` is `undefined`, then safely tries to parse value as JSON.
*/
export const parseValueAsJsonIfNeeded = (
originalValue: unknown,
isoValueInJsonFormat?: boolean,
isValueInJsonFormat?: boolean,
): Return => {
let hasParseError = false;
let value = originalValue;

if (isoValueInJsonFormat === true) {
if (isValueInJsonFormat === true) {
try {
value = parseMaybeEmptyValueAsJson(originalValue);
} catch {
hasParseError = true;
}
} else if (isoValueInJsonFormat !== false) {
} else if (isValueInJsonFormat !== false) {
try {
value = parseMaybeEmptyValueAsJson(originalValue);
} catch {}
Expand Down
7 changes: 5 additions & 2 deletions src/utils/report/client/addOnClickOnClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ declare const reportClientState: ReportClientState;
* This base client function should not use scope variables (except other base functions).
* @internal
*/
export function addOnClickOnClass(className: string, onclick: (event: HTMLElement) => void): void {
export const addOnClickOnClass = (
className: string,
onclick: (element: HTMLElement) => void,
): void => {
let {clickListeners} = reportClientState;

if (!clickListeners) {
Expand All @@ -34,4 +37,4 @@ export function addOnClickOnClass(className: string, onclick: (event: HTMLElemen
}

clickListeners[className] = onclick;
}
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import {assertValueIsDefined as clientAssertValueIsDefined} from './assertValueIsDefined';
import {maybeRenderApiStatistics as clientMaybeRenderApiStatistics} from './maybeRenderApiStatistics';
import {renderTestRunDetails as clientRenderTestRunDetails} from './render';
import {
MaybeApiStatistics as clientMaybeApiStatistics,
TestRunDetails as clientTestRunDetails,
} from './render';

import type {ReportClientState, RunHash, SafeHtml} from '../../../types/internal';
import type {ReportClientState, RunHash} from '../../../types/internal';

const assertValueIsDefined: typeof clientAssertValueIsDefined = clientAssertValueIsDefined;
const maybeRenderApiStatistics = clientMaybeRenderApiStatistics;
const renderTestRunDetails = clientRenderTestRunDetails;
const MaybeApiStatistics = clientMaybeApiStatistics;
const TestRunDetails = clientTestRunDetails;

declare const jsx: JSX.Runtime;
declare const reportClientState: ReportClientState;

/**
Expand Down Expand Up @@ -47,7 +50,7 @@ export function chooseTestRun(runHash: RunHash): void {

if (
!(previousHash in testRunDetailsElementsByHash) &&
!previousTestRunDetailsElement.classList.contains('test-details-empty')
!previousTestRunDetailsElement.classList.contains('empty-state')
) {
testRunDetailsElementsByHash[previousHash] = previousTestRunDetailsElement;
}
Expand All @@ -62,9 +65,9 @@ export function chooseTestRun(runHash: RunHash): void {
return;
}

let rightColumnHtml: SafeHtml | undefined = maybeRenderApiStatistics(runHash);
let rightColumnHtml = <MaybeApiStatistics runHash={runHash} />;

if (rightColumnHtml === undefined) {
if (rightColumnHtml.length === 0) {
const {fullTestRuns} = reportClientState;
const fullTestRun = fullTestRuns.find((testRun) => testRun.runHash === runHash);

Expand All @@ -77,7 +80,7 @@ export function chooseTestRun(runHash: RunHash): void {
return;
}

rightColumnHtml = renderTestRunDetails(fullTestRun);
rightColumnHtml = <TestRunDetails fullTestRun={fullTestRun} />;
}

e2edRightColumnContainer.innerHTML = String(rightColumnHtml);
Expand Down
Loading