@@ -14,7 +14,7 @@ import type {
1414} from './types' ;
1515import { SupportedPageTypes , ValidationError } from './types' ;
1616import { t } from './i18n' ;
17- import { FileName , DirName , getWebappPath } from '@sap-ux/project-access' ;
17+ import { FileName , DirName , getWebappPath , updatePackageScript } from '@sap-ux/project-access' ;
1818import type { Logger } from '@sap-ux/logger' ;
1919import { getAppFeatures } from './utils/modelUtils' ;
2020import {
@@ -25,6 +25,8 @@ import {
2525 readHtmlTargetFromQUnitJs ,
2626 type JourneyRunnerPage
2727} from './utils/opaQUnitUtils' ;
28+ import { getPackageScripts } from '@sap-ux/fiori-generator-shared' ;
29+ import { readHashFromFlpSandbox } from './utils/flpSandboxUtils' ;
2830
2931/**
3032 * Generate OPA test files for a Fiori elements for OData V4 application.
@@ -80,12 +82,12 @@ export async function generateOPAFiles(
8082 if ( hasJourneyRunner ) {
8183 writeJourneyFiles ( appFeatures , writeContext , true , true , virtualOPA5Configured ) ;
8284 } else {
83- editor . move ( join ( testOutDirPath , 'integration' , '**' ) , join ( testOutDirPath , 'integration_old' ) ) ;
84-
85- await addIntegrationOldToGitignore ( basePath , editor ) ;
86- const htmlTarget = readHtmlTargetFromQUnitJs ( testOutDirPath , editor ) ?? config . htmlTarget ;
87- const standaloneConfig = { ... config , htmlTarget } ;
88- const standaloneWriteContext : WriteContext = { ... writeContext , config : standaloneConfig } ;
85+ const standaloneWriteContext = await resolveStandaloneWriteContext (
86+ basePath ,
87+ testOutDirPath ,
88+ writeContext ,
89+ editor
90+ ) ;
8991 if ( ! virtualOPA5Configured ) {
9092 writeCommonAndPageFiles ( standaloneWriteContext , rootCommonTemplateDirPath ) ;
9193 }
@@ -99,6 +101,69 @@ export async function generateOPAFiles(
99101 return editor ;
100102}
101103
104+ /**
105+ * Resolves the write context for standalone mode when no JourneyRunner.js exists yet.
106+ * Moves any existing integration folder to integration_old, or adds the int-test script
107+ * and resolves the htmlTarget from flpSandbox.html if present.
108+ *
109+ * @param basePath - the absolute target path of the application
110+ * @param testOutDirPath - output test directory (.../webapp/test)
111+ * @param writeContext - shared write context to base the resolved context on
112+ * @param editor - a reference to a mem-fs editor
113+ * @returns a new WriteContext with the resolved htmlTarget
114+ */
115+ async function resolveStandaloneWriteContext (
116+ basePath : string ,
117+ testOutDirPath : string ,
118+ writeContext : WriteContext ,
119+ editor : Editor
120+ ) : Promise < WriteContext > {
121+ const { config } = writeContext ;
122+ let htmlTarget = readHtmlTargetFromQUnitJs ( testOutDirPath , editor ) ?? config . htmlTarget ;
123+
124+ if ( existsSync ( join ( testOutDirPath , 'integration' ) ) ) {
125+ editor . move ( join ( testOutDirPath , 'integration' , '**' ) , join ( testOutDirPath , 'integration_old' ) ) ;
126+ await addIntegrationOldToGitignore ( basePath , editor ) ;
127+ } else {
128+ const hasIntTestScript = checkScriptInPackageJson ( editor , basePath , 'int-test' ) ;
129+ if ( ! hasIntTestScript ) {
130+ const script = getPackageScripts ( { localOnly : false , addTest : true } ) [ 'int-test' ] ;
131+ if ( script ) {
132+ await updatePackageScript ( basePath , 'int-test' , script , editor ) ;
133+ }
134+ }
135+ if ( existsSync ( join ( testOutDirPath , 'flpSandbox.html' ) ) ) {
136+ const hashFromFlpSandbox = readHashFromFlpSandbox (
137+ join ( 'test' , 'flpSandbox.html' ) ,
138+ await getWebappPath ( basePath ) ,
139+ editor
140+ ) ;
141+ if ( hashFromFlpSandbox ) {
142+ htmlTarget = `test/flpSandbox.html#${ hashFromFlpSandbox } ` ;
143+ }
144+ }
145+ }
146+
147+ return { ...writeContext , config : { ...config , htmlTarget } } ;
148+ }
149+
150+ /**
151+ * Checks whether a script with the given name exists in the package.json.
152+ *
153+ * @param editor - a reference to a mem-fs editor
154+ * @param basePath - the root folder of the app
155+ * @param scriptName - the name of the script to check for
156+ * @returns true if the script exists, false otherwise
157+ */
158+ function checkScriptInPackageJson ( editor : Editor , basePath : string , scriptName : string ) : boolean {
159+ const packageJsonPath = join ( basePath , FileName . Package ) ;
160+ if ( ! editor . exists ( packageJsonPath ) ) {
161+ return false ;
162+ }
163+ const packageJson = editor . readJSON ( packageJsonPath ) as { scripts ?: Record < string , string > } ;
164+ return ! ! packageJson . scripts ?. [ scriptName ] ;
165+ }
166+
102167/**
103168 * Reads the manifest for an app.
104169 *
0 commit comments