diff --git a/CHANGELOG.md b/CHANGELOG.md index 43151a60b70d..c8acb9446da1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - `[@jest/fake-timers]` Exposing new modern timers function `advanceTimersToFrame()` which advances all timers by the needed milliseconds to execute callbacks currently scheduled with `requestAnimationFrame` ([#14598](https://github.com/jestjs/jest/pull/14598)) - `[jest-matcher-utils]` Add `SERIALIZABLE_PROPERTIES` to allow custom serialization of objects ([#14893](https://github.com/jestjs/jest/pull/14893)) - `[jest-mock]` Add support for the Explicit Resource Management proposal to use the `using` keyword with `jest.spyOn(object, methodName)` ([#14895](https://github.com/jestjs/jest/pull/14895)) +- `[jest-reporters]` Add support for [DEC mode 2026](https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036) - `[jest-runtime]` Exposing new modern timers function `jest.advanceTimersToFrame()` from `@jest/fake-timers` ([#14598](https://github.com/jestjs/jest/pull/14598)) - `[jest-runtime]` Support `import.meta.filename` and `import.meta.dirname` (available from [Node 20.11](https://nodejs.org/en/blog/release/v20.11.0)) ([#14854](https://github.com/jestjs/jest/pull/14854)) - `[jest-runtime]` Support `import.meta.resolve` ([#14930](https://github.com/jestjs/jest/pull/14930)) diff --git a/packages/jest-reporters/src/BaseReporter.ts b/packages/jest-reporters/src/BaseReporter.ts index 1e9f12a0e8e7..902167678486 100644 --- a/packages/jest-reporters/src/BaseReporter.ts +++ b/packages/jest-reporters/src/BaseReporter.ts @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import type {WriteStream} from 'tty'; import type { AggregatedResult, Test, @@ -12,7 +13,7 @@ import type { TestContext, TestResult, } from '@jest/test-result'; -import {preRunMessage} from 'jest-util'; +import {isInteractive, preRunMessage} from 'jest-util'; import type {Reporter, ReporterOnStartOptions} from './types'; const {remove: preRunMessageRemove} = preRunMessage; @@ -57,4 +58,16 @@ export default class BaseReporter implements Reporter { getLastError(): Error | undefined { return this._error; } + + protected __beginSynchronizedUpdate(write: WriteStream['write']): void { + if (isInteractive) { + write('\u001B[?2026h'); + } + } + + protected __endSynchronizedUpdate(write: WriteStream['write']): void { + if (isInteractive) { + write('\u001B[?2026l'); + } + } } diff --git a/packages/jest-reporters/src/DefaultReporter.ts b/packages/jest-reporters/src/DefaultReporter.ts index 288aafb26bd9..f0f3f0bf680e 100644 --- a/packages/jest-reporters/src/DefaultReporter.ts +++ b/packages/jest-reporters/src/DefaultReporter.ts @@ -53,8 +53,14 @@ export default class DefaultReporter extends BaseReporter { this.__wrapStdio(process.stdout); this.__wrapStdio(process.stderr); this._status.onChange(() => { + this.__beginSynchronizedUpdate( + this._globalConfig.useStderr ? this._err : this._out, + ); this.__clearStatus(); this.__printStatus(); + this.__endSynchronizedUpdate( + this._globalConfig.useStderr ? this._err : this._out, + ); }); } @@ -69,11 +75,17 @@ export default class DefaultReporter extends BaseReporter { buffer = []; // This is to avoid conflicts between random output and status text + this.__beginSynchronizedUpdate( + this._globalConfig.useStderr ? this._err : this._out, + ); this.__clearStatus(); if (string) { write(string); } this.__printStatus(); + this.__endSynchronizedUpdate( + this._globalConfig.useStderr ? this._err : this._out, + ); this._bufferedOutput.delete(flushBufferedOutput); }; @@ -194,9 +206,7 @@ export default class DefaultReporter extends BaseReporter { const testRetryReasons = testResult.retryReasons; if (testRetryReasons && testRetryReasons.length > 0) { this.log( - `${chalk.reset.inverse.bold.yellow( - ' LOGGING RETRY ERRORS ', - )} ${chalk.bold(testResult.fullName)}`, + `${chalk.reset.inverse.bold.yellow(' LOGGING RETRY ERRORS ')} ${chalk.bold(testResult.fullName)}`, ); for (const [index, retryReasons] of testRetryReasons.entries()) { let {message, stack} = separateMessageFromStack(retryReasons); @@ -219,11 +229,7 @@ export default class DefaultReporter extends BaseReporter { this.log(getResultHeader(result, this._globalConfig, config)); if (result.console) { this.log( - ` ${TITLE_BULLET}Console\n\n${getConsoleOutput( - result.console, - config, - this._globalConfig, - )}`, + ` ${TITLE_BULLET}Console\n\n${getConsoleOutput(result.console, config, this._globalConfig)}`, ); } }