From 90cdac4ef9a274b7ef64def1ae241ccf48713b1b Mon Sep 17 00:00:00 2001 From: abose Date: Thu, 18 Sep 2025 17:07:14 +0530 Subject: [PATCH 1/4] build: test runner show total time taken to run tests in ui --- test/BootstrapReporterView.js | 33 ++++++++++++++++++++++++++++++--- test/UnitTestReporter.js | 2 +- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/test/BootstrapReporterView.js b/test/BootstrapReporterView.js index dfcef27bb4..59c9df50e7 100644 --- a/test/BootstrapReporterView.js +++ b/test/BootstrapReporterView.js @@ -30,6 +30,24 @@ define(function (require, exports, module) { var _ = require("thirdparty/lodash"); + function formatMilliseconds(ms) { + const hours = Math.floor(ms / (1000 * 60 * 60)); + const minutes = Math.floor((ms % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((ms % (1000 * 60)) / 1000); + + let result = ''; + + if (hours) { + result = result + `${hours}-Hour `; + } + if (minutes) { + result = result + `${minutes}-Minutes `; + } + result = `${result}${seconds}-Seconds`; + + return result.trim(); + } + function _addPrintableContainer() { var container = $(`
@@ -236,17 +254,26 @@ define(function (require, exports, module) { } }; - BootstrapReporterView.prototype._handleRunnerEnd = function (event, reporter) { + BootstrapReporterView.prototype._handleRunnerEnd = function (event, reporter, runnerResult) { if (this.$info) { this.$info.toggleClass("alert-info", false); window.testResults.passed = reporter.passed; + + // Get total time from the reporter's runInfo if available + let totalTime = null; + if (runnerResult && runnerResult.totalTime) { + totalTime = runnerResult.totalTime; + } + + let timeText = totalTime ? ` (Done in ${formatMilliseconds(totalTime)})` : ''; + if (reporter.passed) { - this.$info.toggleClass("alert-success", true).text("Complete. No failures."); + this.$info.toggleClass("alert-success", true).text("Complete. No failures." + timeText); } else { this.$info.toggleClass("alert-error", true).text( "Complete. See failures Below. If all tests have passed and no failures are seen below," + - "Check the debug console for errors. (search for 'Spec Error:' , 'Suite Error:' or Runner Error: in console)"); + "Check the debug console for errors. (search for 'Spec Error:' , 'Suite Error:' or Runner Error: in console)" + timeText); } window.playWrightRunComplete = true; } diff --git a/test/UnitTestReporter.js b/test/UnitTestReporter.js index 7cd02b7a39..995b623066 100644 --- a/test/UnitTestReporter.js +++ b/test/UnitTestReporter.js @@ -512,7 +512,7 @@ define(function (require, exports, module) { } } } - $(this).triggerHandler("runnerEnd", [this]); + $(this).triggerHandler("runnerEnd", [this, runner]); activeReporter = null; }; From 74fc67051f168a41cec7bc80703cc286a271b08a Mon Sep 17 00:00:00 2001 From: abose Date: Thu, 18 Sep 2025 17:21:29 +0530 Subject: [PATCH 2/4] build: test runner ux improvement show running timer --- test/BootstrapReporterView.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/BootstrapReporterView.js b/test/BootstrapReporterView.js index 59c9df50e7..f207fa4bf0 100644 --- a/test/BootstrapReporterView.js +++ b/test/BootstrapReporterView.js @@ -48,6 +48,14 @@ define(function (require, exports, module) { return result.trim(); } + function formatElapsedTime(ms) { + const totalSeconds = Math.floor(ms / 1000); + const hours = Math.floor(totalSeconds / 3600); + const minutes = Math.floor((totalSeconds % 3600) / 60); + const seconds = totalSeconds % 60; + return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; + } + function _addPrintableContainer() { var container = $(`
@@ -247,14 +255,36 @@ define(function (require, exports, module) { if (reporter.activeSpecCount) { this._showProgressBar(); + // display running timer + this.$timer = $('
⏱️ 00:00:00
'); + this.$resultsContainer.append(this.$timer); + // display current running test this.$info = $('
'); this.$resultsContainer.append(this.$info); this.$resultsContainer.append($('
')); + + // start the running timer + this.testStartTime = Date.now(); + this.runningTimer = setInterval(() => { + if (this.$timer) { + this.$timer.text('⏱️ ' + formatElapsedTime(Date.now() - this.testStartTime)); + } + }, 1000); } }; BootstrapReporterView.prototype._handleRunnerEnd = function (event, reporter, runnerResult) { + // Stop and cleanup the running timer + if (this.runningTimer) { + clearInterval(this.runningTimer); + this.runningTimer = null; + this.testStartTime = null; + } + if (this.$timer) { + this.$timer.hide(); + } + if (this.$info) { this.$info.toggleClass("alert-info", false); From 40c02a4a81b6b1a85bafad96b4a23aea7c396b05 Mon Sep 17 00:00:00 2001 From: abose Date: Thu, 18 Sep 2025 17:26:40 +0530 Subject: [PATCH 3/4] build: test runner ux improvement show running timer --- test/BootstrapReporterView.js | 37 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/test/BootstrapReporterView.js b/test/BootstrapReporterView.js index f207fa4bf0..228fd160a9 100644 --- a/test/BootstrapReporterView.js +++ b/test/BootstrapReporterView.js @@ -255,35 +255,27 @@ define(function (require, exports, module) { if (reporter.activeSpecCount) { this._showProgressBar(); - // display running timer - this.$timer = $('
⏱️ 00:00:00
'); - this.$resultsContainer.append(this.$timer); - // display current running test this.$info = $('
'); this.$resultsContainer.append(this.$info); this.$resultsContainer.append($('
')); - - // start the running timer - this.testStartTime = Date.now(); - this.runningTimer = setInterval(() => { - if (this.$timer) { - this.$timer.text('⏱️ ' + formatElapsedTime(Date.now() - this.testStartTime)); - } - }, 1000); } }; BootstrapReporterView.prototype._handleRunnerEnd = function (event, reporter, runnerResult) { - // Stop and cleanup the running timer + // Stop the running timer and mark as completed if (this.runningTimer) { clearInterval(this.runningTimer); this.runningTimer = null; + + // Show final time with completed status + if (this.$timer && this.testStartTime) { + const finalTime = formatElapsedTime(Date.now() - this.testStartTime); + this.$timer.text('🏁 ' + finalTime + ' (Completed)'); + this.$timer.css('color', '#28a745'); // green color for completed + } this.testStartTime = null; } - if (this.$timer) { - this.$timer.hide(); - } if (this.$info) { this.$info.toggleClass("alert-info", false); @@ -317,6 +309,19 @@ define(function (require, exports, module) { }; BootstrapReporterView.prototype._handleSpecStart = function (event, reporter, specName) { + // Create and start timer on first spec if not already created + if (!this.$timer && this.$info) { + this.$timer = $('
⏱️ 00:00:00
'); + this.$timer.insertBefore(this.$info); + + this.testStartTime = Date.now(); + this.runningTimer = setInterval(() => { + if (this.$timer) { + this.$timer.text('⏱️ ' + formatElapsedTime(Date.now() - this.testStartTime)); + } + }, 1000); + } + this.$info.text("Running " + specName); }; From 1c0bb3c93d858ac2d9fc22839b850c298593cbde Mon Sep 17 00:00:00 2001 From: abose Date: Thu, 18 Sep 2025 18:21:14 +0530 Subject: [PATCH 4/4] build: increase waitsFor poll to 30ms from 10 to increase integ test stability --- test/SpecRunner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SpecRunner.js b/test/SpecRunner.js index 0e0bf45447..2fa1677ed1 100644 --- a/test/SpecRunner.js +++ b/test/SpecRunner.js @@ -109,7 +109,7 @@ window.deferredToPromise = jsPromise; * @param pollInterval in millis, default poll interval is 10ms * @returns {*} */ -function awaitsFor(pollFn, _timeoutMessageOrMessageFn, timeoutms = 2000, pollInterval = 10){ +function awaitsFor(pollFn, _timeoutMessageOrMessageFn, timeoutms = 2000, pollInterval = 30){ if(typeof _timeoutMessageOrMessageFn === "number"){ timeoutms = _timeoutMessageOrMessageFn; pollInterval = timeoutms;