@sap-ux/ui5-test-writer 0.7.103 → 0.7.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fiori-elements-opa-writer.d.ts +8 -8
- package/dist/fiori-elements-opa-writer.js +100 -62
- package/dist/types.d.ts +8 -0
- package/dist/utils/listReportUtils.d.ts +21 -2
- package/dist/utils/listReportUtils.js +35 -2
- package/dist/utils/modelUtils.d.ts +3 -1
- package/dist/utils/modelUtils.js +3 -2
- package/dist/utils/opaQUnitUtils.d.ts +39 -0
- package/dist/utils/opaQUnitUtils.js +123 -4
- package/package.json +3 -3
- package/templates/v4/integration/ListReportJourney.js +1 -1
- package/templates/v4/integration/ObjectPageJourney.js +1 -3
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import type { Editor } from 'mem-fs-editor';
|
|
2
2
|
import type { Manifest } from '@sap-ux/project-access';
|
|
3
3
|
import type { Logger } from '@sap-ux/logger';
|
|
4
|
-
/**
|
|
5
|
-
* Reads the manifest for an app.
|
|
6
|
-
*
|
|
7
|
-
* @param fs - a reference to a mem-fs editor
|
|
8
|
-
* @param basePath - the root folder of the app
|
|
9
|
-
* @returns the manifest object. An exception is thrown if the manifest cannot be read.
|
|
10
|
-
*/
|
|
11
|
-
export declare function readManifest(fs: Editor, basePath: string): Manifest;
|
|
12
4
|
/**
|
|
13
5
|
* Generate OPA test files for a Fiori elements for OData V4 application.
|
|
14
6
|
* Note: this can potentially overwrite existing files in the webapp/test folder.
|
|
@@ -29,6 +21,14 @@ export declare function generateOPAFiles(basePath: string, opaConfig: {
|
|
|
29
21
|
appID?: string;
|
|
30
22
|
htmlTarget?: string;
|
|
31
23
|
}, metadata?: string, fs?: Editor, log?: Logger, standalone?: boolean): Promise<Editor>;
|
|
24
|
+
/**
|
|
25
|
+
* Reads the manifest for an app.
|
|
26
|
+
*
|
|
27
|
+
* @param fs - a reference to a mem-fs editor
|
|
28
|
+
* @param basePath - the root folder of the app
|
|
29
|
+
* @returns the manifest object. An exception is thrown if the manifest cannot be read.
|
|
30
|
+
*/
|
|
31
|
+
export declare function readManifest(fs: Editor, basePath: string): Manifest;
|
|
32
32
|
/**
|
|
33
33
|
* Generate a page object file for a Fiori elements for OData V4 application.
|
|
34
34
|
* Note: this doesn't modify other existing files in the webapp/test folder.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.readManifest = readManifest;
|
|
4
3
|
exports.generateOPAFiles = generateOPAFiles;
|
|
4
|
+
exports.readManifest = readManifest;
|
|
5
5
|
exports.generatePageObjectFile = generatePageObjectFile;
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
7
|
const node_fs_1 = require("node:fs");
|
|
@@ -12,6 +12,65 @@ const i18n_1 = require("./i18n");
|
|
|
12
12
|
const project_access_1 = require("@sap-ux/project-access");
|
|
13
13
|
const modelUtils_1 = require("./utils/modelUtils");
|
|
14
14
|
const opaQUnitUtils_1 = require("./utils/opaQUnitUtils");
|
|
15
|
+
/**
|
|
16
|
+
* Generate OPA test files for a Fiori elements for OData V4 application.
|
|
17
|
+
* Note: this can potentially overwrite existing files in the webapp/test folder.
|
|
18
|
+
*
|
|
19
|
+
* @param basePath - the absolute target path where the application will be generated
|
|
20
|
+
* @param opaConfig - parameters for the generation
|
|
21
|
+
* @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used
|
|
22
|
+
* @param opaConfig.htmlTarget - the name of the html that will be used in OPA journey file. If not specified, 'index.html' will be used
|
|
23
|
+
* @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id
|
|
24
|
+
* @param metadata - optional metadata for the OPA test generation
|
|
25
|
+
* @param fs - an optional reference to a mem-fs editor
|
|
26
|
+
* @param log - optional logger instance
|
|
27
|
+
* @param standalone - opa test generation run standalone, not during app generation
|
|
28
|
+
* @returns Reference to a mem-fs-editor
|
|
29
|
+
*/
|
|
30
|
+
async function generateOPAFiles(basePath, opaConfig, metadata, fs, log, standalone = false) {
|
|
31
|
+
const editor = fs ?? (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
|
|
32
|
+
const manifest = readManifest(editor, basePath);
|
|
33
|
+
const { applicationType, hideFilterBar } = getAppTypeAndHideFilterBarFromManifest(manifest);
|
|
34
|
+
const config = createConfig(manifest, opaConfig, hideFilterBar);
|
|
35
|
+
const rootCommonTemplateDirPath = (0, node_path_1.join)(__dirname, '../templates/common');
|
|
36
|
+
const rootV4TemplateDirPath = (0, node_path_1.join)(__dirname, `../templates/${applicationType}`); // Only v4 is supported for the time being
|
|
37
|
+
const testOutDirPath = (0, node_path_1.join)(await (0, project_access_1.getWebappPath)(basePath), 'test');
|
|
38
|
+
// Access ux-specification to get feature data for OPA test generation
|
|
39
|
+
const appFeatures = await (0, modelUtils_1.getAppFeatures)(basePath, editor, log, metadata, manifest);
|
|
40
|
+
// OPA Journey file
|
|
41
|
+
const startPages = config.pages.filter((page) => page.isStartup).map((page) => page.targetKey);
|
|
42
|
+
const LROP = findLROP(config.pages, manifest);
|
|
43
|
+
const journeyParams = {
|
|
44
|
+
startPages,
|
|
45
|
+
startLR: LROP.pageLR?.targetKey,
|
|
46
|
+
navigatedOP: LROP.pageOP?.targetKey,
|
|
47
|
+
hideFilterBar: config.hideFilterBar
|
|
48
|
+
};
|
|
49
|
+
const writeContext = { config, rootV4TemplateDirPath, testOutDirPath, editor, journeyParams };
|
|
50
|
+
if (standalone) {
|
|
51
|
+
const hasJourneyRunner = (0, node_fs_1.existsSync)((0, node_path_1.join)(testOutDirPath, 'integration', 'pages', 'JourneyRunner.js'));
|
|
52
|
+
const virtualOPA5Configured = await (0, opaQUnitUtils_1.hasVirtualOPA5)(basePath);
|
|
53
|
+
if (hasJourneyRunner) {
|
|
54
|
+
writeJourneyFiles(appFeatures, writeContext, true, true, virtualOPA5Configured);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
editor.move((0, node_path_1.join)(testOutDirPath, 'integration', '**'), (0, node_path_1.join)(testOutDirPath, 'integration_old'));
|
|
58
|
+
await (0, opaQUnitUtils_1.addIntegrationOldToGitignore)(basePath, editor);
|
|
59
|
+
const htmlTarget = (0, opaQUnitUtils_1.readHtmlTargetFromQUnitJs)(testOutDirPath, editor) ?? config.htmlTarget;
|
|
60
|
+
const standaloneConfig = { ...config, htmlTarget };
|
|
61
|
+
const standaloneWriteContext = { ...writeContext, config: standaloneConfig };
|
|
62
|
+
if (!virtualOPA5Configured) {
|
|
63
|
+
writeCommonAndPageFiles(standaloneWriteContext, rootCommonTemplateDirPath);
|
|
64
|
+
}
|
|
65
|
+
writeJourneyFiles(appFeatures, standaloneWriteContext, true, hasJourneyRunner, virtualOPA5Configured);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
writeCommonAndPageFiles(writeContext, rootCommonTemplateDirPath);
|
|
70
|
+
writeJourneyFiles(appFeatures, writeContext, false);
|
|
71
|
+
}
|
|
72
|
+
return editor;
|
|
73
|
+
}
|
|
15
74
|
/**
|
|
16
75
|
* Reads the manifest for an app.
|
|
17
76
|
*
|
|
@@ -208,7 +267,6 @@ function writeCommonAndPageFiles(writeContext, rootCommonTemplateDirPath) {
|
|
|
208
267
|
{ appId: config.appID }, undefined, {
|
|
209
268
|
globOptions: { dot: true }
|
|
210
269
|
});
|
|
211
|
-
// Pages files (one for each page in the app)
|
|
212
270
|
config.pages.forEach((page) => {
|
|
213
271
|
writePageObject(page, rootV4TemplateDirPath, testOutDirPath, editor);
|
|
214
272
|
});
|
|
@@ -220,6 +278,29 @@ function writeCommonAndPageFiles(writeContext, rootCommonTemplateDirPath) {
|
|
|
220
278
|
globOptions: { dot: true }
|
|
221
279
|
});
|
|
222
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Checks whether a page object file already exists for the given feature name.
|
|
283
|
+
* If it doesn't exist, finds the matching page config and writes the file.
|
|
284
|
+
*
|
|
285
|
+
* @param featureName - the feature/page name (equals the manifest targetKey)
|
|
286
|
+
* @param config - the OPA config containing all page configurations
|
|
287
|
+
* @param rootV4TemplateDirPath - template root directory for v4 templates
|
|
288
|
+
* @param testOutDirPath - output test directory (.../webapp/test)
|
|
289
|
+
* @param editor - a reference to a mem-fs editor
|
|
290
|
+
* @returns JourneyRunnerPage if the page was newly created, undefined otherwise
|
|
291
|
+
*/
|
|
292
|
+
function ensurePageExists(featureName, config, rootV4TemplateDirPath, testOutDirPath, editor) {
|
|
293
|
+
const pageFilePath = (0, node_path_1.join)(testOutDirPath, 'integration', 'pages', `${featureName}.js`);
|
|
294
|
+
if (editor.exists(pageFilePath)) {
|
|
295
|
+
return undefined;
|
|
296
|
+
}
|
|
297
|
+
const pageConfig = config.pages.find((p) => p.targetKey === featureName);
|
|
298
|
+
if (pageConfig) {
|
|
299
|
+
writePageObject(pageConfig, rootV4TemplateDirPath, testOutDirPath, editor);
|
|
300
|
+
return { targetKey: featureName, appPath: config.appPath };
|
|
301
|
+
}
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
223
304
|
/**
|
|
224
305
|
* Writes journey files for list report, object pages and FPM pages.
|
|
225
306
|
*
|
|
@@ -232,6 +313,7 @@ function writeCommonAndPageFiles(writeContext, rootCommonTemplateDirPath) {
|
|
|
232
313
|
function writeJourneyFiles(appFeatures, writeContext, isStandalone, hasJourneyRunner = false, virtualOPA5Configured = false) {
|
|
233
314
|
const { config, rootV4TemplateDirPath, testOutDirPath, editor, journeyParams } = writeContext;
|
|
234
315
|
const generatedJourneyPages = [];
|
|
316
|
+
const newPages = [];
|
|
235
317
|
if (appFeatures.listReport?.name) {
|
|
236
318
|
editor.copyTpl((0, node_path_1.join)(rootV4TemplateDirPath, 'integration', 'ListReportJourney.js'), (0, node_path_1.join)(testOutDirPath, 'integration', `${appFeatures.listReport.name}Journey.js`), {
|
|
237
319
|
...journeyParams,
|
|
@@ -240,6 +322,10 @@ function writeJourneyFiles(appFeatures, writeContext, isStandalone, hasJourneyRu
|
|
|
240
322
|
globOptions: { dot: true }
|
|
241
323
|
});
|
|
242
324
|
generatedJourneyPages.push(appFeatures.listReport.name);
|
|
325
|
+
const lrPage = ensurePageExists(appFeatures.listReport.name, config, rootV4TemplateDirPath, testOutDirPath, editor);
|
|
326
|
+
if (lrPage) {
|
|
327
|
+
newPages.push(lrPage);
|
|
328
|
+
}
|
|
243
329
|
}
|
|
244
330
|
if (appFeatures.objectPages && appFeatures.objectPages.length > 0) {
|
|
245
331
|
appFeatures.objectPages.forEach((objectPage) => {
|
|
@@ -252,6 +338,10 @@ function writeJourneyFiles(appFeatures, writeContext, isStandalone, hasJourneyRu
|
|
|
252
338
|
globOptions: { dot: true }
|
|
253
339
|
});
|
|
254
340
|
generatedJourneyPages.push(objectPage.name);
|
|
341
|
+
const opPage = ensurePageExists(objectPage.name, config, rootV4TemplateDirPath, testOutDirPath, editor);
|
|
342
|
+
if (opPage) {
|
|
343
|
+
newPages.push(opPage);
|
|
344
|
+
}
|
|
255
345
|
}
|
|
256
346
|
});
|
|
257
347
|
}
|
|
@@ -263,6 +353,13 @@ function writeJourneyFiles(appFeatures, writeContext, isStandalone, hasJourneyRu
|
|
|
263
353
|
globOptions: { dot: true }
|
|
264
354
|
});
|
|
265
355
|
generatedJourneyPages.push(appFeatures.fpm.name);
|
|
356
|
+
const fpmPage = ensurePageExists(appFeatures.fpm.name, config, rootV4TemplateDirPath, testOutDirPath, editor);
|
|
357
|
+
if (fpmPage) {
|
|
358
|
+
newPages.push(fpmPage);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (newPages.length > 0) {
|
|
362
|
+
(0, opaQUnitUtils_1.addPagesToJourneyRunner)(newPages, testOutDirPath, editor);
|
|
266
363
|
}
|
|
267
364
|
if (!virtualOPA5Configured) {
|
|
268
365
|
if (hasJourneyRunner) {
|
|
@@ -290,65 +387,6 @@ function writePageObject(pageConfig, rootTemplateDirPath, testOutDirPath, fs) {
|
|
|
290
387
|
globOptions: { dot: true }
|
|
291
388
|
});
|
|
292
389
|
}
|
|
293
|
-
/**
|
|
294
|
-
* Generate OPA test files for a Fiori elements for OData V4 application.
|
|
295
|
-
* Note: this can potentially overwrite existing files in the webapp/test folder.
|
|
296
|
-
*
|
|
297
|
-
* @param basePath - the absolute target path where the application will be generated
|
|
298
|
-
* @param opaConfig - parameters for the generation
|
|
299
|
-
* @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used
|
|
300
|
-
* @param opaConfig.htmlTarget - the name of the html that will be used in OPA journey file. If not specified, 'index.html' will be used
|
|
301
|
-
* @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id
|
|
302
|
-
* @param metadata - optional metadata for the OPA test generation
|
|
303
|
-
* @param fs - an optional reference to a mem-fs editor
|
|
304
|
-
* @param log - optional logger instance
|
|
305
|
-
* @param standalone - opa test generation run standalone, not during app generation
|
|
306
|
-
* @returns Reference to a mem-fs-editor
|
|
307
|
-
*/
|
|
308
|
-
async function generateOPAFiles(basePath, opaConfig, metadata, fs, log, standalone = false) {
|
|
309
|
-
const editor = fs ?? (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
|
|
310
|
-
const manifest = readManifest(editor, basePath);
|
|
311
|
-
const { applicationType, hideFilterBar } = getAppTypeAndHideFilterBarFromManifest(manifest);
|
|
312
|
-
const config = createConfig(manifest, opaConfig, hideFilterBar);
|
|
313
|
-
const rootCommonTemplateDirPath = (0, node_path_1.join)(__dirname, '../templates/common');
|
|
314
|
-
const rootV4TemplateDirPath = (0, node_path_1.join)(__dirname, `../templates/${applicationType}`); // Only v4 is supported for the time being
|
|
315
|
-
const testOutDirPath = (0, node_path_1.join)(await (0, project_access_1.getWebappPath)(basePath), 'test');
|
|
316
|
-
// Access ux-specification to get feature data for OPA test generation
|
|
317
|
-
const appFeatures = await (0, modelUtils_1.getAppFeatures)(basePath, editor, log, metadata);
|
|
318
|
-
// OPA Journey file
|
|
319
|
-
const startPages = config.pages.filter((page) => page.isStartup).map((page) => page.targetKey);
|
|
320
|
-
const LROP = findLROP(config.pages, manifest);
|
|
321
|
-
const journeyParams = {
|
|
322
|
-
startPages,
|
|
323
|
-
startLR: LROP.pageLR?.targetKey,
|
|
324
|
-
navigatedOP: LROP.pageOP?.targetKey,
|
|
325
|
-
hideFilterBar: config.hideFilterBar
|
|
326
|
-
};
|
|
327
|
-
const writeContext = { config, rootV4TemplateDirPath, testOutDirPath, editor, journeyParams };
|
|
328
|
-
if (standalone) {
|
|
329
|
-
const hasJourneyRunner = (0, node_fs_1.existsSync)((0, node_path_1.join)(testOutDirPath, 'integration', 'pages', 'JourneyRunner.js'));
|
|
330
|
-
const virtualOPA5Configured = await (0, opaQUnitUtils_1.hasVirtualOPA5)(basePath);
|
|
331
|
-
if (hasJourneyRunner) {
|
|
332
|
-
writeJourneyFiles(appFeatures, writeContext, true, true, virtualOPA5Configured);
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
editor.move((0, node_path_1.join)(testOutDirPath, 'integration', '**'), (0, node_path_1.join)(testOutDirPath, 'integration_old'));
|
|
336
|
-
await (0, opaQUnitUtils_1.addIntegrationOldToGitignore)(basePath, editor);
|
|
337
|
-
const htmlTarget = (0, opaQUnitUtils_1.readHtmlTargetFromQUnitJs)(testOutDirPath, editor) ?? config.htmlTarget;
|
|
338
|
-
const standaloneConfig = { ...config, htmlTarget };
|
|
339
|
-
const standaloneWriteContext = { ...writeContext, config: standaloneConfig };
|
|
340
|
-
if (!virtualOPA5Configured) {
|
|
341
|
-
writeCommonAndPageFiles(standaloneWriteContext, rootCommonTemplateDirPath);
|
|
342
|
-
}
|
|
343
|
-
writeJourneyFiles(appFeatures, standaloneWriteContext, true, true, virtualOPA5Configured);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
writeCommonAndPageFiles(writeContext, rootCommonTemplateDirPath);
|
|
348
|
-
writeJourneyFiles(appFeatures, writeContext, false);
|
|
349
|
-
}
|
|
350
|
-
return editor;
|
|
351
|
-
}
|
|
352
390
|
/**
|
|
353
391
|
* Generate a page object file for a Fiori elements for OData V4 application.
|
|
354
392
|
* Note: this doesn't modify other existing files in the webapp/test folder.
|
|
@@ -361,7 +399,7 @@ async function generateOPAFiles(basePath, opaConfig, metadata, fs, log, standalo
|
|
|
361
399
|
* @returns Reference to a mem-fs-editor
|
|
362
400
|
*/
|
|
363
401
|
async function generatePageObjectFile(basePath, pageObjectParameters, fs) {
|
|
364
|
-
const editor = fs
|
|
402
|
+
const editor = fs ?? (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
|
|
365
403
|
const manifest = readManifest(editor, basePath);
|
|
366
404
|
const { applicationType } = getAppTypeAndHideFilterBarFromManifest(manifest);
|
|
367
405
|
const pageConfig = createPageConfig(manifest, pageObjectParameters.targetKey, pageObjectParameters.appID);
|
package/dist/types.d.ts
CHANGED
|
@@ -43,6 +43,13 @@ export type FEV4ManifestTarget = {
|
|
|
43
43
|
};
|
|
44
44
|
};
|
|
45
45
|
};
|
|
46
|
+
views?: {
|
|
47
|
+
paths?: Array<{
|
|
48
|
+
primary?: unknown[];
|
|
49
|
+
secondary?: unknown[];
|
|
50
|
+
defaultPath?: string;
|
|
51
|
+
}>;
|
|
52
|
+
};
|
|
46
53
|
};
|
|
47
54
|
};
|
|
48
55
|
};
|
|
@@ -110,6 +117,7 @@ export type ListReportFeatures = {
|
|
|
110
117
|
filterBarItems?: string[];
|
|
111
118
|
tableColumns?: Record<string, Record<string, string | number | boolean>>;
|
|
112
119
|
toolBarActions?: ActionButtonState[];
|
|
120
|
+
isALP?: boolean;
|
|
113
121
|
};
|
|
114
122
|
export interface ActionButtonState {
|
|
115
123
|
label: string;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Logger } from '@sap-ux/logger';
|
|
2
2
|
import type { TreeAggregations, TreeModel } from '@sap/ux-specification/dist/types/src/parser';
|
|
3
|
-
import type { ActionButtonsResult, ActionButtonState, ButtonState, ButtonVisibilityResult, ListReportFeatures } from '../types';
|
|
3
|
+
import type { ActionButtonsResult, ActionButtonState, ButtonState, ButtonVisibilityResult, FEV4ManifestTarget, ListReportFeatures } from '../types';
|
|
4
4
|
import type { PageWithModelV4 } from '@sap/ux-specification/dist/types/src/parser/application';
|
|
5
|
+
import type { Manifest } from '@sap-ux/project-access';
|
|
5
6
|
/**
|
|
6
7
|
* Builds a button state object from button visibility result.
|
|
7
8
|
*
|
|
@@ -32,15 +33,33 @@ export declare function safeCheckButtonVisibility(metadata: string, entitySetNam
|
|
|
32
33
|
* @returns Array of action button states or empty array if error occurs
|
|
33
34
|
*/
|
|
34
35
|
export declare function safeCheckActionButtonStates(metadata: string, entitySetName: string, actionNames: string[], log?: Logger): ActionButtonState[];
|
|
36
|
+
/**
|
|
37
|
+
* Returns true when a ListReport manifest target is configured as an Analytical List Page.
|
|
38
|
+
* ALP targets have a `views.paths` array where at least one entry contains a `primary` array,
|
|
39
|
+
* indicating the dual-view (chart + table) layout used by ALP.
|
|
40
|
+
*
|
|
41
|
+
* @param target - the manifest routing target to inspect
|
|
42
|
+
* @returns true if the target represents an ALP configuration
|
|
43
|
+
*/
|
|
44
|
+
export declare function isALPManifestTarget(target: FEV4ManifestTarget): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Returns true if any ListReport target in the manifest is configured as an Analytical List Page.
|
|
47
|
+
*
|
|
48
|
+
* @param manifest - the application manifest
|
|
49
|
+
* @param targetKey - optional specific target key to check; if omitted all ListReport targets are checked
|
|
50
|
+
* @returns true if the target (or any ListReport target) is an ALP
|
|
51
|
+
*/
|
|
52
|
+
export declare function isALPFromManifest(manifest: Manifest, targetKey?: string): boolean;
|
|
35
53
|
/**
|
|
36
54
|
* Gets List Report features from the page model using ux-specification.
|
|
37
55
|
*
|
|
38
56
|
* @param listReportPage - the List Report page containing the tree model with feature definitions
|
|
39
57
|
* @param log - optional logger instance
|
|
40
58
|
* @param metadata - optional metadata for the OPA test generation
|
|
59
|
+
* @param manifest - optional application manifest, used to detect ALP configuration
|
|
41
60
|
* @returns feature data extracted from the List Report page model
|
|
42
61
|
*/
|
|
43
|
-
export declare function getListReportFeatures(listReportPage: PageWithModelV4, log?: Logger, metadata?: string): ListReportFeatures;
|
|
62
|
+
export declare function getListReportFeatures(listReportPage: PageWithModelV4, log?: Logger, metadata?: string, manifest?: Manifest): ListReportFeatures;
|
|
44
63
|
/**
|
|
45
64
|
* Retrieves toolbar action definitions from the given tree model.
|
|
46
65
|
*
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.buildButtonState = buildButtonState;
|
|
4
4
|
exports.safeCheckButtonVisibility = safeCheckButtonVisibility;
|
|
5
5
|
exports.safeCheckActionButtonStates = safeCheckActionButtonStates;
|
|
6
|
+
exports.isALPManifestTarget = isALPManifestTarget;
|
|
7
|
+
exports.isALPFromManifest = isALPFromManifest;
|
|
6
8
|
exports.getListReportFeatures = getListReportFeatures;
|
|
7
9
|
exports.getToolBarActions = getToolBarActions;
|
|
8
10
|
exports.checkButtonVisibility = checkButtonVisibility;
|
|
@@ -61,15 +63,45 @@ function safeCheckActionButtonStates(metadata, entitySetName, actionNames, log)
|
|
|
61
63
|
return [];
|
|
62
64
|
}
|
|
63
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Returns true when a ListReport manifest target is configured as an Analytical List Page.
|
|
68
|
+
* ALP targets have a `views.paths` array where at least one entry contains a `primary` array,
|
|
69
|
+
* indicating the dual-view (chart + table) layout used by ALP.
|
|
70
|
+
*
|
|
71
|
+
* @param target - the manifest routing target to inspect
|
|
72
|
+
* @returns true if the target represents an ALP configuration
|
|
73
|
+
*/
|
|
74
|
+
function isALPManifestTarget(target) {
|
|
75
|
+
return (target.options?.settings?.views?.paths?.some((path) => Array.isArray(path.primary) && path.primary.length > 0) ?? false);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Returns true if any ListReport target in the manifest is configured as an Analytical List Page.
|
|
79
|
+
*
|
|
80
|
+
* @param manifest - the application manifest
|
|
81
|
+
* @param targetKey - optional specific target key to check; if omitted all ListReport targets are checked
|
|
82
|
+
* @returns true if the target (or any ListReport target) is an ALP
|
|
83
|
+
*/
|
|
84
|
+
function isALPFromManifest(manifest, targetKey) {
|
|
85
|
+
const targets = manifest['sap.ui5']?.routing?.targets;
|
|
86
|
+
if (!targets) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
const keysToCheck = targetKey ? [targetKey] : Object.keys(targets);
|
|
90
|
+
return keysToCheck.some((key) => {
|
|
91
|
+
const target = targets[key];
|
|
92
|
+
return target?.name === 'sap.fe.templates.ListReport' && isALPManifestTarget(target);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
64
95
|
/**
|
|
65
96
|
* Gets List Report features from the page model using ux-specification.
|
|
66
97
|
*
|
|
67
98
|
* @param listReportPage - the List Report page containing the tree model with feature definitions
|
|
68
99
|
* @param log - optional logger instance
|
|
69
100
|
* @param metadata - optional metadata for the OPA test generation
|
|
101
|
+
* @param manifest - optional application manifest, used to detect ALP configuration
|
|
70
102
|
* @returns feature data extracted from the List Report page model
|
|
71
103
|
*/
|
|
72
|
-
function getListReportFeatures(listReportPage, log, metadata) {
|
|
104
|
+
function getListReportFeatures(listReportPage, log, metadata, manifest) {
|
|
73
105
|
const buttonVisibility = metadata && listReportPage.entitySet
|
|
74
106
|
? safeCheckButtonVisibility(metadata, listReportPage.entitySet, log)
|
|
75
107
|
: undefined;
|
|
@@ -82,7 +114,8 @@ function getListReportFeatures(listReportPage, log, metadata) {
|
|
|
82
114
|
tableColumns: (0, modelUtils_1.getTableColumnData)(listReportPage.model, log),
|
|
83
115
|
toolBarActions: metadata && listReportPage.entitySet
|
|
84
116
|
? safeCheckActionButtonStates(metadata, listReportPage.entitySet, toolbarActions, log)
|
|
85
|
-
: []
|
|
117
|
+
: [],
|
|
118
|
+
isALP: manifest ? isALPFromManifest(manifest, listReportPage.name) : false
|
|
86
119
|
};
|
|
87
120
|
}
|
|
88
121
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Editor } from 'mem-fs-editor';
|
|
2
|
+
import type { Manifest } from '@sap-ux/project-access';
|
|
2
3
|
import type { Logger } from '@sap-ux/logger';
|
|
3
4
|
import type { PageWithModelV4 } from '@sap/ux-specification/dist/types/src/parser/application';
|
|
4
5
|
import type { TreeAggregation, TreeAggregations, TreeModel, ApplicationModel } from '@sap/ux-specification/dist/types/src/parser';
|
|
@@ -49,9 +50,10 @@ export interface PageWithModelV4WithProperties extends PageWithModelV4 {
|
|
|
49
50
|
* @param fs - optional mem-fs editor instance
|
|
50
51
|
* @param log - optional logger instance
|
|
51
52
|
* @param metadata - optional metadata for the OPA test generation
|
|
53
|
+
* @param manifest - optional application manifest, used to detect ALP configuration
|
|
52
54
|
* @returns feature data extracted from the application model
|
|
53
55
|
*/
|
|
54
|
-
export declare function getAppFeatures(basePath: string, fs?: Editor, log?: Logger, metadata?: string): Promise<AppFeatures>;
|
|
56
|
+
export declare function getAppFeatures(basePath: string, fs?: Editor, log?: Logger, metadata?: string, manifest?: Manifest): Promise<AppFeatures>;
|
|
55
57
|
/**
|
|
56
58
|
* Retrieves table column data from the page model using ux-specification.
|
|
57
59
|
*
|
package/dist/utils/modelUtils.js
CHANGED
|
@@ -20,9 +20,10 @@ const listReportUtils_1 = require("./listReportUtils");
|
|
|
20
20
|
* @param fs - optional mem-fs editor instance
|
|
21
21
|
* @param log - optional logger instance
|
|
22
22
|
* @param metadata - optional metadata for the OPA test generation
|
|
23
|
+
* @param manifest - optional application manifest, used to detect ALP configuration
|
|
23
24
|
* @returns feature data extracted from the application model
|
|
24
25
|
*/
|
|
25
|
-
async function getAppFeatures(basePath, fs, log, metadata) {
|
|
26
|
+
async function getAppFeatures(basePath, fs, log, metadata, manifest) {
|
|
26
27
|
const featureData = {};
|
|
27
28
|
let listReportPage = null;
|
|
28
29
|
let objectPages = null;
|
|
@@ -57,7 +58,7 @@ async function getAppFeatures(basePath, fs, log, metadata) {
|
|
|
57
58
|
// attempt to get individual feature data
|
|
58
59
|
try {
|
|
59
60
|
if (listReportPage) {
|
|
60
|
-
featureData.listReport = (0, listReportUtils_1.getListReportFeatures)(listReportPage, log, projectMetadata);
|
|
61
|
+
featureData.listReport = (0, listReportUtils_1.getListReportFeatures)(listReportPage, log, projectMetadata, manifest);
|
|
61
62
|
}
|
|
62
63
|
if (objectPages) {
|
|
63
64
|
log?.warn('Extracting Object Page features from application model');
|
|
@@ -8,6 +8,9 @@ import type { Editor } from 'mem-fs-editor';
|
|
|
8
8
|
* Splices new module paths into the sap.ui.require array of the content string.
|
|
9
9
|
* Entries that are already present are skipped. All other content is preserved exactly.
|
|
10
10
|
*
|
|
11
|
+
* Note: files exceeding MAX_FILE_CONTENT_LENGTH characters are returned unchanged to prevent
|
|
12
|
+
* ReDoS on crafted inputs. Valid generated files are well within this limit.
|
|
13
|
+
*
|
|
11
14
|
* @param fileContent - the full content of the opaTests.qunit.js file
|
|
12
15
|
* @param moduleNames - module paths to add (e.g. ["myApp/test/integration/SomeJourney"])
|
|
13
16
|
* @returns the updated file content, or the original content unchanged if nothing was added
|
|
@@ -43,6 +46,42 @@ export declare function addIntegrationOldToGitignore(basePath: string, fs: Edito
|
|
|
43
46
|
* @param fs - mem-fs-editor instance used to read and write the file
|
|
44
47
|
*/
|
|
45
48
|
export declare function addPathsToQUnitJs(filePaths: string[], projectPath: string, fs: Editor): void;
|
|
49
|
+
/**
|
|
50
|
+
* Page entry to splice into an existing JourneyRunner.js.
|
|
51
|
+
*/
|
|
52
|
+
export interface JourneyRunnerPage {
|
|
53
|
+
/** The page's targetKey, used as both the variable name and `onThe<targetKey>` key */
|
|
54
|
+
targetKey: string;
|
|
55
|
+
/** The app module path prefix (e.g. "project1/test/integration/pages") */
|
|
56
|
+
appPath: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Splices new page entries into the three locations of an existing JourneyRunner.js:
|
|
60
|
+
* - the sap.ui.define dependency array
|
|
61
|
+
* - the function parameter list
|
|
62
|
+
* - the pages object literal
|
|
63
|
+
*
|
|
64
|
+
* Pages already present (detected by their module path in the define array) are skipped.
|
|
65
|
+
* All other content — formatting, comments, whitespace — is preserved exactly.
|
|
66
|
+
*
|
|
67
|
+
* Note: files exceeding MAX_FILE_CONTENT_LENGTH characters are returned unchanged to prevent
|
|
68
|
+
* ReDoS on crafted inputs. Valid generated files are well within this limit.
|
|
69
|
+
*
|
|
70
|
+
* @param fileContent - the full content of the JourneyRunner.js file
|
|
71
|
+
* @param pages - pages to add
|
|
72
|
+
* @returns the updated file content, or the original content unchanged if nothing was added
|
|
73
|
+
*/
|
|
74
|
+
export declare function splicePageIntoJourneyRunner(fileContent: string, pages: JourneyRunnerPage[]): string;
|
|
75
|
+
/**
|
|
76
|
+
* Reads JourneyRunner.js from the project, adds new page entries to all three
|
|
77
|
+
* locations (define array, function params, pages object), and writes the updated
|
|
78
|
+
* content back. Pages already present are skipped.
|
|
79
|
+
*
|
|
80
|
+
* @param pages - pages to add
|
|
81
|
+
* @param testOutDirPath - path to the test output directory (`.../webapp/test`)
|
|
82
|
+
* @param fs - mem-fs-editor instance used to read and write the file
|
|
83
|
+
*/
|
|
84
|
+
export declare function addPagesToJourneyRunner(pages: JourneyRunnerPage[], testOutDirPath: string, fs: Editor): void;
|
|
46
85
|
/**
|
|
47
86
|
* Returns true if any UI5 yaml file in the project contains a `fiori-tools-preview`
|
|
48
87
|
* middleware whose `test` array includes an entry with `framework: OPA5`.
|
|
@@ -9,6 +9,8 @@ exports.spliceModulesIntoQUnitContent = spliceModulesIntoQUnitContent;
|
|
|
9
9
|
exports.readHtmlTargetFromQUnitJs = readHtmlTargetFromQUnitJs;
|
|
10
10
|
exports.addIntegrationOldToGitignore = addIntegrationOldToGitignore;
|
|
11
11
|
exports.addPathsToQUnitJs = addPathsToQUnitJs;
|
|
12
|
+
exports.splicePageIntoJourneyRunner = splicePageIntoJourneyRunner;
|
|
13
|
+
exports.addPagesToJourneyRunner = addPagesToJourneyRunner;
|
|
12
14
|
exports.hasVirtualOPA5 = hasVirtualOPA5;
|
|
13
15
|
const node_path_1 = require("node:path");
|
|
14
16
|
const flpSandboxUtils_1 = require("./flpSandboxUtils");
|
|
@@ -29,16 +31,24 @@ const OPA_QUNIT_FILE = (0, node_path_1.join)('integration', 'opaTests.qunit.js')
|
|
|
29
31
|
* The `d` flag enables `match.indices` so we can read the capture group's
|
|
30
32
|
* exact start/end positions without fragile string searching.
|
|
31
33
|
*/
|
|
32
|
-
const SAP_UI_REQUIRE_ARRAY_REGEX = /sap\.ui\.require\s*\(\s*\[([
|
|
34
|
+
const SAP_UI_REQUIRE_ARRAY_REGEX = /sap\.ui\.require\s*\(\s*\[([^\]]*)\]\s*,\s*function/d;
|
|
35
|
+
/** ReDoS mitigation: files larger than this are returned unchanged rather than matched with regex. */
|
|
36
|
+
const MAX_FILE_CONTENT_LENGTH = 10000;
|
|
33
37
|
/**
|
|
34
38
|
* Splices new module paths into the sap.ui.require array of the content string.
|
|
35
39
|
* Entries that are already present are skipped. All other content is preserved exactly.
|
|
36
40
|
*
|
|
41
|
+
* Note: files exceeding MAX_FILE_CONTENT_LENGTH characters are returned unchanged to prevent
|
|
42
|
+
* ReDoS on crafted inputs. Valid generated files are well within this limit.
|
|
43
|
+
*
|
|
37
44
|
* @param fileContent - the full content of the opaTests.qunit.js file
|
|
38
45
|
* @param moduleNames - module paths to add (e.g. ["myApp/test/integration/SomeJourney"])
|
|
39
46
|
* @returns the updated file content, or the original content unchanged if nothing was added
|
|
40
47
|
*/
|
|
41
48
|
function spliceModulesIntoQUnitContent(fileContent, moduleNames) {
|
|
49
|
+
if (fileContent.length > MAX_FILE_CONTENT_LENGTH) {
|
|
50
|
+
return fileContent;
|
|
51
|
+
}
|
|
42
52
|
const match = SAP_UI_REQUIRE_ARRAY_REGEX.exec(fileContent);
|
|
43
53
|
if (!match) {
|
|
44
54
|
return fileContent;
|
|
@@ -65,10 +75,13 @@ function spliceModulesIntoQUnitContent(fileContent, moduleNames) {
|
|
|
65
75
|
if (insertPosition === undefined) {
|
|
66
76
|
return fileContent;
|
|
67
77
|
}
|
|
68
|
-
|
|
78
|
+
// Ensure the last existing entry ends with a comma before inserting after it.
|
|
79
|
+
const trimmedBefore = fileContent.slice(0, insertPosition).trimEnd();
|
|
80
|
+
const needsComma = !trimmedBefore.endsWith(',');
|
|
81
|
+
const commaFix = needsComma ? ',' : '';
|
|
82
|
+
const trailingWhitespace = fileContent.slice(trimmedBefore.length, insertPosition);
|
|
69
83
|
const after = fileContent.slice(insertPosition);
|
|
70
|
-
|
|
71
|
-
return `${before}${leadingNewline}${newLines}\n${after}`;
|
|
84
|
+
return `${trimmedBefore}${commaFix}\n${newLines}\n${trailingWhitespace}${after}`;
|
|
72
85
|
}
|
|
73
86
|
/**
|
|
74
87
|
* Regex to extract the html launch target from a `launchUrl` line of the form:
|
|
@@ -157,6 +170,112 @@ function addPathsToQUnitJs(filePaths, projectPath, fs) {
|
|
|
157
170
|
// If the file doesn't exist or can't be read, do nothing
|
|
158
171
|
}
|
|
159
172
|
}
|
|
173
|
+
/** Relative path from the test output directory to JourneyRunner.js */
|
|
174
|
+
const JOURNEY_RUNNER_FILE = (0, node_path_1.join)('integration', 'pages', 'JourneyRunner.js');
|
|
175
|
+
/**
|
|
176
|
+
* Splices new page entries into the three locations of an existing JourneyRunner.js:
|
|
177
|
+
* - the sap.ui.define dependency array
|
|
178
|
+
* - the function parameter list
|
|
179
|
+
* - the pages object literal
|
|
180
|
+
*
|
|
181
|
+
* Pages already present (detected by their module path in the define array) are skipped.
|
|
182
|
+
* All other content — formatting, comments, whitespace — is preserved exactly.
|
|
183
|
+
*
|
|
184
|
+
* Note: files exceeding MAX_FILE_CONTENT_LENGTH characters are returned unchanged to prevent
|
|
185
|
+
* ReDoS on crafted inputs. Valid generated files are well within this limit.
|
|
186
|
+
*
|
|
187
|
+
* @param fileContent - the full content of the JourneyRunner.js file
|
|
188
|
+
* @param pages - pages to add
|
|
189
|
+
* @returns the updated file content, or the original content unchanged if nothing was added
|
|
190
|
+
*/
|
|
191
|
+
function splicePageIntoJourneyRunner(fileContent, pages) {
|
|
192
|
+
if (fileContent.length > MAX_FILE_CONTENT_LENGTH) {
|
|
193
|
+
return fileContent;
|
|
194
|
+
}
|
|
195
|
+
// Determine which pages are not yet present by checking the define array
|
|
196
|
+
const toAdd = pages.filter((page) => {
|
|
197
|
+
const modulePath = `${page.appPath}/test/integration/pages/${page.targetKey}`;
|
|
198
|
+
return !fileContent.includes(`"${modulePath}"`);
|
|
199
|
+
});
|
|
200
|
+
if (toAdd.length === 0) {
|
|
201
|
+
return fileContent;
|
|
202
|
+
}
|
|
203
|
+
let result = fileContent;
|
|
204
|
+
// 1. Splice into the sap.ui.define([...]) array.
|
|
205
|
+
// Captures everything between the opening `[` and the closing `]` before `, function`.
|
|
206
|
+
const defineArrayRegex = /sap\.ui\.define\s*\(\s*\[([^\]]*)\]\s*,\s*function/d;
|
|
207
|
+
const defineMatch = defineArrayRegex.exec(result);
|
|
208
|
+
if (defineMatch?.indices?.[1]) {
|
|
209
|
+
const [bodyStart, bodyEnd] = defineMatch.indices[1];
|
|
210
|
+
const arrayBody = result.slice(bodyStart, bodyEnd);
|
|
211
|
+
// Detect indentation from the first existing module entry line
|
|
212
|
+
const indentMatch = /^([ \t]+)"/m.exec(arrayBody);
|
|
213
|
+
const indent = indentMatch ? indentMatch[1] : '\t';
|
|
214
|
+
const newEntries = toAdd
|
|
215
|
+
.map((page) => `${indent}"${page.appPath}/test/integration/pages/${page.targetKey}",`)
|
|
216
|
+
.join('\n');
|
|
217
|
+
// Ensure the last existing entry ends with a comma before we insert after it.
|
|
218
|
+
// The trimmed body ends at bodyEnd; look back from there for the last non-whitespace char.
|
|
219
|
+
const trimmedEnd = result.slice(0, bodyEnd).trimEnd();
|
|
220
|
+
const needsComma = !trimmedEnd.endsWith(',');
|
|
221
|
+
const commaFix = needsComma ? ',' : '';
|
|
222
|
+
const trailingWhitespace = result.slice(trimmedEnd.length, bodyEnd);
|
|
223
|
+
result = `${trimmedEnd}${commaFix}\n${newEntries}` + `${trailingWhitespace}${result.slice(bodyEnd)}`;
|
|
224
|
+
}
|
|
225
|
+
// 2. Splice into the function parameter list: `function (JourneyRunner, A, B)`.
|
|
226
|
+
// Captures everything between `(` and `)` of the function signature.
|
|
227
|
+
const funcParamRegex = /\]\s*,\s*function\s*\(([^)]*)\)\s*\{/d;
|
|
228
|
+
const funcMatch = funcParamRegex.exec(result);
|
|
229
|
+
if (funcMatch?.indices?.[1]) {
|
|
230
|
+
const [, paramEnd] = funcMatch.indices[1];
|
|
231
|
+
const newParams = toAdd.map((page) => `, ${page.targetKey}`).join('');
|
|
232
|
+
result = `${result.slice(0, paramEnd)}${newParams}${result.slice(paramEnd)}`;
|
|
233
|
+
}
|
|
234
|
+
// 3. Splice into the pages object: `pages: { onTheFoo: Foo, ... }`.
|
|
235
|
+
// Captures everything between `pages: {` and the closing `}`.
|
|
236
|
+
const pagesObjectRegex = /pages\s*:\s*\{([^}]*)\}/d;
|
|
237
|
+
const pagesMatch = pagesObjectRegex.exec(result);
|
|
238
|
+
if (pagesMatch?.indices?.[1]) {
|
|
239
|
+
const [, pagesBodyEnd] = pagesMatch.indices[1];
|
|
240
|
+
const pagesBody = result.slice(pagesMatch.indices[1][0], pagesBodyEnd);
|
|
241
|
+
// Detect indentation from the first existing page entry
|
|
242
|
+
const pageIndentMatch = /^([ \t]+)on/m.exec(pagesBody);
|
|
243
|
+
const pageIndent = pageIndentMatch ? pageIndentMatch[1] : '\t\t\t';
|
|
244
|
+
const newPageEntries = toAdd
|
|
245
|
+
.map((page) => `${pageIndent}onThe${page.targetKey}: ${page.targetKey},`)
|
|
246
|
+
.join('\n');
|
|
247
|
+
// Ensure the last existing entry ends with a comma before we insert after it.
|
|
248
|
+
const trimmedPagesEnd = result.slice(0, pagesBodyEnd).trimEnd();
|
|
249
|
+
const needsComma = !trimmedPagesEnd.endsWith(',');
|
|
250
|
+
const commaFix = needsComma ? ',' : '';
|
|
251
|
+
const trailingWhitespace = result.slice(trimmedPagesEnd.length, pagesBodyEnd);
|
|
252
|
+
result =
|
|
253
|
+
`${trimmedPagesEnd}${commaFix}\n${newPageEntries}` + `${trailingWhitespace}${result.slice(pagesBodyEnd)}`;
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Reads JourneyRunner.js from the project, adds new page entries to all three
|
|
259
|
+
* locations (define array, function params, pages object), and writes the updated
|
|
260
|
+
* content back. Pages already present are skipped.
|
|
261
|
+
*
|
|
262
|
+
* @param pages - pages to add
|
|
263
|
+
* @param testOutDirPath - path to the test output directory (`.../webapp/test`)
|
|
264
|
+
* @param fs - mem-fs-editor instance used to read and write the file
|
|
265
|
+
*/
|
|
266
|
+
function addPagesToJourneyRunner(pages, testOutDirPath, fs) {
|
|
267
|
+
try {
|
|
268
|
+
const filePath = (0, node_path_1.join)(testOutDirPath, JOURNEY_RUNNER_FILE);
|
|
269
|
+
const content = fs.read(filePath);
|
|
270
|
+
const updated = splicePageIntoJourneyRunner(content, pages);
|
|
271
|
+
if (updated !== content) {
|
|
272
|
+
fs.write(filePath, updated);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
// If the file doesn't exist or can't be read, do nothing
|
|
277
|
+
}
|
|
278
|
+
}
|
|
160
279
|
/**
|
|
161
280
|
* Returns true if any UI5 yaml file in the project contains a `fiori-tools-preview`
|
|
162
281
|
* middleware whose `test` array includes an entry with `framework: OPA5`.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap-ux/ui5-test-writer",
|
|
3
3
|
"description": "SAP UI5 tests writer",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.104",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/SAP/open-ux-tools.git",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"@sap-ux/edmx-parser": "0.10.0",
|
|
29
29
|
"@sap-ux/annotation-converter": "0.10.21",
|
|
30
30
|
"@sap-ux/ui5-application-writer": "1.8.5",
|
|
31
|
-
"@sap-ux/
|
|
32
|
-
"@sap-ux/
|
|
31
|
+
"@sap-ux/project-access": "1.35.20",
|
|
32
|
+
"@sap-ux/logger": "0.8.5"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/ejs": "3.1.5",
|
|
@@ -41,7 +41,7 @@ sap.ui.define([
|
|
|
41
41
|
|
|
42
42
|
opaTest("Check table columns and actions", function (Given, When, Then) {
|
|
43
43
|
<%_ if (toolBarActions && toolBarActions.length > 0) { -%>
|
|
44
|
-
<%_ if (createButton.visible) { _%>
|
|
44
|
+
<%_ if (createButton.visible && !isALP) { _%>
|
|
45
45
|
Then.onThe<%- startLR%>.onTable().iCheckCreate({ visible: true });
|
|
46
46
|
// Then.onthe<%- startLR%>.onTable().iPressCreate();
|
|
47
47
|
<%_ } _%>
|
|
@@ -60,18 +60,16 @@ sap.ui.define([
|
|
|
60
60
|
});
|
|
61
61
|
<% } -%>
|
|
62
62
|
|
|
63
|
-
<% if (bodySections?.length > 0) { -%>
|
|
63
|
+
<% if (bodySections?.length > 0 && !isStandalone) { -%>
|
|
64
64
|
opaTest("Check body sections of the Object Page", function (Given, When, Then) {
|
|
65
65
|
<% if (bodySections?.length > 1) { -%>
|
|
66
66
|
Then.onThe<%- name%>.iCheckNumberOfSections(<%- bodySections.length %>);
|
|
67
67
|
<% } -%>
|
|
68
68
|
<% bodySections.forEach(function(section) { -%>
|
|
69
|
-
<% if (!isStandalone) { -%>
|
|
70
69
|
<% if (bodySections.length > 1) { -%>
|
|
71
70
|
When.onThe<%- name%>.iPressSectionIconTabFilterButton("<%- section.id %>");
|
|
72
71
|
<% } -%>
|
|
73
72
|
Then.onThe<%- name%>.iCheckSection({ section: "<%- section.id %>" });
|
|
74
|
-
<% } -%>
|
|
75
73
|
<% if (section?.subSections?.length > 0) { -%>
|
|
76
74
|
<% section.subSections.forEach(function(subSection) { -%>
|
|
77
75
|
//When.onThe<%- name%>.iGoToSection({ section: "<%- section.id %>", subSection: "<%- subSection.id %>" });
|