Skip to content

test_runner: write timestamp as first line in watch mode #59153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

OkunadeNaheem
Copy link

I added an event emitter ->timestamp in tests_stream.js file and then call the event emitter timestamp whenever the --watch is triggered through restartTestFile() in runner.js file

timestamp eventemitter being called then logs the timestamp message(current date and time) in this format

[21/07/2025 21:24:13] INFO: Test restarted

Refs: #57206

Ensure that the timestamp emitted by TestsStream#timeStamp()
is always written as the first line when watch mode is active.
This improves clarity in test restarts under --watch, making
logs easier to follow.

Refs: nodejs#57206
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/test_runner

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem. labels Jul 21, 2025
Comment on lines +153 to +156
// This event emitter logs a timestamp whenever a test restarts because of changes in any related files.
timeStamp(type, data) {
process.stdout.write(`\n[${new Date().toLocaleString('en-GB').replace(',', '')}] INFO: Test restarted\n`);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should emit an event, right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, timestamp event.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to call kEmitMessage in order to actually emit the event.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, I see. I will correct that.

something like this:
opts.root.reporterkEmitMessage;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite, in the timeStamp function, you should call this[kEmitMessage]. Look at the other methods for reference

Comment on lines +500 to +503
// Emit the 'test:restarted' event if a timeStamp reporter is available.
if (opts.root?.reporter?.timeStamp) {
opts.root.reporter.timeStamp('test:restarted', { __proto__: null, file });
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a case where timeStamp won't be callable? I don't think so?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there is no case, because it is only called when the --watch flag is used, and the only condition for it to be triggered is when there is a change in the test file or the file being tested.

But what if there is no actual change in the test case result? It still runs regardless.
This goes beyond the scope of this issue. I would have to modify the working process of file_watcher.js for the --watch flag so that --watch would not be triggered unless there is a change in the actual test result — based on a comparison with the previous result (from the code being tested).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you misunderstood. I'm saying you don't need the if clause since there isn't a case where that function isn't callable (it's never undefined)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yeah, it is never undefined. I will take that out.
Thanks for the feedback.

is this not something that needs to be worked on tho?

But what if there is no actual change in the test case result? It still runs regardless.\nThis goes beyond the scope of this issue. I would have to modify the working process of file_watcher.js for the --watch flag so that --watch would not be triggered unless there is a change in the actual test result — based on a comparison with the previous result (from the code being tested).

Comment on lines +20 to +22
common.mustCall(() => {
reporter.timeStamp('test:restarted', { file: 'dummy.js' });
})();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are calling the mustCall, you should make the event's callback the mustCall instead (on(something, common.mustCall()))

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right. I would also have to add about three lines of code that make actual changes to the file being tested.
But this cuts off the test and restarts it. There no way for me to make an actual change to the file being tested without the test execution not generating an error.

Previous Detail: this run on --watch
Here is the previous test code I wrote:

const fs = require('fs');
const { run } = require('internal/test_runner/runner');
const { parseCommandLine } = require('internal/test_runner/utils');
const { join } = require('path');
const common = require('../common');
const assert = require('assert');

const testFile = join(__dirname, '../fixtures/test-runner/test_only.js');

const options = {
...parseCommandLine(),
globPatterns: [testFile],
watch: true,
isolation: 'process',
cwd: __dirname,
};

const reporter = run(options);

let timeStampCalled = false;

reporter.timeStamp = common.mustCall((type, data) => {
assert.strictEqual(type, 'test:restarted');
assert.ok(data.file);
timeStampCalled = true;
});

reporter.on('test:summary', common.mustCall((data) => {
assert.ok(data);
assert.ok(typeof data.success === 'boolean');
assert.ok(timeStampCalled, 'Expected timeStamp to be called before summary');
}));

// Trigger file change after 500ms to activate watch mode
setTimeout(() => {
fs.appendFileSync(testFile, '\n');
}, 500);

// Failsafe timeout
setTimeout(() => {
if (!timeStampCalled) {
console.error('[Test] FAIL: timeStamp() was not called in time');
process.exit(1);
}
}, 3000);

Comment on lines +501 to +502
if (opts.root?.reporter?.timeStamp) {
opts.root.reporter.timeStamp('test:restarted', { __proto__: null, file });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @OkunadeNaheem , we already have the restart event being dispatched here

opts.root.reporter[kEmitMessage]('test:watch:restarted');

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do I utilise the timestamp feature?
Tho I saw that some changes were made by @JacopoPatroclo but I did not see how to utilise, so I thought the changes was not a solution for the timestamp feature.

Comment on lines +154 to +155
timeStamp(type, data) {
process.stdout.write(`\n[${new Date().toLocaleString('en-GB').replace(',', '')}] INFO: Test restarted\n`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this logic should be placed as part of the reporters, as a user might want to avoid this message in their report

// Flags: --expose-internals
'use strict';

const common = require('../common');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we might want to test the output of the runner instead of the TestsStream itself!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy