@sap-ux/ui5-test-writer 0.9.14 → 1.0.0
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.js +52 -54
- package/dist/fiori-freestyle-opa-writer.d.ts +1 -1
- package/dist/fiori-freestyle-opa-writer.js +28 -29
- package/dist/i18n.js +9 -19
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -9
- package/dist/types.js +2 -6
- package/dist/utils/actionUtils.d.ts +4 -4
- package/dist/utils/actionUtils.js +20 -38
- package/dist/utils/flpSandboxUtils.js +3 -6
- package/dist/utils/listReportUtils.d.ts +5 -5
- package/dist/utils/listReportUtils.js +35 -55
- package/dist/utils/modelUtils.d.ts +3 -3
- package/dist/utils/modelUtils.js +21 -31
- package/dist/utils/objectPageUtils.d.ts +3 -3
- package/dist/utils/objectPageUtils.js +39 -43
- package/dist/utils/opaQUnitUtils.js +24 -34
- package/dist/utils/tableUtils.d.ts +2 -2
- package/dist/utils/tableUtils.js +7 -12
- package/package.json +11 -9
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
15
|
-
const flpSandboxUtils_1 = require("./utils/flpSandboxUtils");
|
|
1
|
+
import { dirname, join } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { create as createStorage } from 'mem-fs';
|
|
5
|
+
import { create } from 'mem-fs-editor';
|
|
6
|
+
import { SupportedPageTypes, ValidationError } from './types.js';
|
|
7
|
+
import { t } from './i18n.js';
|
|
8
|
+
import { FileName, DirName, getWebappPath, updatePackageScript } from '@sap-ux/project-access';
|
|
9
|
+
import { getAppFeatures } from './utils/modelUtils.js';
|
|
10
|
+
import { addIntegrationOldToGitignore, addPathsToQUnitJs, addPagesToJourneyRunner, hasVirtualOPA5, readHtmlTargetFromQUnitJs, addVirtualTestConfig } from './utils/opaQUnitUtils.js';
|
|
11
|
+
import { getPackageScripts } from '@sap-ux/fiori-generator-shared';
|
|
12
|
+
import { readHashFromFlpSandbox } from './utils/flpSandboxUtils.js';
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
14
|
/**
|
|
17
15
|
* Generate OPA test files for a Fiori elements for OData V4 application.
|
|
18
16
|
* Note: this can potentially overwrite existing files in the webapp/test folder.
|
|
@@ -29,16 +27,16 @@ const flpSandboxUtils_1 = require("./utils/flpSandboxUtils");
|
|
|
29
27
|
* @param standalone - opa test generation run standalone, not during app generation
|
|
30
28
|
* @returns Reference to a mem-fs-editor
|
|
31
29
|
*/
|
|
32
|
-
async function generateOPAFiles(basePath, opaConfig, metadata, fs, log, standalone = false) {
|
|
33
|
-
const editor = fs ??
|
|
30
|
+
export async function generateOPAFiles(basePath, opaConfig, metadata, fs, log, standalone = false) {
|
|
31
|
+
const editor = fs ?? create(createStorage());
|
|
34
32
|
const manifest = readManifest(editor, basePath);
|
|
35
33
|
const { applicationType, hideFilterBar } = getAppTypeAndHideFilterBarFromManifest(manifest);
|
|
36
34
|
const config = createConfig(manifest, opaConfig, hideFilterBar);
|
|
37
|
-
const rootCommonTemplateDirPath =
|
|
38
|
-
const rootV4TemplateDirPath =
|
|
39
|
-
const testOutDirPath =
|
|
35
|
+
const rootCommonTemplateDirPath = join(__dirname, '../templates/common');
|
|
36
|
+
const rootV4TemplateDirPath = join(__dirname, `../templates/${applicationType}`); // Only v4 is supported for the time being
|
|
37
|
+
const testOutDirPath = join(await getWebappPath(basePath), 'test');
|
|
40
38
|
// Access ux-specification to get feature data for OPA test generation
|
|
41
|
-
const appFeatures = await
|
|
39
|
+
const appFeatures = await getAppFeatures(basePath, editor, log, metadata, manifest);
|
|
42
40
|
// OPA Journey file
|
|
43
41
|
const startPages = config.pages.filter((page) => page.isStartup).map((page) => page.targetKey);
|
|
44
42
|
const LROP = findLROP(config.pages, manifest);
|
|
@@ -50,8 +48,8 @@ async function generateOPAFiles(basePath, opaConfig, metadata, fs, log, standalo
|
|
|
50
48
|
};
|
|
51
49
|
const writeContext = { config, rootV4TemplateDirPath, testOutDirPath, editor, journeyParams };
|
|
52
50
|
if (standalone) {
|
|
53
|
-
const hasJourneyRunner =
|
|
54
|
-
const virtualOPA5Configured = await
|
|
51
|
+
const hasJourneyRunner = existsSync(join(testOutDirPath, 'integration', 'pages', 'JourneyRunner.js'));
|
|
52
|
+
const virtualOPA5Configured = await hasVirtualOPA5(basePath);
|
|
55
53
|
if (hasJourneyRunner) {
|
|
56
54
|
writeJourneyFiles(appFeatures, writeContext, true, true, virtualOPA5Configured);
|
|
57
55
|
}
|
|
@@ -67,7 +65,7 @@ async function generateOPAFiles(basePath, opaConfig, metadata, fs, log, standalo
|
|
|
67
65
|
writeCommonAndPageFiles(writeContext, rootCommonTemplateDirPath, opaConfig.useVirtualPreviewEndpoints ?? false);
|
|
68
66
|
writeJourneyFiles(appFeatures, writeContext, false, false, opaConfig.useVirtualPreviewEndpoints ?? false);
|
|
69
67
|
if (opaConfig.useVirtualPreviewEndpoints) {
|
|
70
|
-
await
|
|
68
|
+
await addVirtualTestConfig(basePath, [{ framework: 'OPA5', path: '/test/integration/opaTests.qunit.html' }, { framework: 'Testsuite' }], editor);
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
return editor;
|
|
@@ -85,21 +83,21 @@ async function generateOPAFiles(basePath, opaConfig, metadata, fs, log, standalo
|
|
|
85
83
|
*/
|
|
86
84
|
async function resolveStandaloneWriteContext(basePath, testOutDirPath, writeContext, editor) {
|
|
87
85
|
const { config } = writeContext;
|
|
88
|
-
let htmlTarget =
|
|
89
|
-
if (
|
|
90
|
-
editor.move(
|
|
91
|
-
await
|
|
86
|
+
let htmlTarget = readHtmlTargetFromQUnitJs(testOutDirPath, editor) ?? config.htmlTarget;
|
|
87
|
+
if (existsSync(join(testOutDirPath, 'integration'))) {
|
|
88
|
+
editor.move(join(testOutDirPath, 'integration', '**'), join(testOutDirPath, 'integration_old'));
|
|
89
|
+
await addIntegrationOldToGitignore(basePath, editor);
|
|
92
90
|
}
|
|
93
91
|
else {
|
|
94
92
|
const hasIntTestScript = checkScriptInPackageJson(editor, basePath, 'int-test');
|
|
95
93
|
if (!hasIntTestScript) {
|
|
96
|
-
const script =
|
|
94
|
+
const script = getPackageScripts({ localOnly: false, addTest: true })['int-test'];
|
|
97
95
|
if (script) {
|
|
98
|
-
await
|
|
96
|
+
await updatePackageScript(basePath, 'int-test', script, editor);
|
|
99
97
|
}
|
|
100
98
|
}
|
|
101
|
-
if (
|
|
102
|
-
const hashFromFlpSandbox =
|
|
99
|
+
if (existsSync(join(testOutDirPath, 'flpSandbox.html'))) {
|
|
100
|
+
const hashFromFlpSandbox = readHashFromFlpSandbox(join('test', 'flpSandbox.html'), await getWebappPath(basePath), editor);
|
|
103
101
|
if (hashFromFlpSandbox) {
|
|
104
102
|
htmlTarget = `test/flpSandbox.html#${hashFromFlpSandbox}`;
|
|
105
103
|
}
|
|
@@ -116,7 +114,7 @@ async function resolveStandaloneWriteContext(basePath, testOutDirPath, writeCont
|
|
|
116
114
|
* @returns true if the script exists, false otherwise
|
|
117
115
|
*/
|
|
118
116
|
function checkScriptInPackageJson(editor, basePath, scriptName) {
|
|
119
|
-
const packageJsonPath =
|
|
117
|
+
const packageJsonPath = join(basePath, FileName.Package);
|
|
120
118
|
if (!editor.exists(packageJsonPath)) {
|
|
121
119
|
return false;
|
|
122
120
|
}
|
|
@@ -130,11 +128,11 @@ function checkScriptInPackageJson(editor, basePath, scriptName) {
|
|
|
130
128
|
* @param basePath - the root folder of the app
|
|
131
129
|
* @returns the manifest object. An exception is thrown if the manifest cannot be read.
|
|
132
130
|
*/
|
|
133
|
-
function readManifest(fs, basePath) {
|
|
134
|
-
const manifest = fs.readJSON(
|
|
131
|
+
export function readManifest(fs, basePath) {
|
|
132
|
+
const manifest = fs.readJSON(join(basePath, DirName.Webapp, FileName.Manifest));
|
|
135
133
|
if (!manifest) {
|
|
136
|
-
throw new
|
|
137
|
-
filePath:
|
|
134
|
+
throw new ValidationError(t('error.cannotReadManifest', {
|
|
135
|
+
filePath: join(basePath, DirName.Webapp, FileName.Manifest)
|
|
138
136
|
}));
|
|
139
137
|
}
|
|
140
138
|
return manifest;
|
|
@@ -151,15 +149,15 @@ function getAppTypeAndHideFilterBarFromManifest(manifest) {
|
|
|
151
149
|
let isFEV4 = false;
|
|
152
150
|
for (const targetKey in appTargets) {
|
|
153
151
|
const target = appTargets[targetKey];
|
|
154
|
-
if (target.type === 'Component' && target.name && target.name in
|
|
152
|
+
if (target.type === 'Component' && target.name && target.name in SupportedPageTypes) {
|
|
155
153
|
isFEV4 = true;
|
|
156
|
-
if (
|
|
154
|
+
if (SupportedPageTypes[target.name] === 'ListReport') {
|
|
157
155
|
hideFilterBar = target.options?.settings?.hideFilterBar ?? false;
|
|
158
156
|
}
|
|
159
157
|
}
|
|
160
158
|
}
|
|
161
159
|
if (!isFEV4) {
|
|
162
|
-
throw new
|
|
160
|
+
throw new ValidationError(t('error.badApplicationType'));
|
|
163
161
|
}
|
|
164
162
|
return { applicationType: 'v4', hideFilterBar }; // For the time being, only FE V4 is supported
|
|
165
163
|
}
|
|
@@ -174,7 +172,7 @@ function getAppFromManifest(manifest, forcedAppID) {
|
|
|
174
172
|
const appID = forcedAppID ?? manifest['sap.app']?.id;
|
|
175
173
|
const appPath = appID?.split('.').join('/');
|
|
176
174
|
if (!appID || !appPath) {
|
|
177
|
-
throw new
|
|
175
|
+
throw new ValidationError(t('error.cannotReadAppID'));
|
|
178
176
|
}
|
|
179
177
|
return { appID, appPath };
|
|
180
178
|
}
|
|
@@ -192,7 +190,7 @@ function createPageConfig(manifest, targetKey, forcedAppID) {
|
|
|
192
190
|
const { appID, appPath } = getAppFromManifest(manifest, forcedAppID);
|
|
193
191
|
if (target?.type === 'Component' &&
|
|
194
192
|
target?.name &&
|
|
195
|
-
target.name in
|
|
193
|
+
target.name in SupportedPageTypes &&
|
|
196
194
|
target?.id &&
|
|
197
195
|
(target?.options?.settings?.entitySet || target?.options?.settings?.contextPath)) {
|
|
198
196
|
const pageConfig = {
|
|
@@ -200,7 +198,7 @@ function createPageConfig(manifest, targetKey, forcedAppID) {
|
|
|
200
198
|
appID,
|
|
201
199
|
targetKey,
|
|
202
200
|
componentID: target.id,
|
|
203
|
-
template:
|
|
201
|
+
template: SupportedPageTypes[target.name],
|
|
204
202
|
isStartup: false
|
|
205
203
|
};
|
|
206
204
|
if (target.options.settings.contextPath) {
|
|
@@ -316,7 +314,7 @@ function writeCommonAndPageFiles(writeContext, rootCommonTemplateDirPath, useVir
|
|
|
316
314
|
const { config, rootV4TemplateDirPath, testOutDirPath, editor, journeyParams } = writeContext;
|
|
317
315
|
// Common test files (testsuite served virtually when useVirtualPreviewEndpoints is enabled)
|
|
318
316
|
if (!useVirtualPreviewEndpoints) {
|
|
319
|
-
editor.copyTpl(
|
|
317
|
+
editor.copyTpl(join(rootCommonTemplateDirPath), testOutDirPath,
|
|
320
318
|
// unit tests are not added for Fiori elements app
|
|
321
319
|
{ appId: config.appID }, undefined, {
|
|
322
320
|
globOptions: { dot: true }
|
|
@@ -325,11 +323,11 @@ function writeCommonAndPageFiles(writeContext, rootCommonTemplateDirPath, useVir
|
|
|
325
323
|
config.pages.forEach((page) => {
|
|
326
324
|
writePageObject(page, rootV4TemplateDirPath, testOutDirPath, editor);
|
|
327
325
|
});
|
|
328
|
-
editor.copyTpl(
|
|
326
|
+
editor.copyTpl(join(rootV4TemplateDirPath, 'integration', 'FirstJourney.js'), join(testOutDirPath, 'integration', `${config.opaJourneyFileName}.js`), journeyParams, undefined, {
|
|
329
327
|
globOptions: { dot: true }
|
|
330
328
|
});
|
|
331
329
|
// Journey Runner
|
|
332
|
-
editor.copyTpl(
|
|
330
|
+
editor.copyTpl(join(rootV4TemplateDirPath, 'integration', 'pages', 'JourneyRunner.js'), join(testOutDirPath, 'integration', 'pages', 'JourneyRunner.js'), config, undefined, {
|
|
333
331
|
globOptions: { dot: true }
|
|
334
332
|
});
|
|
335
333
|
}
|
|
@@ -345,7 +343,7 @@ function writeCommonAndPageFiles(writeContext, rootCommonTemplateDirPath, useVir
|
|
|
345
343
|
* @returns JourneyRunnerPage if the page was newly created, undefined otherwise
|
|
346
344
|
*/
|
|
347
345
|
function ensurePageExists(featureName, config, rootV4TemplateDirPath, testOutDirPath, editor) {
|
|
348
|
-
const pageFilePath =
|
|
346
|
+
const pageFilePath = join(testOutDirPath, 'integration', 'pages', `${featureName}.js`);
|
|
349
347
|
if (editor.exists(pageFilePath)) {
|
|
350
348
|
return undefined;
|
|
351
349
|
}
|
|
@@ -370,7 +368,7 @@ function writeJourneyFiles(appFeatures, writeContext, isStandalone, hasJourneyRu
|
|
|
370
368
|
const generatedJourneyPages = [];
|
|
371
369
|
const newPages = [];
|
|
372
370
|
if (appFeatures.listReport?.name) {
|
|
373
|
-
editor.copyTpl(
|
|
371
|
+
editor.copyTpl(join(rootV4TemplateDirPath, 'integration', 'ListReportJourney.js'), join(testOutDirPath, 'integration', `${appFeatures.listReport.name}Journey.js`), {
|
|
374
372
|
...journeyParams,
|
|
375
373
|
...appFeatures.listReport
|
|
376
374
|
}, undefined, {
|
|
@@ -385,7 +383,7 @@ function writeJourneyFiles(appFeatures, writeContext, isStandalone, hasJourneyRu
|
|
|
385
383
|
if (appFeatures.objectPages && appFeatures.objectPages.length > 0) {
|
|
386
384
|
appFeatures.objectPages.forEach((objectPage) => {
|
|
387
385
|
if (objectPage.name) {
|
|
388
|
-
editor.copyTpl(
|
|
386
|
+
editor.copyTpl(join(rootV4TemplateDirPath, 'integration', 'ObjectPageJourney.js'), join(testOutDirPath, 'integration', `${objectPage.name}Journey.js`), {
|
|
389
387
|
...journeyParams,
|
|
390
388
|
...objectPage,
|
|
391
389
|
isStandalone
|
|
@@ -401,7 +399,7 @@ function writeJourneyFiles(appFeatures, writeContext, isStandalone, hasJourneyRu
|
|
|
401
399
|
});
|
|
402
400
|
}
|
|
403
401
|
if (appFeatures.fpm?.name) {
|
|
404
|
-
editor.copyTpl(
|
|
402
|
+
editor.copyTpl(join(rootV4TemplateDirPath, 'integration', 'FPMJourney.js'), join(testOutDirPath, 'integration', `${appFeatures.fpm.name}Journey.js`), {
|
|
405
403
|
...journeyParams,
|
|
406
404
|
...appFeatures.fpm
|
|
407
405
|
}, undefined, {
|
|
@@ -414,16 +412,16 @@ function writeJourneyFiles(appFeatures, writeContext, isStandalone, hasJourneyRu
|
|
|
414
412
|
}
|
|
415
413
|
}
|
|
416
414
|
if (newPages.length > 0) {
|
|
417
|
-
|
|
415
|
+
addPagesToJourneyRunner(newPages, testOutDirPath, editor);
|
|
418
416
|
}
|
|
419
417
|
if (!virtualOPA5Configured) {
|
|
420
418
|
if (hasJourneyRunner) {
|
|
421
|
-
|
|
419
|
+
addPathsToQUnitJs(generatedJourneyPages.map((page) => {
|
|
422
420
|
return `${config.appPath}/test/integration/${page}Journey`;
|
|
423
421
|
}), testOutDirPath, editor);
|
|
424
422
|
}
|
|
425
423
|
else {
|
|
426
|
-
editor.copyTpl(
|
|
424
|
+
editor.copyTpl(join(rootV4TemplateDirPath, 'integration', 'opaTests.*.*'), join(testOutDirPath, 'integration'), { ...config, generatedJourneyPages }, undefined, {
|
|
427
425
|
globOptions: { dot: true }
|
|
428
426
|
});
|
|
429
427
|
}
|
|
@@ -438,7 +436,7 @@ function writeJourneyFiles(appFeatures, writeContext, isStandalone, hasJourneyRu
|
|
|
438
436
|
* @param fs - a reference to a mem-fs editor
|
|
439
437
|
*/
|
|
440
438
|
function writePageObject(pageConfig, rootTemplateDirPath, testOutDirPath, fs) {
|
|
441
|
-
fs.copyTpl(
|
|
439
|
+
fs.copyTpl(join(rootTemplateDirPath, 'integration', 'pages', `${pageConfig.template}.js`), join(testOutDirPath, 'integration', 'pages', `${pageConfig.targetKey}.js`), pageConfig, undefined, {
|
|
442
440
|
globOptions: { dot: true }
|
|
443
441
|
});
|
|
444
442
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const ui5_application_writer_1 = require("@sap-ux/ui5-application-writer");
|
|
1
|
+
import { dirname, join, sep } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { create as createStorage } from 'mem-fs';
|
|
4
|
+
import { create } from 'mem-fs-editor';
|
|
5
|
+
import { getFilePaths, FileName } from '@sap-ux/project-access';
|
|
6
|
+
import { t } from './i18n.js';
|
|
7
|
+
import { compareUI5VersionGte, ui5LtsVersion_1_71, ui5LtsVersion_1_120 } from '@sap-ux/ui5-application-writer';
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
9
|
/**
|
|
11
10
|
* Updates tsconfig.json to include paths for unit and integration tests.
|
|
12
11
|
*
|
|
@@ -16,15 +15,15 @@ const ui5_application_writer_1 = require("@sap-ux/ui5-application-writer");
|
|
|
16
15
|
*/
|
|
17
16
|
function writeOPATsconfigJsonUpdates(fs, destinationRoot, log) {
|
|
18
17
|
try {
|
|
19
|
-
const tsconfig = fs.readJSON(
|
|
18
|
+
const tsconfig = fs.readJSON(join(destinationRoot, FileName.Tsconfig)) ?? {};
|
|
20
19
|
tsconfig.compilerOptions = tsconfig.compilerOptions || {};
|
|
21
20
|
tsconfig.compilerOptions.paths = tsconfig.compilerOptions.paths || {};
|
|
22
21
|
tsconfig.compilerOptions.paths['unit/*'] = ['./webapp/test/unit/*'];
|
|
23
22
|
tsconfig.compilerOptions.paths['integration/*'] = ['./webapp/test/integration/*'];
|
|
24
|
-
fs.writeJSON(
|
|
23
|
+
fs.writeJSON(join(destinationRoot, FileName.Tsconfig), tsconfig);
|
|
25
24
|
}
|
|
26
25
|
catch (error) {
|
|
27
|
-
log?.error(
|
|
26
|
+
log?.error(t('error.errorWritingTsConfig', {
|
|
28
27
|
error: error
|
|
29
28
|
}));
|
|
30
29
|
}
|
|
@@ -37,9 +36,9 @@ function writeOPATsconfigJsonUpdates(fs, destinationRoot, log) {
|
|
|
37
36
|
*/
|
|
38
37
|
function getTemplateUi5Version(ui5Version) {
|
|
39
38
|
if (!ui5Version) {
|
|
40
|
-
return
|
|
39
|
+
return ui5LtsVersion_1_120;
|
|
41
40
|
}
|
|
42
|
-
return
|
|
41
|
+
return compareUI5VersionGte(ui5Version, ui5LtsVersion_1_120) ? ui5LtsVersion_1_120 : ui5LtsVersion_1_71;
|
|
43
42
|
}
|
|
44
43
|
/**
|
|
45
44
|
* Filters files based on the template UI5 version.
|
|
@@ -55,7 +54,7 @@ function filterByUi5Version(files, templateUi5Version) {
|
|
|
55
54
|
return true;
|
|
56
55
|
}
|
|
57
56
|
// For all other files, include only those in the current UI5 version directory.
|
|
58
|
-
return filePath.includes(`${
|
|
57
|
+
return filePath.includes(`${sep}${templateUi5Version}${sep}`);
|
|
59
58
|
});
|
|
60
59
|
}
|
|
61
60
|
/**
|
|
@@ -88,7 +87,7 @@ function filterByTypeScript(files, isTypeScript) {
|
|
|
88
87
|
*/
|
|
89
88
|
function getDestFilePath(filePath, freestyleTemplateDir, commonTemplateDir, templateUi5Version) {
|
|
90
89
|
if (filePath.includes(freestyleTemplateDir)) {
|
|
91
|
-
return filePath.replace(freestyleTemplateDir, '').replace(`${
|
|
90
|
+
return filePath.replace(freestyleTemplateDir, '').replace(`${sep}${templateUi5Version}${sep}`, sep);
|
|
92
91
|
}
|
|
93
92
|
else if (filePath.includes(commonTemplateDir)) {
|
|
94
93
|
return filePath.replace(commonTemplateDir, '');
|
|
@@ -106,16 +105,16 @@ function getDestFilePath(filePath, freestyleTemplateDir, commonTemplateDir, temp
|
|
|
106
105
|
* @param {Logger} log - Optional logger instance.
|
|
107
106
|
* @returns {Editor} - The modified file system editor.
|
|
108
107
|
*/
|
|
109
|
-
async function generateFreestyleOPAFiles(basePath, opaConfig, fs, log) {
|
|
110
|
-
const fsEditor = fs ??
|
|
108
|
+
export async function generateFreestyleOPAFiles(basePath, opaConfig, fs, log) {
|
|
109
|
+
const fsEditor = fs ?? create(createStorage());
|
|
111
110
|
const { enableTypeScript, ui5Version, viewName, appId, useVirtualPreviewEndpoints } = opaConfig;
|
|
112
|
-
const freestyleTemplateDir =
|
|
113
|
-
const commonTemplateDir =
|
|
114
|
-
const testOutDir =
|
|
111
|
+
const freestyleTemplateDir = join(__dirname, '../templates/freestyle/webapp/test');
|
|
112
|
+
const commonTemplateDir = join(__dirname, '../templates/common');
|
|
113
|
+
const testOutDir = join(basePath, 'webapp/test');
|
|
115
114
|
const templateUi5Version = getTemplateUi5Version(ui5Version);
|
|
116
115
|
const appIdWithSlash = appId.replace(/[.]/g, '/'); // Replace all dots with slashes
|
|
117
116
|
const navigationIntent = appId.replace(/[./\\\-\s]/g, ''); // Remove all dots, slashes, dashes, and spaces
|
|
118
|
-
const templateFiles = await
|
|
117
|
+
const templateFiles = await getFilePaths(freestyleTemplateDir);
|
|
119
118
|
const isTypeScript = Boolean(enableTypeScript);
|
|
120
119
|
const templateFilteredFiles = filterByUi5Version(templateFiles, templateUi5Version);
|
|
121
120
|
let filteredFiles = filterByTypeScript(templateFilteredFiles, isTypeScript);
|
|
@@ -123,7 +122,7 @@ async function generateFreestyleOPAFiles(basePath, opaConfig, fs, log) {
|
|
|
123
122
|
filteredFiles = filteredFiles.filter((filePath) => !['testsuite.qunit', 'unitTests.qunit', 'opaTests.qunit'].some((pattern) => filePath.includes(pattern)));
|
|
124
123
|
}
|
|
125
124
|
else {
|
|
126
|
-
const commonFiles = await
|
|
125
|
+
const commonFiles = await getFilePaths(commonTemplateDir);
|
|
127
126
|
filteredFiles.push(...commonFiles.filter((f) => f.endsWith('.html')));
|
|
128
127
|
}
|
|
129
128
|
const config = {
|
|
@@ -137,10 +136,10 @@ async function generateFreestyleOPAFiles(basePath, opaConfig, fs, log) {
|
|
|
137
136
|
// - viewName.js files are renamed to include the view name in their file path
|
|
138
137
|
// - viewName.ts files are renamed with the view name appended with 'Page'
|
|
139
138
|
const renameMap = {
|
|
140
|
-
[
|
|
141
|
-
[
|
|
142
|
-
[
|
|
143
|
-
[
|
|
139
|
+
[join('/integration/pages/viewName.js')]: join(`integration/pages/${viewName}.js`),
|
|
140
|
+
[join('/integration/pages/viewName.ts')]: join(`integration/pages/${viewName}Page.ts`),
|
|
141
|
+
[join('/unit/controller/viewName.controller.js')]: join(`unit/controller/${viewName}.controller.js`),
|
|
142
|
+
[join('/unit/controller/viewName.controller.ts')]: join(`unit/controller/${viewName}Page.controller.ts`)
|
|
144
143
|
};
|
|
145
144
|
// copy templates
|
|
146
145
|
let freestyleTestTemplatesCopied = false;
|
|
@@ -148,7 +147,7 @@ async function generateFreestyleOPAFiles(basePath, opaConfig, fs, log) {
|
|
|
148
147
|
filteredFiles.forEach((filePath) => {
|
|
149
148
|
// remove template UI5 version from the path
|
|
150
149
|
const destFilePath = getDestFilePath(filePath, freestyleTemplateDir, commonTemplateDir, templateUi5Version);
|
|
151
|
-
const destinationFilePath =
|
|
150
|
+
const destinationFilePath = join(testOutDir, renameMap?.[destFilePath] ?? destFilePath);
|
|
152
151
|
fsEditor.copyTpl(filePath, destinationFilePath, config, undefined, {
|
|
153
152
|
globOptions: { dot: true }
|
|
154
153
|
});
|
|
@@ -156,7 +155,7 @@ async function generateFreestyleOPAFiles(basePath, opaConfig, fs, log) {
|
|
|
156
155
|
freestyleTestTemplatesCopied = true;
|
|
157
156
|
}
|
|
158
157
|
catch (error) {
|
|
159
|
-
log?.error(
|
|
158
|
+
log?.error(t('error.errorCopyingFreestyleTestTemplates', {
|
|
160
159
|
error: error
|
|
161
160
|
}));
|
|
162
161
|
}
|
package/dist/i18n.js
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.i18n = void 0;
|
|
7
|
-
exports.initI18n = initI18n;
|
|
8
|
-
exports.t = t;
|
|
9
|
-
const i18next_1 = __importDefault(require("i18next"));
|
|
10
|
-
const ui5_test_writer_i18n_json_1 = __importDefault(require("./translations/ui5-test-writer.i18n.json"));
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
import translations from './translations/ui5-test-writer.i18n.json' with { type: 'json' };
|
|
11
3
|
const NS = 'ui5-test-writer';
|
|
12
|
-
|
|
4
|
+
export const i18n = i18next.createInstance();
|
|
13
5
|
/**
|
|
14
6
|
* Initialize i18next with the translations for this module.
|
|
15
7
|
*/
|
|
16
|
-
async function initI18n() {
|
|
17
|
-
await
|
|
8
|
+
export async function initI18n() {
|
|
9
|
+
await i18n.init({
|
|
18
10
|
resources: {
|
|
19
11
|
en: {
|
|
20
|
-
[NS]:
|
|
12
|
+
[NS]: translations
|
|
21
13
|
}
|
|
22
14
|
},
|
|
23
15
|
lng: 'en',
|
|
@@ -34,10 +26,8 @@ async function initI18n() {
|
|
|
34
26
|
* @param options additional options
|
|
35
27
|
* @returns {string} localized string stored for the given key
|
|
36
28
|
*/
|
|
37
|
-
function t(key, options) {
|
|
38
|
-
return
|
|
29
|
+
export function t(key, options) {
|
|
30
|
+
return i18n.t(key, options);
|
|
39
31
|
}
|
|
40
|
-
initI18n().catch(() =>
|
|
41
|
-
// Ignore any errors since the write will still work
|
|
42
|
-
});
|
|
32
|
+
void initI18n().catch(() => undefined);
|
|
43
33
|
//# sourceMappingURL=i18n.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { generateOPAFiles } from './fiori-elements-opa-writer';
|
|
2
|
-
export { generateFreestyleOPAFiles } from './fiori-freestyle-opa-writer';
|
|
3
|
-
export { addVirtualTestConfig } from './utils/opaQUnitUtils';
|
|
1
|
+
export { generateOPAFiles } from './fiori-elements-opa-writer.js';
|
|
2
|
+
export { generateFreestyleOPAFiles } from './fiori-freestyle-opa-writer.js';
|
|
3
|
+
export { addVirtualTestConfig } from './utils/opaQUnitUtils.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var fiori_elements_opa_writer_1 = require("./fiori-elements-opa-writer");
|
|
5
|
-
Object.defineProperty(exports, "generateOPAFiles", { enumerable: true, get: function () { return fiori_elements_opa_writer_1.generateOPAFiles; } });
|
|
6
|
-
var fiori_freestyle_opa_writer_1 = require("./fiori-freestyle-opa-writer");
|
|
7
|
-
Object.defineProperty(exports, "generateFreestyleOPAFiles", { enumerable: true, get: function () { return fiori_freestyle_opa_writer_1.generateFreestyleOPAFiles; } });
|
|
8
|
-
var opaQUnitUtils_1 = require("./utils/opaQUnitUtils");
|
|
9
|
-
Object.defineProperty(exports, "addVirtualTestConfig", { enumerable: true, get: function () { return opaQUnitUtils_1.addVirtualTestConfig; } });
|
|
1
|
+
export { generateOPAFiles } from './fiori-elements-opa-writer.js';
|
|
2
|
+
export { generateFreestyleOPAFiles } from './fiori-freestyle-opa-writer.js';
|
|
3
|
+
export { addVirtualTestConfig } from './utils/opaQUnitUtils.js';
|
|
10
4
|
//# sourceMappingURL=index.js.map
|
package/dist/types.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ValidationError = exports.SupportedPageTypes = void 0;
|
|
4
|
-
exports.SupportedPageTypes = {
|
|
1
|
+
export const SupportedPageTypes = {
|
|
5
2
|
'sap.fe.templates.ListReport': 'ListReport',
|
|
6
3
|
'sap.fe.templates.ObjectPage': 'ObjectPage',
|
|
7
4
|
'sap.fe.core.fpm': 'FPM'
|
|
@@ -9,7 +6,7 @@ exports.SupportedPageTypes = {
|
|
|
9
6
|
/**
|
|
10
7
|
* General validation error thrown if app config options contain invalid combinations
|
|
11
8
|
*/
|
|
12
|
-
class ValidationError extends Error {
|
|
9
|
+
export class ValidationError extends Error {
|
|
13
10
|
/**
|
|
14
11
|
* ValidationError constructor.
|
|
15
12
|
*
|
|
@@ -20,5 +17,4 @@ class ValidationError extends Error {
|
|
|
20
17
|
this.name = this.constructor.name;
|
|
21
18
|
}
|
|
22
19
|
}
|
|
23
|
-
exports.ValidationError = ValidationError;
|
|
24
20
|
//# sourceMappingURL=types.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ConvertedMetadata } from '@sap-ux/vocabularies-types';
|
|
2
|
-
import type { ActionButtonState, ButtonState, ButtonVisibilityResult } from '../types';
|
|
3
|
-
import type { DataFieldForAction } from '@sap-ux/vocabularies-types/vocabularies/UI';
|
|
4
|
-
import type { OperationAvailable } from '@sap-ux/vocabularies-types/vocabularies/Core';
|
|
5
|
-
import type { DeleteRestrictionsType, InsertRestrictionsType, UpdateRestrictionsType } from '@sap-ux/vocabularies-types/vocabularies/Capabilities';
|
|
2
|
+
import type { ActionButtonState, ButtonState, ButtonVisibilityResult } from '../types.js';
|
|
3
|
+
import type { DataFieldForAction } from '@sap-ux/vocabularies-types/vocabularies/UI.js';
|
|
4
|
+
import type { OperationAvailable } from '@sap-ux/vocabularies-types/vocabularies/Core.js';
|
|
5
|
+
import type { DeleteRestrictionsType, InsertRestrictionsType, UpdateRestrictionsType } from '@sap-ux/vocabularies-types/vocabularies/Capabilities.js';
|
|
6
6
|
import type { Logger } from '@sap-ux/logger';
|
|
7
7
|
type OperationAvailableWithPaths = OperationAvailable & {
|
|
8
8
|
$Path?: string;
|