@sap-ux/ui5-test-writer 0.4.1 → 0.5.1
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 +43 -0
- package/dist/fiori-elements-opa-writer.js +283 -0
- package/dist/fiori-freestyle-opa-writer.d.ts +14 -0
- package/dist/fiori-freestyle-opa-writer.js +166 -0
- package/dist/i18n.js +2 -3
- package/dist/index.d.ts +2 -33
- package/dist/index.js +5 -275
- package/dist/translations/ui5-test-writer.i18n.json +3 -1
- package/dist/types.d.ts +12 -0
- package/package.json +5 -3
- package/templates/freestyle/webapp/test/1.120.0/integration/AllJourneys.js +13 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/NavigationJourney.js +23 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/NavigationJourney.ts +34 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/arrangements/Startup.js +25 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.html +29 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.js +7 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.ts +6 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/pages/App.js +28 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/pages/AppPage.ts +22 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/pages/viewName.js +28 -0
- package/templates/freestyle/webapp/test/1.120.0/integration/pages/viewName.ts +23 -0
- package/templates/freestyle/webapp/test/1.120.0/unit/AllTests.js +5 -0
- package/templates/freestyle/webapp/test/1.120.0/unit/controller/viewName.controller.js +16 -0
- package/templates/freestyle/webapp/test/1.120.0/unit/controller/viewName.controller.ts +10 -0
- package/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.html +28 -0
- package/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.js +12 -0
- package/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.ts +10 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/AllJourneys.js +13 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.js +23 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.ts +34 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/arrangements/Startup.js +25 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.html +29 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.js +7 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.ts +10 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/pages/App.js +28 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/pages/AppPage.ts +22 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.js +28 -0
- package/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.ts +23 -0
- package/templates/freestyle/webapp/test/1.71.0/unit/AllTests.js +5 -0
- package/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.js +16 -0
- package/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.ts +10 -0
- package/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.html +27 -0
- package/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.js +12 -0
- package/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.ts +10 -0
- package/templates/freestyle/webapp/test/testsuite.qunit.js +16 -0
- package/templates/freestyle/webapp/test/testsuite.qunit.ts +14 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Editor } from 'mem-fs-editor';
|
|
2
|
+
import type { Manifest } from '@sap-ux/project-access';
|
|
3
|
+
/**
|
|
4
|
+
* Reads the manifest for an app.
|
|
5
|
+
*
|
|
6
|
+
* @param fs - a reference to a mem-fs editor
|
|
7
|
+
* @param basePath - the root folder of the app
|
|
8
|
+
* @returns the manifest object. An exception is thrown if the manifest cannot be read.
|
|
9
|
+
*/
|
|
10
|
+
export declare function readManifest(fs: Editor, basePath: string): Manifest;
|
|
11
|
+
/**
|
|
12
|
+
* Generate OPA test files for a Fiori elements for OData V4 application.
|
|
13
|
+
* Note: this can potentially overwrite existing files in the webapp/test folder.
|
|
14
|
+
*
|
|
15
|
+
* @param basePath - the absolute target path where the application will be generated
|
|
16
|
+
* @param opaConfig - parameters for the generation
|
|
17
|
+
* @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used
|
|
18
|
+
* @param opaConfig.htmlTarget - the name of the html that will be used in OPA journey file. If not specified, 'index.html' will be used
|
|
19
|
+
* @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id
|
|
20
|
+
* @param fs - an optional reference to a mem-fs editor
|
|
21
|
+
* @returns Reference to a mem-fs-editor
|
|
22
|
+
*/
|
|
23
|
+
export declare function generateOPAFiles(basePath: string, opaConfig: {
|
|
24
|
+
scriptName?: string;
|
|
25
|
+
appID?: string;
|
|
26
|
+
htmlTarget?: string;
|
|
27
|
+
}, fs?: Editor): Editor;
|
|
28
|
+
/**
|
|
29
|
+
* Generate a page object file for a Fiori elements for OData V4 application.
|
|
30
|
+
* Note: this doesn't modify other existing files in the webapp/test folder.
|
|
31
|
+
*
|
|
32
|
+
* @param basePath - the absolute target path where the application will be generated
|
|
33
|
+
* @param pageObjectParameters - parameters for the page
|
|
34
|
+
* @param pageObjectParameters.targetKey - the key of the target in the manifest file corresponding to the page
|
|
35
|
+
* @param pageObjectParameters.appID - the appID. If not specified, will be read from the manifest in sap.app/id
|
|
36
|
+
* @param fs - an optional reference to a mem-fs editor
|
|
37
|
+
* @returns Reference to a mem-fs-editor
|
|
38
|
+
*/
|
|
39
|
+
export declare function generatePageObjectFile(basePath: string, pageObjectParameters: {
|
|
40
|
+
targetKey: string;
|
|
41
|
+
appID?: string;
|
|
42
|
+
}, fs?: Editor): Editor;
|
|
43
|
+
//# sourceMappingURL=fiori-elements-opa-writer.d.ts.map
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readManifest = readManifest;
|
|
4
|
+
exports.generateOPAFiles = generateOPAFiles;
|
|
5
|
+
exports.generatePageObjectFile = generatePageObjectFile;
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const mem_fs_1 = require("mem-fs");
|
|
8
|
+
const mem_fs_editor_1 = require("mem-fs-editor");
|
|
9
|
+
const types_1 = require("./types");
|
|
10
|
+
const i18n_1 = require("./i18n");
|
|
11
|
+
const project_access_1 = require("@sap-ux/project-access");
|
|
12
|
+
/**
|
|
13
|
+
* Reads the manifest for an app.
|
|
14
|
+
*
|
|
15
|
+
* @param fs - a reference to a mem-fs editor
|
|
16
|
+
* @param basePath - the root folder of the app
|
|
17
|
+
* @returns the manifest object. An exception is thrown if the manifest cannot be read.
|
|
18
|
+
*/
|
|
19
|
+
function readManifest(fs, basePath) {
|
|
20
|
+
const manifest = fs.readJSON((0, path_1.join)(basePath, project_access_1.DirName.Webapp, project_access_1.FileName.Manifest));
|
|
21
|
+
if (!manifest) {
|
|
22
|
+
throw new types_1.ValidationError((0, i18n_1.t)('error.cannotReadManifest', {
|
|
23
|
+
filePath: (0, path_1.join)(basePath, project_access_1.DirName.Webapp, project_access_1.FileName.Manifest)
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
return manifest;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Retrieves the application type of the main datasource (FreeStyle, FE V2 or FE V4).
|
|
30
|
+
*
|
|
31
|
+
* @param manifest - the app descriptor of the app
|
|
32
|
+
* @returns {{ applicationType: string, hideFilterBar: boolean }} An object containing the application type and hideFilterBar flag. An exception is thrown if it can't be found or if it's not supported
|
|
33
|
+
*/
|
|
34
|
+
function getAppTypeAndHideFilterBarFromManifest(manifest) {
|
|
35
|
+
const appTargets = manifest['sap.ui5']?.routing?.targets;
|
|
36
|
+
let hideFilterBar = false;
|
|
37
|
+
let isFEV4 = false;
|
|
38
|
+
for (const targetKey in appTargets) {
|
|
39
|
+
const target = appTargets[targetKey];
|
|
40
|
+
if (target.type === 'Component' && target.name && target.name in types_1.SupportedPageTypes) {
|
|
41
|
+
isFEV4 = true;
|
|
42
|
+
if (types_1.SupportedPageTypes[target.name] === 'ListReport') {
|
|
43
|
+
hideFilterBar = target.options?.settings?.hideFilterBar ?? false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (!isFEV4) {
|
|
48
|
+
throw new types_1.ValidationError((0, i18n_1.t)('error.badApplicationType'));
|
|
49
|
+
}
|
|
50
|
+
return { applicationType: 'v4', hideFilterBar }; // For the time being, only FE V4 is supported
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Retrieves appID and appPath from the manifest.
|
|
54
|
+
*
|
|
55
|
+
* @param manifest - the app descriptor of the app
|
|
56
|
+
* @param forcedAppID - the appID in case we don't want to read it from the manifest
|
|
57
|
+
* @returns appID and appPath
|
|
58
|
+
*/
|
|
59
|
+
function getAppFromManifest(manifest, forcedAppID) {
|
|
60
|
+
const appID = forcedAppID ?? manifest['sap.app']?.id;
|
|
61
|
+
const appPath = appID?.split('.').join('/');
|
|
62
|
+
if (!appID || !appPath) {
|
|
63
|
+
throw new types_1.ValidationError((0, i18n_1.t)('error.cannotReadAppID'));
|
|
64
|
+
}
|
|
65
|
+
return { appID, appPath };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create the page configuration object from the app descriptor and the target key.
|
|
69
|
+
*
|
|
70
|
+
* @param manifest - the app descriptor of the app
|
|
71
|
+
* @param targetKey - the key of the target in the manifest
|
|
72
|
+
* @param forcedAppID - the appID in case we don't want to read it from the manifest
|
|
73
|
+
* @returns Page configuration object, or undefined if the target type is not supported
|
|
74
|
+
*/
|
|
75
|
+
function createPageConfig(manifest, targetKey, forcedAppID) {
|
|
76
|
+
const appTargets = manifest['sap.ui5']?.routing?.targets;
|
|
77
|
+
const target = appTargets && appTargets[targetKey];
|
|
78
|
+
const { appID, appPath } = getAppFromManifest(manifest, forcedAppID);
|
|
79
|
+
if (target?.type === 'Component' &&
|
|
80
|
+
target?.name &&
|
|
81
|
+
target.name in types_1.SupportedPageTypes &&
|
|
82
|
+
target?.id &&
|
|
83
|
+
(target?.options?.settings?.entitySet || target?.options?.settings?.contextPath)) {
|
|
84
|
+
const pageConfig = {
|
|
85
|
+
appPath,
|
|
86
|
+
appID,
|
|
87
|
+
targetKey,
|
|
88
|
+
componentID: target.id,
|
|
89
|
+
template: types_1.SupportedPageTypes[target.name],
|
|
90
|
+
isStartup: false
|
|
91
|
+
};
|
|
92
|
+
if (target.options.settings.contextPath) {
|
|
93
|
+
pageConfig.contextPath = target.options.settings.contextPath;
|
|
94
|
+
}
|
|
95
|
+
else if (target.options.settings.entitySet) {
|
|
96
|
+
pageConfig.entitySet = target.options.settings.entitySet;
|
|
97
|
+
}
|
|
98
|
+
return pageConfig;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create the configuration object from the app descriptor.
|
|
106
|
+
*
|
|
107
|
+
* @param manifest - the app descriptor of the target app
|
|
108
|
+
* @param opaConfig - parameters for the generation
|
|
109
|
+
* @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used
|
|
110
|
+
* @param opaConfig.htmlTarget - the name of the html file that will be used in the OPA journey file. If not specified, 'index.html' will be used
|
|
111
|
+
* @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id
|
|
112
|
+
* @param hideFilterBar - whether the filter bar should be hidden in the generated tests
|
|
113
|
+
* @returns OPA test configuration object
|
|
114
|
+
*/
|
|
115
|
+
function createConfig(manifest, opaConfig, hideFilterBar) {
|
|
116
|
+
// General application info
|
|
117
|
+
const { appID, appPath } = getAppFromManifest(manifest, opaConfig.appID);
|
|
118
|
+
const config = {
|
|
119
|
+
appID,
|
|
120
|
+
appPath,
|
|
121
|
+
pages: [],
|
|
122
|
+
opaJourneyFileName: opaConfig.scriptName ?? 'FirstJourney',
|
|
123
|
+
htmlTarget: opaConfig.htmlTarget ?? 'index.html',
|
|
124
|
+
hideFilterBar
|
|
125
|
+
};
|
|
126
|
+
// Identify startup targets from the routes
|
|
127
|
+
const appRoutes = (manifest['sap.ui5']?.routing?.routes ?? []);
|
|
128
|
+
// Find the route with an empty pattern (except for the trailing query part)
|
|
129
|
+
const startupRoute = appRoutes.find((route) => {
|
|
130
|
+
return route.pattern.replace(':?query:', '') === '';
|
|
131
|
+
});
|
|
132
|
+
let startupTargets = startupRoute?.target ?? [];
|
|
133
|
+
if (!Array.isArray(startupTargets)) {
|
|
134
|
+
startupTargets = [startupTargets];
|
|
135
|
+
}
|
|
136
|
+
// Create page configurations in supported cases
|
|
137
|
+
const appTargets = manifest['sap.ui5']?.routing?.targets;
|
|
138
|
+
for (const targetKey in appTargets) {
|
|
139
|
+
const pageConfig = createPageConfig(manifest, targetKey, opaConfig.appID);
|
|
140
|
+
if (pageConfig) {
|
|
141
|
+
pageConfig.isStartup = startupTargets.includes(targetKey);
|
|
142
|
+
config.pages.push(pageConfig);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return config;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Finds the initial ListReport page and the first Object page from the app.
|
|
149
|
+
*
|
|
150
|
+
* @param pages - the page configs of the app
|
|
151
|
+
* @param manifest - the app descriptor of the target app
|
|
152
|
+
* @returns the page fonfigs for the LR and the OP if they're found
|
|
153
|
+
*/
|
|
154
|
+
function findLROP(pages, manifest) {
|
|
155
|
+
const pageLR = pages.find((page) => {
|
|
156
|
+
return page.isStartup && page.template === 'ListReport';
|
|
157
|
+
});
|
|
158
|
+
if (!pageLR) {
|
|
159
|
+
return {};
|
|
160
|
+
}
|
|
161
|
+
const appTargets = manifest['sap.ui5']?.routing?.targets;
|
|
162
|
+
const appRoutes = (manifest['sap.ui5']?.routing?.routes ?? []);
|
|
163
|
+
const target = appTargets?.[pageLR.targetKey];
|
|
164
|
+
if (!target?.options?.settings?.navigation) {
|
|
165
|
+
return { pageLR }; // No navigation from LR
|
|
166
|
+
}
|
|
167
|
+
// Find all targets that can be navigated from the LR page
|
|
168
|
+
const navigatedTargetKeys = [];
|
|
169
|
+
for (const navKey in target.options.settings.navigation) {
|
|
170
|
+
const navObject = target.options.settings.navigation[navKey];
|
|
171
|
+
const navigatedRoute = navObject.detail?.route &&
|
|
172
|
+
appRoutes.find((route) => {
|
|
173
|
+
return route.name === navObject.detail?.route;
|
|
174
|
+
});
|
|
175
|
+
if (Array.isArray(navigatedRoute?.target)) {
|
|
176
|
+
navigatedTargetKeys.push(...navigatedRoute.target);
|
|
177
|
+
}
|
|
178
|
+
else if (navigatedRoute?.target) {
|
|
179
|
+
navigatedTargetKeys.push(navigatedRoute.target);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Find the first navigated page that is valid and not the starting LR
|
|
183
|
+
let pageOP;
|
|
184
|
+
for (let i = 0; i < navigatedTargetKeys.length && !pageOP; i++) {
|
|
185
|
+
if (navigatedTargetKeys[i] === pageLR.targetKey) {
|
|
186
|
+
continue; // This can happen in the FCL case where the LR is also part of the route's targets to the OP
|
|
187
|
+
}
|
|
188
|
+
pageOP = pages.find((page) => {
|
|
189
|
+
return page.targetKey === navigatedTargetKeys[i];
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return { pageLR, pageOP };
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Writes a page object in a mem-fs-editor.
|
|
196
|
+
*
|
|
197
|
+
* @param pageConfig - the page configuration object
|
|
198
|
+
* @param rootTemplateDirPath - template root directory
|
|
199
|
+
* @param testOutDirPath - output test directory (.../webapp/test)
|
|
200
|
+
* @param fs - a reference to a mem-fs editor
|
|
201
|
+
*/
|
|
202
|
+
function writePageObject(pageConfig, rootTemplateDirPath, testOutDirPath, fs) {
|
|
203
|
+
fs.copyTpl((0, path_1.join)(rootTemplateDirPath, `integration/pages/${pageConfig.template}.js`), (0, path_1.join)(testOutDirPath, `integration/pages/${pageConfig.targetKey}.js`), pageConfig, undefined, {
|
|
204
|
+
globOptions: { dot: true }
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Generate OPA test files for a Fiori elements for OData V4 application.
|
|
209
|
+
* Note: this can potentially overwrite existing files in the webapp/test folder.
|
|
210
|
+
*
|
|
211
|
+
* @param basePath - the absolute target path where the application will be generated
|
|
212
|
+
* @param opaConfig - parameters for the generation
|
|
213
|
+
* @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used
|
|
214
|
+
* @param opaConfig.htmlTarget - the name of the html that will be used in OPA journey file. If not specified, 'index.html' will be used
|
|
215
|
+
* @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id
|
|
216
|
+
* @param fs - an optional reference to a mem-fs editor
|
|
217
|
+
* @returns Reference to a mem-fs-editor
|
|
218
|
+
*/
|
|
219
|
+
function generateOPAFiles(basePath, opaConfig, fs) {
|
|
220
|
+
const editor = fs ?? (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
|
|
221
|
+
const manifest = readManifest(editor, basePath);
|
|
222
|
+
const { applicationType, hideFilterBar } = getAppTypeAndHideFilterBarFromManifest(manifest);
|
|
223
|
+
const config = createConfig(manifest, opaConfig, hideFilterBar);
|
|
224
|
+
const rootCommonTemplateDirPath = (0, path_1.join)(__dirname, '../templates/common');
|
|
225
|
+
const rootV4TemplateDirPath = (0, path_1.join)(__dirname, `../templates/${applicationType}`); // Only v4 is supported for the time being
|
|
226
|
+
const testOutDirPath = (0, path_1.join)(basePath, 'webapp/test');
|
|
227
|
+
// Common test files
|
|
228
|
+
editor.copyTpl((0, path_1.join)(rootCommonTemplateDirPath), testOutDirPath,
|
|
229
|
+
// unit tests are not added for Fiori elements app
|
|
230
|
+
{ appId: config.appID }, undefined, {
|
|
231
|
+
globOptions: { dot: true }
|
|
232
|
+
});
|
|
233
|
+
// Integration (OPA) test files - version-specific
|
|
234
|
+
editor.copyTpl((0, path_1.join)(rootV4TemplateDirPath, 'integration', 'opaTests.*.*'), (0, path_1.join)(testOutDirPath, 'integration'), config, undefined, {
|
|
235
|
+
globOptions: { dot: true }
|
|
236
|
+
});
|
|
237
|
+
// Pages files (one for each page in the app)
|
|
238
|
+
config.pages.forEach((page) => {
|
|
239
|
+
writePageObject(page, rootV4TemplateDirPath, testOutDirPath, editor);
|
|
240
|
+
});
|
|
241
|
+
// OPA Journey file
|
|
242
|
+
const startPages = config.pages.filter((page) => page.isStartup).map((page) => page.targetKey);
|
|
243
|
+
const LROP = findLROP(config.pages, manifest);
|
|
244
|
+
const journeyParams = {
|
|
245
|
+
startPages,
|
|
246
|
+
startLR: LROP.pageLR?.targetKey,
|
|
247
|
+
navigatedOP: LROP.pageOP?.targetKey,
|
|
248
|
+
hideFilterBar: config.hideFilterBar
|
|
249
|
+
};
|
|
250
|
+
editor.copyTpl((0, path_1.join)(rootV4TemplateDirPath, 'integration/FirstJourney.js'), (0, path_1.join)(testOutDirPath, `integration/${config.opaJourneyFileName}.js`), journeyParams, undefined, {
|
|
251
|
+
globOptions: { dot: true }
|
|
252
|
+
});
|
|
253
|
+
return editor;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Generate a page object file for a Fiori elements for OData V4 application.
|
|
257
|
+
* Note: this doesn't modify other existing files in the webapp/test folder.
|
|
258
|
+
*
|
|
259
|
+
* @param basePath - the absolute target path where the application will be generated
|
|
260
|
+
* @param pageObjectParameters - parameters for the page
|
|
261
|
+
* @param pageObjectParameters.targetKey - the key of the target in the manifest file corresponding to the page
|
|
262
|
+
* @param pageObjectParameters.appID - the appID. If not specified, will be read from the manifest in sap.app/id
|
|
263
|
+
* @param fs - an optional reference to a mem-fs editor
|
|
264
|
+
* @returns Reference to a mem-fs-editor
|
|
265
|
+
*/
|
|
266
|
+
function generatePageObjectFile(basePath, pageObjectParameters, fs) {
|
|
267
|
+
const editor = fs || (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
|
|
268
|
+
const manifest = readManifest(editor, basePath);
|
|
269
|
+
const { applicationType } = getAppTypeAndHideFilterBarFromManifest(manifest);
|
|
270
|
+
const pageConfig = createPageConfig(manifest, pageObjectParameters.targetKey, pageObjectParameters.appID);
|
|
271
|
+
if (pageConfig) {
|
|
272
|
+
const rootTemplateDirPath = (0, path_1.join)(__dirname, `../templates/${applicationType}`); // Only v4 is supported for the time being
|
|
273
|
+
const testOutDirPath = (0, path_1.join)(basePath, 'webapp/test');
|
|
274
|
+
writePageObject(pageConfig, rootTemplateDirPath, testOutDirPath, editor);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
throw new types_1.ValidationError((0, i18n_1.t)('error.cannotGeneratePageFile', {
|
|
278
|
+
targetKey: pageObjectParameters.targetKey
|
|
279
|
+
}));
|
|
280
|
+
}
|
|
281
|
+
return editor;
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=fiori-elements-opa-writer.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Editor } from 'mem-fs-editor';
|
|
2
|
+
import type { FFOPAConfig } from './types';
|
|
3
|
+
import type { Logger } from '@sap-ux/logger';
|
|
4
|
+
/**
|
|
5
|
+
* Generates and copies freestyle test files based on configuration.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} basePath - The base directory path.
|
|
8
|
+
* @param {FFOPAConfig} opaConfig - Configuration object.
|
|
9
|
+
* @param {Editor} fs - Optional file system editor instance.
|
|
10
|
+
* @param {Logger} log - Optional logger instance.
|
|
11
|
+
* @returns {Editor} - The modified file system editor.
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateFreestyleOPAFiles(basePath: string, opaConfig: FFOPAConfig, fs?: Editor, log?: Logger): Promise<Editor>;
|
|
14
|
+
//# sourceMappingURL=fiori-freestyle-opa-writer.d.ts.map
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateFreestyleOPAFiles = generateFreestyleOPAFiles;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const mem_fs_1 = require("mem-fs");
|
|
6
|
+
const mem_fs_editor_1 = require("mem-fs-editor");
|
|
7
|
+
const project_access_1 = require("@sap-ux/project-access");
|
|
8
|
+
const i18n_1 = require("./i18n");
|
|
9
|
+
const ui5_application_writer_1 = require("@sap-ux/ui5-application-writer");
|
|
10
|
+
/**
|
|
11
|
+
* Updates tsconfig.json to include paths for unit and integration tests.
|
|
12
|
+
*
|
|
13
|
+
* @param {Editor} fs - The file system editor instance.
|
|
14
|
+
* @param {string} destinationRoot - The root directory where tsconfig.json exists.
|
|
15
|
+
* @param log
|
|
16
|
+
*/
|
|
17
|
+
function writeOPATsconfigJsonUpdates(fs, destinationRoot, log) {
|
|
18
|
+
try {
|
|
19
|
+
const tsconfig = fs.readJSON((0, path_1.join)(destinationRoot, project_access_1.FileName.Tsconfig)) ?? {};
|
|
20
|
+
tsconfig.compilerOptions = tsconfig.compilerOptions || {};
|
|
21
|
+
tsconfig.compilerOptions.paths = tsconfig.compilerOptions.paths || {};
|
|
22
|
+
tsconfig.compilerOptions.paths['unit/*'] = ['./webapp/test/unit/*'];
|
|
23
|
+
tsconfig.compilerOptions.paths['integration/*'] = ['./webapp/test/integration/*'];
|
|
24
|
+
fs.writeJSON((0, path_1.join)(destinationRoot, project_access_1.FileName.Tsconfig), tsconfig);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
log?.error((0, i18n_1.t)('error.errorWritingTsConfig', {
|
|
28
|
+
error: error
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Gets the template UI5 version based on the provided UI5 version.
|
|
34
|
+
*
|
|
35
|
+
* @param ui5Version - The UI5 version.
|
|
36
|
+
* @returns template UI5 version.
|
|
37
|
+
*/
|
|
38
|
+
function getTemplateUi5Version(ui5Version) {
|
|
39
|
+
const templateLtsVersion_1_120 = '1.120.0';
|
|
40
|
+
if (!ui5Version) {
|
|
41
|
+
return templateLtsVersion_1_120;
|
|
42
|
+
}
|
|
43
|
+
return (0, ui5_application_writer_1.compareUI5VersionGte)(ui5Version, templateLtsVersion_1_120) ? templateLtsVersion_1_120 : ui5_application_writer_1.ui5LtsVersion_1_71;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Filters files based on the template UI5 version.
|
|
47
|
+
*
|
|
48
|
+
* @param files - Array of file paths.
|
|
49
|
+
* @param templateUi5Version - The current template Ui5 Version.
|
|
50
|
+
* @returns Files that either are testsuite files or reside in the current template UI5 version folder.
|
|
51
|
+
*/
|
|
52
|
+
function filterByUi5Version(files, templateUi5Version) {
|
|
53
|
+
return files.filter((filePath) => {
|
|
54
|
+
// Always include testsuite files.
|
|
55
|
+
if (filePath.includes('testsuite.qunit')) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
// For all other files, include only those in the current UI5 version directory.
|
|
59
|
+
return filePath.includes(`${path_1.sep}${templateUi5Version}${path_1.sep}`);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Filters files based on the TypeScript setting.
|
|
64
|
+
*
|
|
65
|
+
* @param files - Array of file paths.
|
|
66
|
+
* @param isTypeScript - If true, include .ts files; if false, include .js files.
|
|
67
|
+
* @returns Files filtered based on the file extension.
|
|
68
|
+
*/
|
|
69
|
+
function filterByTypeScript(files, isTypeScript) {
|
|
70
|
+
return files.filter((filePath) => {
|
|
71
|
+
if (filePath.endsWith('.ts')) {
|
|
72
|
+
return isTypeScript;
|
|
73
|
+
}
|
|
74
|
+
if (filePath.endsWith('.js')) {
|
|
75
|
+
return !isTypeScript;
|
|
76
|
+
}
|
|
77
|
+
// Keep all .html file types
|
|
78
|
+
return true;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Determines the destination file path based on the provided file path.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} filePath - The original file path.
|
|
85
|
+
* @param {string} freestyleTemplateDir - The directory file path to be removed from the path.
|
|
86
|
+
* @param {string} commonTemplateDir - The directory file to be removed for common templates path.
|
|
87
|
+
* @param {string} templateUi5Version - The UI5 version to be replaced in the path.
|
|
88
|
+
* @returns {string} - The transformed destination file path.
|
|
89
|
+
*/
|
|
90
|
+
function getDestFilePath(filePath, freestyleTemplateDir, commonTemplateDir, templateUi5Version) {
|
|
91
|
+
if (filePath.includes(freestyleTemplateDir)) {
|
|
92
|
+
return filePath.replace(freestyleTemplateDir, '').replace(`${path_1.sep}${templateUi5Version}${path_1.sep}`, path_1.sep);
|
|
93
|
+
}
|
|
94
|
+
else if (filePath.includes(commonTemplateDir)) {
|
|
95
|
+
return filePath.replace(commonTemplateDir, '');
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
return filePath;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Generates and copies freestyle test files based on configuration.
|
|
103
|
+
*
|
|
104
|
+
* @param {string} basePath - The base directory path.
|
|
105
|
+
* @param {FFOPAConfig} opaConfig - Configuration object.
|
|
106
|
+
* @param {Editor} fs - Optional file system editor instance.
|
|
107
|
+
* @param {Logger} log - Optional logger instance.
|
|
108
|
+
* @returns {Editor} - The modified file system editor.
|
|
109
|
+
*/
|
|
110
|
+
async function generateFreestyleOPAFiles(basePath, opaConfig, fs, log) {
|
|
111
|
+
const fsEditor = fs ?? (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
|
|
112
|
+
const { enableTypeScript, ui5Version, viewName, appId } = opaConfig;
|
|
113
|
+
const freestyleTemplateDir = (0, path_1.join)(__dirname, '../templates/freestyle/webapp/test');
|
|
114
|
+
const commonTemplateDir = (0, path_1.join)(__dirname, '../templates/common');
|
|
115
|
+
const testOutDir = (0, path_1.join)(basePath, 'webapp/test');
|
|
116
|
+
const templateUi5Version = getTemplateUi5Version(ui5Version);
|
|
117
|
+
const appIdWithSlash = appId.replace(/[.]/g, '/'); // Replace all dots with slashes
|
|
118
|
+
const navigationIntent = appId.replace(/[./\\\-\s]/g, ''); // Remove all dots, slashes, dashes, and spaces
|
|
119
|
+
const templateFiles = await (0, project_access_1.getFilePaths)(freestyleTemplateDir);
|
|
120
|
+
const isTypeScript = Boolean(enableTypeScript);
|
|
121
|
+
const templateFilteredFiles = filterByUi5Version(templateFiles, templateUi5Version);
|
|
122
|
+
const filteredFiles = filterByTypeScript(templateFilteredFiles, isTypeScript);
|
|
123
|
+
// copy common templates
|
|
124
|
+
const commonFiles = await (0, project_access_1.getFilePaths)(commonTemplateDir);
|
|
125
|
+
const filteredCommonFiles = commonFiles.filter((filePath) => filePath.endsWith('.html'));
|
|
126
|
+
filteredFiles.push(...filteredCommonFiles);
|
|
127
|
+
const config = {
|
|
128
|
+
...opaConfig,
|
|
129
|
+
viewNamePage: `${viewName}Page`,
|
|
130
|
+
appIdWithSlash,
|
|
131
|
+
navigationIntent,
|
|
132
|
+
ui5Theme: opaConfig.ui5Theme ?? ''
|
|
133
|
+
};
|
|
134
|
+
// Rename files:
|
|
135
|
+
// - viewName.js files are renamed to include the view name in their file path
|
|
136
|
+
// - viewName.ts files are renamed with the view name appended with 'Page'
|
|
137
|
+
const renameMap = {
|
|
138
|
+
[(0, path_1.join)('/integration/pages/viewName.js')]: (0, path_1.join)(`integration/pages/${viewName}.js`),
|
|
139
|
+
[(0, path_1.join)('/integration/pages/viewName.ts')]: (0, path_1.join)(`integration/pages/${viewName}Page.ts`),
|
|
140
|
+
[(0, path_1.join)('/unit/controller/viewName.controller.js')]: (0, path_1.join)(`unit/controller/${viewName}.controller.js`),
|
|
141
|
+
[(0, path_1.join)('/unit/controller/viewName.controller.ts')]: (0, path_1.join)(`unit/controller/${viewName}Page.controller.ts`)
|
|
142
|
+
};
|
|
143
|
+
// copy templates
|
|
144
|
+
let freestyleTestTemplatesCopied = false;
|
|
145
|
+
try {
|
|
146
|
+
filteredFiles.forEach((filePath) => {
|
|
147
|
+
// remove template UI5 version from the path
|
|
148
|
+
const destFilePath = getDestFilePath(filePath, freestyleTemplateDir, commonTemplateDir, templateUi5Version);
|
|
149
|
+
const destinationFilePath = (0, path_1.join)(testOutDir, renameMap?.[destFilePath] ?? destFilePath);
|
|
150
|
+
fsEditor.copyTpl(filePath, destinationFilePath, config, undefined, {
|
|
151
|
+
globOptions: { dot: true }
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
freestyleTestTemplatesCopied = true;
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
log?.error((0, i18n_1.t)('error.errorCopyingFreestyleTestTemplates', {
|
|
158
|
+
error: error
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
if (freestyleTestTemplatesCopied && isTypeScript) {
|
|
162
|
+
writeOPATsconfigJsonUpdates(fsEditor, basePath, log);
|
|
163
|
+
}
|
|
164
|
+
return fsEditor;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=fiori-freestyle-opa-writer.js.map
|
package/dist/i18n.js
CHANGED
|
@@ -3,7 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.initI18n = initI18n;
|
|
7
|
+
exports.t = t;
|
|
7
8
|
const i18next_1 = __importDefault(require("i18next"));
|
|
8
9
|
const ui5_test_writer_i18n_json_1 = __importDefault(require("./translations/ui5-test-writer.i18n.json"));
|
|
9
10
|
const NS = 'ui5-test-writer';
|
|
@@ -23,7 +24,6 @@ async function initI18n() {
|
|
|
23
24
|
ns: [NS]
|
|
24
25
|
});
|
|
25
26
|
}
|
|
26
|
-
exports.initI18n = initI18n;
|
|
27
27
|
/**
|
|
28
28
|
* Helper function facading the call to i18next.
|
|
29
29
|
*
|
|
@@ -34,7 +34,6 @@ exports.initI18n = initI18n;
|
|
|
34
34
|
function t(key, options) {
|
|
35
35
|
return i18next_1.default.t(key, options);
|
|
36
36
|
}
|
|
37
|
-
exports.t = t;
|
|
38
37
|
initI18n().catch(() => {
|
|
39
38
|
// Ignore any errors since the write will still work
|
|
40
39
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,34 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Generate OPA test files for a Fiori elements for OData V4 application.
|
|
4
|
-
* Note: this can potentially overwrite existing files in the webapp/test folder.
|
|
5
|
-
*
|
|
6
|
-
* @param basePath - the absolute target path where the application will be generated
|
|
7
|
-
* @param opaConfig - parameters for the generation
|
|
8
|
-
* @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used
|
|
9
|
-
* @param opaConfig.htmlTarget - the name of the html that will be used in OPA journey file. If not specified, 'index.html' will be used
|
|
10
|
-
* @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id
|
|
11
|
-
* @param fs - an optional reference to a mem-fs editor
|
|
12
|
-
* @returns Reference to a mem-fs-editor
|
|
13
|
-
*/
|
|
14
|
-
export declare function generateOPAFiles(basePath: string, opaConfig: {
|
|
15
|
-
scriptName?: string;
|
|
16
|
-
appID?: string;
|
|
17
|
-
htmlTarget?: string;
|
|
18
|
-
}, fs?: Editor): Editor;
|
|
19
|
-
/**
|
|
20
|
-
* Generate a page object file for a Fiori elements for OData V4 application.
|
|
21
|
-
* Note: this doesn't modify other existing files in the webapp/test folder.
|
|
22
|
-
*
|
|
23
|
-
* @param basePath - the absolute target path where the application will be generated
|
|
24
|
-
* @param pageObjectParameters - parameters for the page
|
|
25
|
-
* @param pageObjectParameters.targetKey - the key of the target in the manifest file corresponding to the page
|
|
26
|
-
* @param pageObjectParameters.appID - the appID. If not specified, will be read from the manifest in sap.app/id
|
|
27
|
-
* @param fs - an optional reference to a mem-fs editor
|
|
28
|
-
* @returns Reference to a mem-fs-editor
|
|
29
|
-
*/
|
|
30
|
-
export declare function generatePageObjectFile(basePath: string, pageObjectParameters: {
|
|
31
|
-
targetKey: string;
|
|
32
|
-
appID?: string;
|
|
33
|
-
}, fs?: Editor): Editor;
|
|
1
|
+
export { generateOPAFiles } from './fiori-elements-opa-writer';
|
|
2
|
+
export { generateFreestyleOPAFiles } from './fiori-freestyle-opa-writer';
|
|
34
3
|
//# sourceMappingURL=index.d.ts.map
|