@@ -82,19 +82,19 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
8282
8383 const testData : Map < vscode . TestItem , TestInfo > = new Map ( ) ;
8484
85+ const ts : Testsuite = getTestsuite ( ) ;
8586 let rootItem : vscode . TestItem ;
87+
8688 controller . refreshHandler = async function ( ) {
8789 controller . items . replace ( [ ] ) ;
8890 testData . clear ( ) ;
8991
90- const ts : Testsuite = getTestsuite ( ) ;
91-
9292 if ( ! existsSync ( ts . uri . fsPath ) ) {
9393 return ;
9494 }
9595
9696 rootItem = this . createTestItem (
97- getRootItemId ( ) ,
97+ getRootItemId ( ts ) ,
9898 vscode . workspace . asRelativePath ( ts . uri ) ,
9999 ts . uri ,
100100 ) ;
@@ -179,8 +179,6 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
179179 request : vscode . TestRunRequest ,
180180 token : vscode . CancellationToken ,
181181 ) : Promise < void > => {
182- const ts = getTestsuite ( ) ;
183-
184182 const enableEventSystem : boolean =
185183 vscode . workspace . getConfiguration ( 'e3-testsuite' ) . get ( 'enableEventSystem' ) ?? true ;
186184
@@ -193,7 +191,7 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
193191 }
194192
195193 function onlyRootSelected ( rq : vscode . TestRunRequest ) {
196- return rq . include ?. length === 1 && rq . include [ 0 ] . id === getRootItemId ( ) ;
194+ return rq . include ?. length === 1 && rq . include [ 0 ] . id === getRootItemId ( ts ) ;
197195 }
198196
199197 if ( request . include && ! onlyRootSelected ( request ) ) {
@@ -536,7 +534,7 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
536534 reportResult ( run , result . status , targetItem , messages ) ;
537535 }
538536
539- if ( existsSync ( getTestsuite ( ) . uri . fsPath ) ) {
537+ if ( existsSync ( ts . uri . fsPath ) ) {
540538 void vscode . window . withProgress (
541539 {
542540 location : vscode . ProgressLocation . Notification ,
@@ -551,13 +549,47 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
551549 }
552550}
553551
554- function getRootItemId ( ) : string {
555- return getTestsuite ( ) . uri . toString ( ) ;
552+ function getRootItemId ( ts : Testsuite ) : string {
553+ return ts . uri . toString ( ) ;
556554}
557555
558- function getTestsuite ( ) {
556+ /**
557+ * Retrieves the testsuite configuration for the current workspace.
558+ *
559+ * This function determines the testsuite path by first checking the user's configuration.
560+ * If no path is configured, it automatically searches through predefined candidate locations
561+ * and uses the first existing file. It also retrieves the Python executable configuration.
562+ *
563+ * @returns {Testsuite } An object containing the testsuite URI and Python executable path
564+ *
565+ * @remarks
566+ * The function searches for testsuite files in the following order:
567+ * 1. 'testsuite.py' in the workspace root
568+ * 2. 'testsuite/testsuite.py' relative to workspace root
569+ *
570+ * If no testsuite file is found, it defaults to the first candidate path.
571+ * The Python executable defaults to 'python' if not configured.
572+ *
573+ * @throws Will throw an error if no workspace folders are available
574+ */
575+ export function getTestsuite ( ) {
576+ const wsPath = vscode . workspace . workspaceFolders ! [ 0 ] . uri . fsPath ;
577+
559578 const config = vscode . workspace . getConfiguration ( 'e3-testsuite' ) ;
560- const tsPath = config . get < string > ( 'testsuitePath' ) ?? 'testsuite.py' ;
579+ const configuredPath = config . get < string > ( 'testsuitePath' ) ;
580+
581+ let tsPath ;
582+ if ( configuredPath ) {
583+ tsPath = configuredPath ;
584+ } else {
585+ /**
586+ * Automatically look through candidates and return the first one that exists.
587+ */
588+ const candidates = [ 'testsuite.py' , path . join ( 'testsuite' , 'testsuite.py' ) ] ;
589+ tsPath =
590+ candidates . map ( ( p ) => path . join ( wsPath , p ) ) . find ( ( p ) => existsSync ( p ) ) ?? candidates [ 0 ] ;
591+ }
592+
561593 const python = config . get < string > ( 'python' ) ?? 'python' ;
562594
563595 const tsAbsUri : vscode . Uri = path . isAbsolute ( tsPath )
0 commit comments