From 445fdda09b10856b636a3913c9c0e85f4a8db32a Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 7 Feb 2025 09:28:42 +0000 Subject: [PATCH 01/42] adding simple handlebar templates --- .../templates/simple/model.json | 164 ++++++++++++++++++ .../1.124.0/integration/AllJourneys.js.tmpl | 13 ++ .../integration/NavigationJourney.js.tmpl | 23 +++ .../integration/NavigationJourney.ts.tmpl | 34 ++++ .../integration/arrangements/Startup.js.tmpl | 25 +++ .../integration/opaTests.qunit.html.tmpl | 29 ++++ .../integration/opaTests.qunit.js.tmpl | 7 + .../integration/opaTests.qunit.ts.tmpl | 7 + .../1.124.0/integration/pages/App.js.tmpl | 28 +++ .../1.124.0/integration/pages/AppPage.ts.tmpl | 22 +++ .../integration/pages/viewName.js.tmpl | 28 +++ .../integration/pages/viewName.ts.tmpl | 23 +++ .../test/1.124.0/testsuite.qunit.html.tmpl | 11 ++ .../test/1.124.0/testsuite.qunit.js.tmpl | 15 ++ .../test/1.124.0/testsuite.qunit.ts.tmpl | 14 ++ .../webapp/test/1.124.0/unit/AllTests.js.tmpl | 5 + .../controller/viewName.controller.js.tmpl | 16 ++ .../controller/viewName.controller.ts.tmpl | 10 ++ .../1.124.0/unit/unitTests.qunit.html.tmpl | 28 +++ .../test/1.124.0/unit/unitTests.qunit.js.tmpl | 10 ++ .../test/1.124.0/unit/unitTests.qunit.ts.tmpl | 10 ++ .../webapp/test/1.71.0/flpSandbox.js.tmpl | 102 +++++++++++ .../webapp/test/1.71.0/initFlpSandbox.js.tmpl | 13 ++ .../1.71.0/integration/AllJourneys.js.tmpl | 13 ++ .../integration/NavigationJourney.js.tmpl | 23 +++ .../integration/NavigationJourney.ts.tmpl | 34 ++++ .../integration/arrangements/Startup.js.tmpl | 25 +++ .../integration/opaTests.qunit.html.tmpl | 29 ++++ .../1.71.0/integration/opaTests.qunit.js.tmpl | 7 + .../1.71.0/integration/opaTests.qunit.ts.tmpl | 10 ++ .../test/1.71.0/integration/pages/App.js.tmpl | 28 +++ .../1.71.0/integration/pages/AppPage.ts.tmpl | 22 +++ .../1.71.0/integration/pages/viewName.js.tmpl | 28 +++ .../1.71.0/integration/pages/viewName.ts.tmpl | 23 +++ .../test/1.71.0/testsuite.qunit.html.tmpl | 11 ++ .../test/1.71.0/testsuite.qunit.js.tmpl | 15 ++ .../test/1.71.0/testsuite.qunit.ts.tmpl | 14 ++ .../webapp/test/1.71.0/unit/AllTests.js.tmpl | 5 + .../controller/viewName.controller.js.tmpl | 16 ++ .../controller/viewName.controller.ts.tmpl | 10 ++ .../1.71.0/unit/unitTests.qunit.html.tmpl | 27 +++ .../test/1.71.0/unit/unitTests.qunit.js.tmpl | 12 ++ .../test/1.71.0/unit/unitTests.qunit.ts.tmpl | 10 ++ 43 files changed, 999 insertions(+) create mode 100644 packages/ui5-test-writer/templates/simple/model.json create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/AllJourneys.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/arrangements/Startup.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.html.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/App.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/AppPage.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.html.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/AllTests.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.html.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/flpSandbox.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/initFlpSandbox.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/AllJourneys.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/arrangements/Startup.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.html.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/App.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/AppPage.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.html.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/AllTests.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.ts.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.html.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.js.tmpl create mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.ts.tmpl diff --git a/packages/ui5-test-writer/templates/simple/model.json b/packages/ui5-test-writer/templates/simple/model.json new file mode 100644 index 0000000000..0231282c2f --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/model.json @@ -0,0 +1,164 @@ +{ + "neoapp": { + "welcomeFile": "/webapp/test/flpSandbox.html", + "sendWelcomeFileRedirect": true + }, + "datasource": { + "type": "odata", + "url": "" + }, + "simple": { + "environment": { + "internal": "false", + "resourcePath": "" + }, + "parameters": { + "ManifestVersion": { + "value": "" + }, + "ui5Version": { + "value": "" + }, + "ProjectName": { + "value": "" + }, + "AppId": { + "value": "" + }, + "ViewName": { + "value": "" + }, + "ViewNamePage": { + "value": "" + }, + "UI5Theme": { + "value": "" + }, + "sapUiBootstrapSrcUrl": { + "value": "" + }, + "AppIdWithSlash": { + "value": "" + }, + "ApplicationNamespace": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "Namespace" + }, + "wizard": { + "control": "TextField", + "regExp": "^[a-z][a-z 0-9]*(?:\\.[a-z][a-z 0-9]*)*$", + "required": true, + "title": "Namespace", + "regExpErrorMsg": "A namespace must not start with a digit. After the first character you may use any alphanumeric character or number separated by dots. Two successive dots are also forbidden. A namespace must not end with a dot." + } + }, + "ApplicationTitle": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "sap.app.title" + }, + "wizard": { + "control": "TextField", + "required": true, + "title": "Title", + "regExp": "^[\\w][\\w\\.\\-\\ ]*$" + } + }, + "ApplicationDescription": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "sap.app.description" + }, + "wizard": { + "control": "TextField", + "required": false, + "title": "Description" + } + }, + "FioriID": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "sap.fiori.registrationIds" + }, + "wizard": { + "control": "TextField", + "required": false, + "title": "SAP Fiori ID", + "internalOnly": true + } + }, + "ApplicationComponentHierarchy": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "sap.app.ach" + }, + "wizard": { + "control": "TextField", + "required": false, + "title": "Application Component Hierarchy", + "internalOnly": true + } + }, + "FLP": { + "type": "Entity", + "multiplicity": "many", + "isRoot": true, + "binding": [ + { + "name": "SAP Fiori Launchpad Component (optimized for SAP Fiori Launchpad registration)", + "value": true + }, + { + "name": "Standalone App (optimized for individual deployment)", + "value": false + } + ], + "value": "", + "wizard": { + "control": "ComboBox", + "required": true, + "title": "App Type", + "tooltip": "Choose if your app should run in SAP Fiori Launchpad or standalone" + } + }, + "DefineReplacement": { + "type": "string", + "value": "" + } + }, + "forms": [ + { + "type": "appDescriptorGenericStep", + "groups": [ + { + "parameters": [ + "@simple.parameters.ApplicationTitle", + "@simple.parameters.ApplicationNamespace", + "@simple.parameters.ApplicationDescription", + "@simple.parameters.ApplicationComponentHierarchy", + "@simple.parameters.FioriID" + ] + } + ] + }, + { + "groups": [ + { + "title": "Application Scenario", + "parameters": ["@simple.parameters.FLP"] + }, + { + "title": "Data Binding", + "parameters": [] + } + ] + } + ] + } +} diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/AllJourneys.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/AllJourneys.js.tmpl new file mode 100644 index 0000000000..446661b69d --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/AllJourneys.js.tmpl @@ -0,0 +1,13 @@ +sap.ui.define([ + "sap/ui/test/Opa5", + "./arrangements/Startup", + "./NavigationJourney" +], function (Opa5, Startup) { + "use strict"; + + Opa5.extendConfig({ + arrangements: new Startup(), + viewNamespace: "{{simple.parameters.AppId.value}}.view.", + autoWait: true + }); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.js.tmpl new file mode 100644 index 0000000000..7131fc1b29 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.js.tmpl @@ -0,0 +1,23 @@ +/*global QUnit*/ + +sap.ui.define([ + "sap/ui/test/opaQunit", + "./pages/App", + "./pages/{{simple.parameters.ViewName.value}}" +], function (opaTest) { + "use strict"; + + QUnit.module("Navigation Journey"); + + opaTest("Should see the initial page of the app", function (Given, When, Then) { + // Arrangements + Given.iStartMyApp(); + + // Assertions + Then.onTheAppPage.iShouldSeeTheApp(); + Then.onTheViewPage.iShouldSeeThePageView(); + + //Cleanup + Then.iTeardownMyApp(); + }); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.ts.tmpl new file mode 100644 index 0000000000..ab61f59a43 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.ts.tmpl @@ -0,0 +1,34 @@ +/*global QUnit*/ +import opaTest from "sap/ui/test/opaQunit"; +import AppPage from "./pages/AppPage"; +import ViewPage from "./pages/{{simple.parameters.ViewName.value}}Page"; + +import Opa5 from "sap/ui/test/Opa5"; + +QUnit.module("Navigation Journey"); + +const onTheAppPage = new AppPage(); +const onTheViewPage = new ViewPage(); +Opa5.extendConfig({ + viewNamespace: "{{simple.parameters.AppId.value}}.view.", + autoWait: true +}); + +opaTest("Should see the initial page of the app", function () { + // Arrangements + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iStartMyUIComponent({ + componentConfig: { + name: "{{simple.parameters.AppId.value}}" + } + }); + + // Assertions + onTheAppPage.iShouldSeeTheApp(); + onTheViewPage.iShouldSeeThePageView(); + + + // Cleanup + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iTeardownMyApp(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/arrangements/Startup.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/arrangements/Startup.js.tmpl new file mode 100644 index 0000000000..6c764d9335 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/arrangements/Startup.js.tmpl @@ -0,0 +1,25 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + + return Opa5.extend("integration.arrangements.Startup", { + + iStartMyApp: function (oOptionsParameter) { + var oOptions = oOptionsParameter || {}; + + // start the app with a minimal delay to make tests fast but still async to discover basic timing issues + oOptions.delay = oOptions.delay || 50; + + // start the app UI component + this.iStartMyUIComponent({ + componentConfig: { + name: "{{simple.parameters.AppId.value}}", + async: true + }, + hash: oOptions.hash, + autoWait: oOptions.autoWait + }); + } + }); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.html.tmpl new file mode 100644 index 0000000000..251e5a63e3 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.html.tmpl @@ -0,0 +1,29 @@ + + + + + Integration tests for Basic Template + + + + + + + + +
+
+ + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.js.tmpl new file mode 100644 index 0000000000..752127326e --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.js.tmpl @@ -0,0 +1,7 @@ +/* global QUnit */ + +sap.ui.require(["{{formatNamespace simple.parameters.AppId.value}}/test/integration/AllJourneys" +], function () { + QUnit.config.autostart = false; + QUnit.start(); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.ts.tmpl new file mode 100644 index 0000000000..851583d95f --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.ts.tmpl @@ -0,0 +1,7 @@ +/* global QUnit */ + +sap.ui.require(["integration/NavigationJourney" +], function () { + QUnit.config.autostart = false; + QUnit.start(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/App.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/App.js.tmpl new file mode 100644 index 0000000000..db276e3fd4 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/App.js.tmpl @@ -0,0 +1,28 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + var sViewName = "App"; + + Opa5.createPageObjects({ + onTheAppPage: { + + actions: {}, + + assertions: { + + iShouldSeeTheApp: function () { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/AppPage.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/AppPage.ts.tmpl new file mode 100644 index 0000000000..8cb42d2a57 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/AppPage.ts.tmpl @@ -0,0 +1,22 @@ +import Opa5 from "sap/ui/test/Opa5"; + +const sViewName = "App"; + +export default class AppPage extends Opa5 { + // Actions + + + // Assertions + iShouldSeeTheApp() { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + +} + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.js.tmpl new file mode 100644 index 0000000000..5ec0839dc2 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.js.tmpl @@ -0,0 +1,28 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + var sViewName = "{{simple.parameters.ViewName.value}}"; + + Opa5.createPageObjects({ + onTheViewPage: { + + actions: {}, + + assertions: { + + iShouldSeeThePageView: function () { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.ts.tmpl new file mode 100644 index 0000000000..1767150c80 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.ts.tmpl @@ -0,0 +1,23 @@ +import Opa5 from "sap/ui/test/Opa5"; + +const sViewName = "{{simple.parameters.ViewName.value}}"; + +export default class {{simple.parameters.ViewNamePage.value}} extends Opa5 { + // Actions + + + // Assertions + iShouldSeeThePageView() { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + +} + + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.html.tmpl new file mode 100644 index 0000000000..17fec6f239 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.html.tmpl @@ -0,0 +1,11 @@ + + + + + QUnit test suite for {{simple.parameters.AppId.value}} + + + + + + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.js.tmpl new file mode 100644 index 0000000000..3df60a28c1 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.js.tmpl @@ -0,0 +1,15 @@ +/* global window, parent, location */ + +// eslint-disable-next-line fiori-custom/sap-no-global-define +window.suite = function() { + "use strict"; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + + oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); + oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); + + return oSuite; +}; \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.ts.tmpl new file mode 100644 index 0000000000..61446459d1 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.ts.tmpl @@ -0,0 +1,14 @@ +/* global window, parent, location */ + +// eslint-disable-next-line fiori-custom/sap-no-global-define,@typescript-eslint/ban-ts-comment +// @ts-nocheck +window.suite = function() { + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + + oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); + oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); + + return oSuite; +}; diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/AllTests.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/AllTests.js.tmpl new file mode 100644 index 0000000000..fe65f492c6 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/AllTests.js.tmpl @@ -0,0 +1,5 @@ +sap.ui.define([ + "{{simple.parameters.AppIdWithSlash.value}}/test/unit/controller/{{simple.parameters.ViewName.value}}.controller" +], function () { + "use strict"; +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.js.tmpl new file mode 100644 index 0000000000..cbc446b9fc --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.js.tmpl @@ -0,0 +1,16 @@ +/*global QUnit*/ + +sap.ui.define([ + "{{simple.parameters.AppIdWithSlash.value}}/controller/{{simple.parameters.ViewName.value}}.controller" +], function (Controller) { + "use strict"; + + QUnit.module("{{simple.parameters.ViewName.value}} Controller"); + + QUnit.test("I should test the {{simple.parameters.ViewName.value}} controller", function (assert) { + var oAppController = new Controller(); + oAppController.onInit(); + assert.ok(oAppController); + }); + +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.ts.tmpl new file mode 100644 index 0000000000..ebe71640c9 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.ts.tmpl @@ -0,0 +1,10 @@ +/*global QUnit*/ +import Controller from "{{simple.parameters.AppIdWithSlash.value}}/controller/{{simple.parameters.ViewName.value}}.controller"; + +QUnit.module("{{simple.parameters.ViewName.value}} Controller"); + +QUnit.test("I should test the {{simple.parameters.ViewName.value}} controller", function (assert: Assert) { + const oAppController = new Controller("{{simple.parameters.ViewName.value}}"); + oAppController.onInit(); + assert.ok(oAppController); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.html.tmpl new file mode 100644 index 0000000000..38a547b189 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.html.tmpl @@ -0,0 +1,28 @@ + + + + + Unit tests for {{simple.parameters.AppId.value}} + + + + + + + + + + +
+
+ + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.js.tmpl new file mode 100644 index 0000000000..9466c4093c --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.js.tmpl @@ -0,0 +1,10 @@ +/* global QUnit */ +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +sap.ui.require([ + "{{simple.parameters.AppIdWithSlash.value}}/test/unit/AllTests" +], function (Controller) { + "use strict"; + QUnit.start(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.ts.tmpl new file mode 100644 index 0000000000..b25f2a4fc0 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.ts.tmpl @@ -0,0 +1,10 @@ +/* @sapUiRequire */ +QUnit.config.autostart = false; + +// import all your QUnit tests here +void Promise.all([ + import("sap/ui/core/Core"), // required to wait until Core has booted to start the QUnit tests + import("unit/controller/{{simple.parameters.ViewName.value}}Page.controller"), +]).then(([{default: Core}]) => Core.ready()).then(() => { + QUnit.start(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/flpSandbox.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/flpSandbox.js.tmpl new file mode 100644 index 0000000000..1f3c835e1b --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/flpSandbox.js.tmpl @@ -0,0 +1,102 @@ +sap.ui.define([ + "sap/base/util/ObjectPath", + "sap/ushell/services/Container" +], function (ObjectPath) { + "use strict"; + + // define ushell config + ObjectPath.set(["sap-ushell-config"], { + defaultRenderer: "fiori2", + bootstrapPlugins: { + "RuntimeAuthoringPlugin": { + component: "sap.ushell.plugins.rta", + config: { + validateAppVersion: false + } + }, + "PersonalizePlugin": { + component: "sap.ushell.plugins.rta-personalize", + config: { + validateAppVersion: false + } + } + }, + renderers: { + fiori2: { + componentData: { + config: { + enableSearch: false, + rootIntent: "Shell-home" + } + } + } + }, + services: { + "LaunchPage": { + "adapter": { + "config": { + "groups": [{ + "tiles": [{ + "tileType": "sap.ushell.ui.tile.StaticTile", + "properties": { + {{#if simple.parameters.ApplicationTitle.value}} + "title": "{{simple.parameters.ApplicationTitle.value}}",{{/if}} + "targetURL": "#{{simple.parameters.NavigationIntent}}-display" + } + }] + }] + } + } + }, + "ClientSideTargetResolution": { + "adapter": { + "config": { + "inbounds": { + "{{simple.parameters.NavigationIntent}}-display": { + "semanticObject": "{{simple.parameters.NavigationIntent}}", + "action": "display", + {{#if simple.parameters.ApplicationDescription.value}} + "description": "{{simple.parameters.ApplicationDescription.value}}",{{/if}}{{#if simple.parameters.ApplicationTitle.value}} + "title": "{{simple.parameters.ApplicationTitle.value}}",{{/if}} + "signature": { + "parameters": {} + }, + "resolutionResult": { + "applicationType": "SAPUI5", + "additionalInformation": "SAPUI5.Component={{simple.parameters.AppId.value}}", + "url": sap.ui.require.toUrl("{{formatNamespace simple.parameters.AppId.value}}") + } + } + } + } + } + }, + NavTargetResolution: { + config: { + "enableClientSideTargetResolution": true + } + } + } + }); + + var oFlpSandbox = { + init: function () { + /** + * Initializes the FLP sandbox + * @returns {Promise} a promise that is resolved when the sandbox bootstrap has finshed + */ + + // sandbox is a singleton, so we can start it only once + if (!this._oBootstrapFinished) { + this._oBootstrapFinished = sap.ushell.bootstrap("local"); + this._oBootstrapFinished.then(function () { + sap.ushell.Container.createRenderer().placeAt("content"); + }); + } + + return this._oBootstrapFinished; + } + }; + + return oFlpSandbox; +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/initFlpSandbox.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/initFlpSandbox.js.tmpl new file mode 100644 index 0000000000..7a8f6bcfba --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/initFlpSandbox.js.tmpl @@ -0,0 +1,13 @@ +sap.ui.define([ + "./flpSandbox", + "sap/ui/fl/FakeLrepConnectorLocalStorage", + "sap/m/MessageBox" +], function (flpSandbox, FakeLrepConnectorLocalStorage, MessageBox) { + "use strict"; + + flpSandbox.init().then(function () { + FakeLrepConnectorLocalStorage.enableFakeConnector(); + }, function (oError) { + MessageBox.error(oError.message); + }); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/AllJourneys.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/AllJourneys.js.tmpl new file mode 100644 index 0000000000..446661b69d --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/AllJourneys.js.tmpl @@ -0,0 +1,13 @@ +sap.ui.define([ + "sap/ui/test/Opa5", + "./arrangements/Startup", + "./NavigationJourney" +], function (Opa5, Startup) { + "use strict"; + + Opa5.extendConfig({ + arrangements: new Startup(), + viewNamespace: "{{simple.parameters.AppId.value}}.view.", + autoWait: true + }); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.js.tmpl new file mode 100644 index 0000000000..7131fc1b29 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.js.tmpl @@ -0,0 +1,23 @@ +/*global QUnit*/ + +sap.ui.define([ + "sap/ui/test/opaQunit", + "./pages/App", + "./pages/{{simple.parameters.ViewName.value}}" +], function (opaTest) { + "use strict"; + + QUnit.module("Navigation Journey"); + + opaTest("Should see the initial page of the app", function (Given, When, Then) { + // Arrangements + Given.iStartMyApp(); + + // Assertions + Then.onTheAppPage.iShouldSeeTheApp(); + Then.onTheViewPage.iShouldSeeThePageView(); + + //Cleanup + Then.iTeardownMyApp(); + }); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.ts.tmpl new file mode 100644 index 0000000000..ab61f59a43 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.ts.tmpl @@ -0,0 +1,34 @@ +/*global QUnit*/ +import opaTest from "sap/ui/test/opaQunit"; +import AppPage from "./pages/AppPage"; +import ViewPage from "./pages/{{simple.parameters.ViewName.value}}Page"; + +import Opa5 from "sap/ui/test/Opa5"; + +QUnit.module("Navigation Journey"); + +const onTheAppPage = new AppPage(); +const onTheViewPage = new ViewPage(); +Opa5.extendConfig({ + viewNamespace: "{{simple.parameters.AppId.value}}.view.", + autoWait: true +}); + +opaTest("Should see the initial page of the app", function () { + // Arrangements + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iStartMyUIComponent({ + componentConfig: { + name: "{{simple.parameters.AppId.value}}" + } + }); + + // Assertions + onTheAppPage.iShouldSeeTheApp(); + onTheViewPage.iShouldSeeThePageView(); + + + // Cleanup + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iTeardownMyApp(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/arrangements/Startup.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/arrangements/Startup.js.tmpl new file mode 100644 index 0000000000..6c764d9335 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/arrangements/Startup.js.tmpl @@ -0,0 +1,25 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + + return Opa5.extend("integration.arrangements.Startup", { + + iStartMyApp: function (oOptionsParameter) { + var oOptions = oOptionsParameter || {}; + + // start the app with a minimal delay to make tests fast but still async to discover basic timing issues + oOptions.delay = oOptions.delay || 50; + + // start the app UI component + this.iStartMyUIComponent({ + componentConfig: { + name: "{{simple.parameters.AppId.value}}", + async: true + }, + hash: oOptions.hash, + autoWait: oOptions.autoWait + }); + } + }); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.html.tmpl new file mode 100644 index 0000000000..4e2b65aa9e --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.html.tmpl @@ -0,0 +1,29 @@ + + + + + Integration tests for Basic Template + + + + + + + +
+
+ + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.js.tmpl new file mode 100644 index 0000000000..752127326e --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.js.tmpl @@ -0,0 +1,7 @@ +/* global QUnit */ + +sap.ui.require(["{{formatNamespace simple.parameters.AppId.value}}/test/integration/AllJourneys" +], function () { + QUnit.config.autostart = false; + QUnit.start(); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.ts.tmpl new file mode 100644 index 0000000000..024c1d9041 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.ts.tmpl @@ -0,0 +1,10 @@ +/* global QUnit */ +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +// import all your OPA journeys here +void Promise.all([ + import("integration/NavigationJourney") +]).then(() => { + QUnit.start(); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/App.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/App.js.tmpl new file mode 100644 index 0000000000..db276e3fd4 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/App.js.tmpl @@ -0,0 +1,28 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + var sViewName = "App"; + + Opa5.createPageObjects({ + onTheAppPage: { + + actions: {}, + + assertions: { + + iShouldSeeTheApp: function () { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/AppPage.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/AppPage.ts.tmpl new file mode 100644 index 0000000000..8cb42d2a57 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/AppPage.ts.tmpl @@ -0,0 +1,22 @@ +import Opa5 from "sap/ui/test/Opa5"; + +const sViewName = "App"; + +export default class AppPage extends Opa5 { + // Actions + + + // Assertions + iShouldSeeTheApp() { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + +} + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.js.tmpl new file mode 100644 index 0000000000..5ec0839dc2 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.js.tmpl @@ -0,0 +1,28 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + var sViewName = "{{simple.parameters.ViewName.value}}"; + + Opa5.createPageObjects({ + onTheViewPage: { + + actions: {}, + + assertions: { + + iShouldSeeThePageView: function () { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.ts.tmpl new file mode 100644 index 0000000000..1767150c80 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.ts.tmpl @@ -0,0 +1,23 @@ +import Opa5 from "sap/ui/test/Opa5"; + +const sViewName = "{{simple.parameters.ViewName.value}}"; + +export default class {{simple.parameters.ViewNamePage.value}} extends Opa5 { + // Actions + + + // Assertions + iShouldSeeThePageView() { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + +} + + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.html.tmpl new file mode 100644 index 0000000000..17fec6f239 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.html.tmpl @@ -0,0 +1,11 @@ + + + + + QUnit test suite for {{simple.parameters.AppId.value}} + + + + + + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.js.tmpl new file mode 100644 index 0000000000..3df60a28c1 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.js.tmpl @@ -0,0 +1,15 @@ +/* global window, parent, location */ + +// eslint-disable-next-line fiori-custom/sap-no-global-define +window.suite = function() { + "use strict"; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + + oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); + oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); + + return oSuite; +}; \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.ts.tmpl new file mode 100644 index 0000000000..61446459d1 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.ts.tmpl @@ -0,0 +1,14 @@ +/* global window, parent, location */ + +// eslint-disable-next-line fiori-custom/sap-no-global-define,@typescript-eslint/ban-ts-comment +// @ts-nocheck +window.suite = function() { + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + + oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); + oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); + + return oSuite; +}; diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/AllTests.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/AllTests.js.tmpl new file mode 100644 index 0000000000..fe65f492c6 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/AllTests.js.tmpl @@ -0,0 +1,5 @@ +sap.ui.define([ + "{{simple.parameters.AppIdWithSlash.value}}/test/unit/controller/{{simple.parameters.ViewName.value}}.controller" +], function () { + "use strict"; +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.js.tmpl new file mode 100644 index 0000000000..cbc446b9fc --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.js.tmpl @@ -0,0 +1,16 @@ +/*global QUnit*/ + +sap.ui.define([ + "{{simple.parameters.AppIdWithSlash.value}}/controller/{{simple.parameters.ViewName.value}}.controller" +], function (Controller) { + "use strict"; + + QUnit.module("{{simple.parameters.ViewName.value}} Controller"); + + QUnit.test("I should test the {{simple.parameters.ViewName.value}} controller", function (assert) { + var oAppController = new Controller(); + oAppController.onInit(); + assert.ok(oAppController); + }); + +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.ts.tmpl new file mode 100644 index 0000000000..ebe71640c9 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.ts.tmpl @@ -0,0 +1,10 @@ +/*global QUnit*/ +import Controller from "{{simple.parameters.AppIdWithSlash.value}}/controller/{{simple.parameters.ViewName.value}}.controller"; + +QUnit.module("{{simple.parameters.ViewName.value}} Controller"); + +QUnit.test("I should test the {{simple.parameters.ViewName.value}} controller", function (assert: Assert) { + const oAppController = new Controller("{{simple.parameters.ViewName.value}}"); + oAppController.onInit(); + assert.ok(oAppController); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.html.tmpl new file mode 100644 index 0000000000..f3f6783bda --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.html.tmpl @@ -0,0 +1,27 @@ + + + + + Unit tests for {{simple.parameters.AppId.value}} + + + + + + + + + +
+
+ + diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.js.tmpl new file mode 100644 index 0000000000..329eb6912d --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.js.tmpl @@ -0,0 +1,12 @@ +/* global QUnit */ +QUnit.config.autostart = false; + +sap.ui.getCore().attachInit(function () { + "use strict"; + + sap.ui.require([ + "{{simple.parameters.AppIdWithSlash.value}}/test/unit/AllTests" + ], function () { + QUnit.start(); + }); +}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.ts.tmpl new file mode 100644 index 0000000000..f27303b333 --- /dev/null +++ b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.ts.tmpl @@ -0,0 +1,10 @@ +/* global QUnit */ +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +// import all your QUnit tests here +void Promise.all([ + import("unit/controller/{{simple.parameters.ViewName.value}}Page.controller") +]).then(() => { + QUnit.start(); +}); \ No newline at end of file From 08b3623607601700bb41791f2f56eca011817fa2 Mon Sep 17 00:00:00 2001 From: I743583 Date: Tue, 11 Feb 2025 08:59:51 +0000 Subject: [PATCH 02/42] progress --- packages/fiori-freestyle-writer/package.json | 1 + packages/fiori-freestyle-writer/src/index.ts | 33 ++++ packages/fiori-freestyle-writer/src/types.ts | 10 ++ packages/fiori-freestyle-writer/tsconfig.json | 3 + packages/ui5-test-writer/src/index.ts | 146 +++++++++++++++- packages/ui5-test-writer/src/types.ts | 16 ++ .../templates/simple/model.json | 164 ------------------ .../1.124.0/integration/AllJourneys.js.tmpl | 13 -- .../integration/NavigationJourney.js.tmpl | 23 --- .../integration/NavigationJourney.ts.tmpl | 34 ---- .../integration/arrangements/Startup.js.tmpl | 25 --- .../integration/opaTests.qunit.html.tmpl | 29 ---- .../integration/opaTests.qunit.js.tmpl | 7 - .../integration/opaTests.qunit.ts.tmpl | 7 - .../1.124.0/integration/pages/App.js.tmpl | 28 --- .../1.124.0/integration/pages/AppPage.ts.tmpl | 22 --- .../integration/pages/viewName.js.tmpl | 28 --- .../integration/pages/viewName.ts.tmpl | 23 --- .../test/1.124.0/testsuite.qunit.html.tmpl | 11 -- .../test/1.124.0/testsuite.qunit.js.tmpl | 15 -- .../test/1.124.0/testsuite.qunit.ts.tmpl | 14 -- .../webapp/test/1.124.0/unit/AllTests.js.tmpl | 5 - .../controller/viewName.controller.js.tmpl | 16 -- .../controller/viewName.controller.ts.tmpl | 10 -- .../1.124.0/unit/unitTests.qunit.html.tmpl | 28 --- .../test/1.124.0/unit/unitTests.qunit.js.tmpl | 10 -- .../test/1.124.0/unit/unitTests.qunit.ts.tmpl | 10 -- .../webapp/test/1.71.0/flpSandbox.js.tmpl | 102 ----------- .../webapp/test/1.71.0/initFlpSandbox.js.tmpl | 13 -- .../1.71.0/integration/AllJourneys.js.tmpl | 13 -- .../integration/NavigationJourney.js.tmpl | 23 --- .../integration/NavigationJourney.ts.tmpl | 34 ---- .../integration/arrangements/Startup.js.tmpl | 25 --- .../integration/opaTests.qunit.html.tmpl | 29 ---- .../1.71.0/integration/opaTests.qunit.js.tmpl | 7 - .../1.71.0/integration/opaTests.qunit.ts.tmpl | 10 -- .../test/1.71.0/integration/pages/App.js.tmpl | 28 --- .../1.71.0/integration/pages/AppPage.ts.tmpl | 22 --- .../1.71.0/integration/pages/viewName.js.tmpl | 28 --- .../1.71.0/integration/pages/viewName.ts.tmpl | 23 --- .../test/1.71.0/testsuite.qunit.html.tmpl | 11 -- .../test/1.71.0/testsuite.qunit.js.tmpl | 15 -- .../test/1.71.0/testsuite.qunit.ts.tmpl | 14 -- .../webapp/test/1.71.0/unit/AllTests.js.tmpl | 5 - .../controller/viewName.controller.js.tmpl | 16 -- .../controller/viewName.controller.ts.tmpl | 10 -- .../1.71.0/unit/unitTests.qunit.html.tmpl | 27 --- .../test/1.71.0/unit/unitTests.qunit.js.tmpl | 12 -- .../test/1.71.0/unit/unitTests.qunit.ts.tmpl | 10 -- pnpm-lock.yaml | 3 + 50 files changed, 210 insertions(+), 1001 deletions(-) delete mode 100644 packages/ui5-test-writer/templates/simple/model.json delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/AllJourneys.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/arrangements/Startup.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.html.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/App.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/AppPage.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.html.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/AllTests.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.html.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/flpSandbox.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/initFlpSandbox.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/AllJourneys.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/arrangements/Startup.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.html.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/App.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/AppPage.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.html.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/AllTests.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.ts.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.html.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.js.tmpl delete mode 100644 packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.ts.tmpl diff --git a/packages/fiori-freestyle-writer/package.json b/packages/fiori-freestyle-writer/package.json index 8e41055011..178a9278eb 100644 --- a/packages/fiori-freestyle-writer/package.json +++ b/packages/fiori-freestyle-writer/package.json @@ -37,6 +37,7 @@ "@sap-ux/ui5-config": "workspace:*", "@sap-ux/fiori-generator-shared": "workspace:*", "@sap-ux/cap-config-writer": "workspace:*", + "@sap-ux/ui5-test-writer": "workspace:*", "ejs": "3.1.10", "i18next": "20.6.1", "lodash": "4.17.21", diff --git a/packages/fiori-freestyle-writer/src/index.ts b/packages/fiori-freestyle-writer/src/index.ts index b87c27c0d4..43bb82fa3b 100644 --- a/packages/fiori-freestyle-writer/src/index.ts +++ b/packages/fiori-freestyle-writer/src/index.ts @@ -13,6 +13,7 @@ import { initI18n } from './i18n'; import { getBootstrapResourceUrls, getPackageScripts } from '@sap-ux/fiori-generator-shared'; import { getTemplateVersionPath, processDestinationPath } from './utils'; import { applyCAPUpdates, type CapProjectSettings } from '@sap-ux/cap-config-writer'; +import { generateFreestyleTestFiles } from '@sap-ux/ui5-test-writer'; /** * Generate a UI5 application based on the specified Fiori Freestyle floorplan template. @@ -167,6 +168,38 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor) fs.write(ui5LocalConfigPath, ui5LocalConfig.toString()); } + + const getApplicationIdWithSlash = (): string => { + let appIdWihSlash; + if (ffApp.appOptions?.typescript=== true) { + appIdWihSlash = `${ffApp.app.namespace?.replace(/\./g, '/').replace(/\/$/, '')}${ + ffApp.app.namespace !== '' ? '/' : '' + }${ffApp.package.name?.replace(/[_-]/g, '')}`; + } else { + appIdWihSlash = `${ffApp.app.namespace?.replace(/\./g, '')}${ffApp.app.namespace !== '' ? '/' : ''}${ + ffApp.package.name + }`; + } + return appIdWihSlash; + } + console.log(); + if (ffApp.appOptions?.addTests) { + generateFreestyleTestFiles( + basePath, + { + appId: ffApp.app.id, + viewName: (ffApp.template.settings as BasicAppSettings).viewName, + ui5Theme: ffApp.ui5?.ui5Theme, + appIdWithSlash: getApplicationIdWithSlash(), + applicationTitle: ffApp.app.title, + //navigationIntent: string, + applicationDescription: ffApp.app.description, + hasData: ffApp.service?.hasData, + }, + fs + ); + } + if (ffApp.service?.capService) { const hasCdsUi5PluginInfo = !!ffApp.service.capService.cdsUi5PluginInfo; const settings: CapProjectSettings = { diff --git a/packages/fiori-freestyle-writer/src/types.ts b/packages/fiori-freestyle-writer/src/types.ts index df20c999ed..f96330d280 100644 --- a/packages/fiori-freestyle-writer/src/types.ts +++ b/packages/fiori-freestyle-writer/src/types.ts @@ -1,6 +1,7 @@ import type { Ui5App, App } from '@sap-ux/ui5-application-writer'; import type { OdataService } from '@sap-ux/odata-service-writer'; import type { CapServiceCdsInfo } from '@sap-ux/cap-config-writer'; +import { AppOptions } from '@sap-ux/ui5-application-writer'; export const TemplateType = { Basic: 'basic', @@ -36,13 +37,22 @@ export interface Template { } export interface FioriApp extends App { flpAppId?: string; + namespace?: string; } export interface FreestyleApp extends Ui5App { template: Template; service?: OdataService & { capService?: CapServiceCdsInfo; + hasData?: boolean; }; app: FioriApp; + appOptions: Partial & { + /** + * Generate OPA based tests, for Simple template. + * This will eventually move up to {@link Ui5App.appOptions} + */ + addTests?: boolean; + }; } // We need this for the service version diff --git a/packages/fiori-freestyle-writer/tsconfig.json b/packages/fiori-freestyle-writer/tsconfig.json index a4a412cba2..4fa4674b37 100644 --- a/packages/fiori-freestyle-writer/tsconfig.json +++ b/packages/fiori-freestyle-writer/tsconfig.json @@ -27,6 +27,9 @@ }, { "path": "../ui5-config" + }, + { + "path": "../ui5-test-writer" } ] } diff --git a/packages/ui5-test-writer/src/index.ts b/packages/ui5-test-writer/src/index.ts index e4a381612f..7a7b2e4525 100644 --- a/packages/ui5-test-writer/src/index.ts +++ b/packages/ui5-test-writer/src/index.ts @@ -1,11 +1,13 @@ -import { join } from 'path'; +import { join, parse, basename } from 'path'; +import path from 'path'; import { create as createStorage } from 'mem-fs'; import type { Editor } from 'mem-fs-editor'; import { create } from 'mem-fs-editor'; import type { Manifest } from '@sap-ux/project-access'; import type { FEV4OPAConfig, FEV4OPAPageConfig, FEV4ManifestTarget } from './types'; -import { SupportedPageTypes, ValidationError } from './types'; +import { SupportedPageTypes, ValidationError, TestConfig } from './types'; import { t } from './i18n'; +import fs from 'fs'; /** * Reads the manifest for an app. @@ -356,3 +358,143 @@ export function generatePageObjectFile( return editor; } + +function writeOPAPackageJsonUpdates(fsEditor: Editor, destinationRoot: string, hasData: boolean): void { + const ui5MockYamlScript = hasData ? '--config ./ui5-mock.yaml ' : ''; + const scripts = { + 'unit-tests': `fiori run ${ui5MockYamlScript}--open 'test/unit/unitTests.qunit.html'`, + + 'int-tests': `fiori run ${ui5MockYamlScript}--open 'test/integration/opaTests.qunit.html'` + }; + + fsEditor.extendJSON(join(destinationRoot, 'package.json'), { scripts }); +} + +export function writeOPATsconfigJsonUpdates(fsEditor: Editor, destinationRoot: string): void { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const tsconfig: any = fsEditor.readJSON(join(destinationRoot, 'tsconfig.json')); + if (tsconfig.compilerOptions === undefined) { + tsconfig.compilerOptions = {}; + } + if (tsconfig.compilerOptions.paths === undefined) { + tsconfig.compilerOptions.paths = {}; + } + debugger; + tsconfig.compilerOptions.paths['unit/*'] = ['./webapp/test/unit/*']; + tsconfig.compilerOptions.paths['integration/*'] = ['./webapp/test/integration/*']; + + fsEditor.writeJSON(join(destinationRoot, 'tsconfig.json'), tsconfig); +} + +// export function generateFreestyleTestFiles( +// basePath: string, +// testConfig: { +// appId?: string; +// viewName?: string; +// viewNamePage?: string; +// ui5Theme?: string; +// appIdWithSlash?: string; +// applicationTitle?: string; +// navigationIntent?: string; +// applicationDescription?: string; +// enableTypeScript?: boolean; +// edmx?: boolean; +// }, +// fsEditor?: Editor +// ): Editor { +// const editor: Editor = fsEditor ?? create(createStorage()); +// const freestyleTemplateDirPath = join(__dirname, `../templates/freestyle/simple/webapp/test/1.71.0`); +// const testOutDirPath = join(basePath, 'webapp/test'); + +// // Function to recursively get all files from a directory +// const getAllFiles = (dir: any): string[] | [] => +// fs?.readdirSync(dir).reduce((files: any, file: string) => { +// const name = path.join(dir, file); +// const isDirectory = fs?.statSync(name).isDirectory(); +// return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name]; +// }, []); + +// // Get all template files +// const allTemplateFiles = getAllFiles(freestyleTemplateDirPath); + +// // Filter files based on TypeScript setting +// const filteredFiles = allTemplateFiles.filter(filePath => { +// if (filePath.endsWith('.ts')) { +// return testConfig.enableTypeScript === true; // Keep .ts if TypeScript is enabled +// } else if (filePath.endsWith('.js')) { +// return testConfig.enableTypeScript === false; // Keep .js if TypeScript is disabled +// } +// return true; // Keep other files (e.g., .html, .json, etc.) +// }); + +// // Copy each filtered file using copyTpl +// filteredFiles.forEach(filePath => { +// const relativePath = filePath.replace(freestyleTemplateDirPath, ''); // Preserve folder structure +// editor.copyTpl(filePath, join(testOutDirPath, relativePath), testConfig); +// }); + +// writeOPAPackageJsonUpdates(editor, basePath, !!testConfig.edmx); +// if (testConfig.enableTypeScript === true) { +// writeOPATsconfigJsonUpdates(editor, basePath); +// } + +// return editor; +// } + +// Function to recursively get all files from a directory +const getAllFiles = (dir: any): string[] | [] => + fs?.readdirSync(dir).reduce((files: any, file: string) => { + const name = path.join(dir, file); + const isDirectory = fs?.statSync(name).isDirectory(); + return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name]; + }, +[]); + +/** + * Generates and copies freestyle test files based on configuration + */ +export function generateFreestyleTestFiles( + basePath: string, + testConfig: TestConfig, + fsEditor?: Editor +): Editor { + const editor: Editor = fsEditor ?? create(createStorage()); + const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/simple/webapp/test/1.71.0'); + const testOutDirPath = join(basePath, 'webapp/test'); + + const viewNamePage = `${testConfig.viewName}Page` + + // Get all template files + const allTemplateFiles = getAllFiles(freestyleTemplateDirPath); + + // Filter files based on TypeScript setting + const filteredFiles = allTemplateFiles.filter(filePath => { + if (filePath.endsWith('.ts')) { + return testConfig.enableTypeScript === true; + } else if (filePath.endsWith('.js')) { + return testConfig.enableTypeScript === false; + } + return true; + }); + + // Copy each filtered file using copyTpl + filteredFiles.forEach(filePath => { + const relativePath = filePath.replace(freestyleTemplateDirPath, ''); + editor.copyTpl(filePath, join(testOutDirPath, relativePath), { + ...testConfig, + viewNamePage + }); + }); + + // Update package.json scripts + writeOPAPackageJsonUpdates(editor, basePath, testConfig.hasData ?? false); + + // Update tsconfig.json if TypeScript is enabled + if (testConfig.enableTypeScript) { + writeOPATsconfigJsonUpdates(editor, basePath); + } + + return editor; +} + + diff --git a/packages/ui5-test-writer/src/types.ts b/packages/ui5-test-writer/src/types.ts index 36e6d6e5b2..6963f4e1ba 100644 --- a/packages/ui5-test-writer/src/types.ts +++ b/packages/ui5-test-writer/src/types.ts @@ -58,3 +58,19 @@ export class ValidationError extends Error { this.name = this.constructor.name; } } + +/** + * Configuration interface for generating test files + */ +export interface TestConfig { + appId?: string; + appIdWithSlash?: string; + applicationTitle?: string; + applicationDescription?: string; + navigationIntent?: string; + ui5Theme?: string; + enableTypeScript?: boolean; + hasData?: boolean; + viewName?: string; + viewNamePage?: string; +} \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/model.json b/packages/ui5-test-writer/templates/simple/model.json deleted file mode 100644 index 0231282c2f..0000000000 --- a/packages/ui5-test-writer/templates/simple/model.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "neoapp": { - "welcomeFile": "/webapp/test/flpSandbox.html", - "sendWelcomeFileRedirect": true - }, - "datasource": { - "type": "odata", - "url": "" - }, - "simple": { - "environment": { - "internal": "false", - "resourcePath": "" - }, - "parameters": { - "ManifestVersion": { - "value": "" - }, - "ui5Version": { - "value": "" - }, - "ProjectName": { - "value": "" - }, - "AppId": { - "value": "" - }, - "ViewName": { - "value": "" - }, - "ViewNamePage": { - "value": "" - }, - "UI5Theme": { - "value": "" - }, - "sapUiBootstrapSrcUrl": { - "value": "" - }, - "AppIdWithSlash": { - "value": "" - }, - "ApplicationNamespace": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "Namespace" - }, - "wizard": { - "control": "TextField", - "regExp": "^[a-z][a-z 0-9]*(?:\\.[a-z][a-z 0-9]*)*$", - "required": true, - "title": "Namespace", - "regExpErrorMsg": "A namespace must not start with a digit. After the first character you may use any alphanumeric character or number separated by dots. Two successive dots are also forbidden. A namespace must not end with a dot." - } - }, - "ApplicationTitle": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "sap.app.title" - }, - "wizard": { - "control": "TextField", - "required": true, - "title": "Title", - "regExp": "^[\\w][\\w\\.\\-\\ ]*$" - } - }, - "ApplicationDescription": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "sap.app.description" - }, - "wizard": { - "control": "TextField", - "required": false, - "title": "Description" - } - }, - "FioriID": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "sap.fiori.registrationIds" - }, - "wizard": { - "control": "TextField", - "required": false, - "title": "SAP Fiori ID", - "internalOnly": true - } - }, - "ApplicationComponentHierarchy": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "sap.app.ach" - }, - "wizard": { - "control": "TextField", - "required": false, - "title": "Application Component Hierarchy", - "internalOnly": true - } - }, - "FLP": { - "type": "Entity", - "multiplicity": "many", - "isRoot": true, - "binding": [ - { - "name": "SAP Fiori Launchpad Component (optimized for SAP Fiori Launchpad registration)", - "value": true - }, - { - "name": "Standalone App (optimized for individual deployment)", - "value": false - } - ], - "value": "", - "wizard": { - "control": "ComboBox", - "required": true, - "title": "App Type", - "tooltip": "Choose if your app should run in SAP Fiori Launchpad or standalone" - } - }, - "DefineReplacement": { - "type": "string", - "value": "" - } - }, - "forms": [ - { - "type": "appDescriptorGenericStep", - "groups": [ - { - "parameters": [ - "@simple.parameters.ApplicationTitle", - "@simple.parameters.ApplicationNamespace", - "@simple.parameters.ApplicationDescription", - "@simple.parameters.ApplicationComponentHierarchy", - "@simple.parameters.FioriID" - ] - } - ] - }, - { - "groups": [ - { - "title": "Application Scenario", - "parameters": ["@simple.parameters.FLP"] - }, - { - "title": "Data Binding", - "parameters": [] - } - ] - } - ] - } -} diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/AllJourneys.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/AllJourneys.js.tmpl deleted file mode 100644 index 446661b69d..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/AllJourneys.js.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -sap.ui.define([ - "sap/ui/test/Opa5", - "./arrangements/Startup", - "./NavigationJourney" -], function (Opa5, Startup) { - "use strict"; - - Opa5.extendConfig({ - arrangements: new Startup(), - viewNamespace: "{{simple.parameters.AppId.value}}.view.", - autoWait: true - }); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.js.tmpl deleted file mode 100644 index 7131fc1b29..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.js.tmpl +++ /dev/null @@ -1,23 +0,0 @@ -/*global QUnit*/ - -sap.ui.define([ - "sap/ui/test/opaQunit", - "./pages/App", - "./pages/{{simple.parameters.ViewName.value}}" -], function (opaTest) { - "use strict"; - - QUnit.module("Navigation Journey"); - - opaTest("Should see the initial page of the app", function (Given, When, Then) { - // Arrangements - Given.iStartMyApp(); - - // Assertions - Then.onTheAppPage.iShouldSeeTheApp(); - Then.onTheViewPage.iShouldSeeThePageView(); - - //Cleanup - Then.iTeardownMyApp(); - }); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.ts.tmpl deleted file mode 100644 index ab61f59a43..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/NavigationJourney.ts.tmpl +++ /dev/null @@ -1,34 +0,0 @@ -/*global QUnit*/ -import opaTest from "sap/ui/test/opaQunit"; -import AppPage from "./pages/AppPage"; -import ViewPage from "./pages/{{simple.parameters.ViewName.value}}Page"; - -import Opa5 from "sap/ui/test/Opa5"; - -QUnit.module("Navigation Journey"); - -const onTheAppPage = new AppPage(); -const onTheViewPage = new ViewPage(); -Opa5.extendConfig({ - viewNamespace: "{{simple.parameters.AppId.value}}.view.", - autoWait: true -}); - -opaTest("Should see the initial page of the app", function () { - // Arrangements - // eslint-disable-next-line @typescript-eslint/no-floating-promises - onTheAppPage.iStartMyUIComponent({ - componentConfig: { - name: "{{simple.parameters.AppId.value}}" - } - }); - - // Assertions - onTheAppPage.iShouldSeeTheApp(); - onTheViewPage.iShouldSeeThePageView(); - - - // Cleanup - // eslint-disable-next-line @typescript-eslint/no-floating-promises - onTheAppPage.iTeardownMyApp(); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/arrangements/Startup.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/arrangements/Startup.js.tmpl deleted file mode 100644 index 6c764d9335..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/arrangements/Startup.js.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -sap.ui.define([ - "sap/ui/test/Opa5" -], function (Opa5) { - "use strict"; - - return Opa5.extend("integration.arrangements.Startup", { - - iStartMyApp: function (oOptionsParameter) { - var oOptions = oOptionsParameter || {}; - - // start the app with a minimal delay to make tests fast but still async to discover basic timing issues - oOptions.delay = oOptions.delay || 50; - - // start the app UI component - this.iStartMyUIComponent({ - componentConfig: { - name: "{{simple.parameters.AppId.value}}", - async: true - }, - hash: oOptions.hash, - autoWait: oOptions.autoWait - }); - } - }); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.html.tmpl deleted file mode 100644 index 251e5a63e3..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.html.tmpl +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Integration tests for Basic Template - - - - - - - - -
-
- - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.js.tmpl deleted file mode 100644 index 752127326e..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.js.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -/* global QUnit */ - -sap.ui.require(["{{formatNamespace simple.parameters.AppId.value}}/test/integration/AllJourneys" -], function () { - QUnit.config.autostart = false; - QUnit.start(); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.ts.tmpl deleted file mode 100644 index 851583d95f..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/opaTests.qunit.ts.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -/* global QUnit */ - -sap.ui.require(["integration/NavigationJourney" -], function () { - QUnit.config.autostart = false; - QUnit.start(); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/App.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/App.js.tmpl deleted file mode 100644 index db276e3fd4..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/App.js.tmpl +++ /dev/null @@ -1,28 +0,0 @@ -sap.ui.define([ - "sap/ui/test/Opa5" -], function (Opa5) { - "use strict"; - var sViewName = "App"; - - Opa5.createPageObjects({ - onTheAppPage: { - - actions: {}, - - assertions: { - - iShouldSeeTheApp: function () { - return this.waitFor({ - id: "app", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - } - } - }); - -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/AppPage.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/AppPage.ts.tmpl deleted file mode 100644 index 8cb42d2a57..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/AppPage.ts.tmpl +++ /dev/null @@ -1,22 +0,0 @@ -import Opa5 from "sap/ui/test/Opa5"; - -const sViewName = "App"; - -export default class AppPage extends Opa5 { - // Actions - - - // Assertions - iShouldSeeTheApp() { - return this.waitFor({ - id: "app", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - -} - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.js.tmpl deleted file mode 100644 index 5ec0839dc2..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.js.tmpl +++ /dev/null @@ -1,28 +0,0 @@ -sap.ui.define([ - "sap/ui/test/Opa5" -], function (Opa5) { - "use strict"; - var sViewName = "{{simple.parameters.ViewName.value}}"; - - Opa5.createPageObjects({ - onTheViewPage: { - - actions: {}, - - assertions: { - - iShouldSeeThePageView: function () { - return this.waitFor({ - id: "page", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - } - } - }); - -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.ts.tmpl deleted file mode 100644 index 1767150c80..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/integration/pages/viewName.ts.tmpl +++ /dev/null @@ -1,23 +0,0 @@ -import Opa5 from "sap/ui/test/Opa5"; - -const sViewName = "{{simple.parameters.ViewName.value}}"; - -export default class {{simple.parameters.ViewNamePage.value}} extends Opa5 { - // Actions - - - // Assertions - iShouldSeeThePageView() { - return this.waitFor({ - id: "page", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - -} - - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.html.tmpl deleted file mode 100644 index 17fec6f239..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.html.tmpl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - QUnit test suite for {{simple.parameters.AppId.value}} - - - - - - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.js.tmpl deleted file mode 100644 index 3df60a28c1..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.js.tmpl +++ /dev/null @@ -1,15 +0,0 @@ -/* global window, parent, location */ - -// eslint-disable-next-line fiori-custom/sap-no-global-define -window.suite = function() { - "use strict"; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); - - oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); - oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); - - return oSuite; -}; \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.ts.tmpl deleted file mode 100644 index 61446459d1..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/testsuite.qunit.ts.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -/* global window, parent, location */ - -// eslint-disable-next-line fiori-custom/sap-no-global-define,@typescript-eslint/ban-ts-comment -// @ts-nocheck -window.suite = function() { - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); - - oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); - oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); - - return oSuite; -}; diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/AllTests.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/AllTests.js.tmpl deleted file mode 100644 index fe65f492c6..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/AllTests.js.tmpl +++ /dev/null @@ -1,5 +0,0 @@ -sap.ui.define([ - "{{simple.parameters.AppIdWithSlash.value}}/test/unit/controller/{{simple.parameters.ViewName.value}}.controller" -], function () { - "use strict"; -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.js.tmpl deleted file mode 100644 index cbc446b9fc..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.js.tmpl +++ /dev/null @@ -1,16 +0,0 @@ -/*global QUnit*/ - -sap.ui.define([ - "{{simple.parameters.AppIdWithSlash.value}}/controller/{{simple.parameters.ViewName.value}}.controller" -], function (Controller) { - "use strict"; - - QUnit.module("{{simple.parameters.ViewName.value}} Controller"); - - QUnit.test("I should test the {{simple.parameters.ViewName.value}} controller", function (assert) { - var oAppController = new Controller(); - oAppController.onInit(); - assert.ok(oAppController); - }); - -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.ts.tmpl deleted file mode 100644 index ebe71640c9..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/controller/viewName.controller.ts.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -/*global QUnit*/ -import Controller from "{{simple.parameters.AppIdWithSlash.value}}/controller/{{simple.parameters.ViewName.value}}.controller"; - -QUnit.module("{{simple.parameters.ViewName.value}} Controller"); - -QUnit.test("I should test the {{simple.parameters.ViewName.value}} controller", function (assert: Assert) { - const oAppController = new Controller("{{simple.parameters.ViewName.value}}"); - oAppController.onInit(); - assert.ok(oAppController); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.html.tmpl deleted file mode 100644 index 38a547b189..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.html.tmpl +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Unit tests for {{simple.parameters.AppId.value}} - - - - - - - - - - -
-
- - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.js.tmpl deleted file mode 100644 index 9466c4093c..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.js.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -/* global QUnit */ -// https://api.qunitjs.com/config/autostart/ -QUnit.config.autostart = false; - -sap.ui.require([ - "{{simple.parameters.AppIdWithSlash.value}}/test/unit/AllTests" -], function (Controller) { - "use strict"; - QUnit.start(); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.ts.tmpl deleted file mode 100644 index b25f2a4fc0..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.124.0/unit/unitTests.qunit.ts.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -/* @sapUiRequire */ -QUnit.config.autostart = false; - -// import all your QUnit tests here -void Promise.all([ - import("sap/ui/core/Core"), // required to wait until Core has booted to start the QUnit tests - import("unit/controller/{{simple.parameters.ViewName.value}}Page.controller"), -]).then(([{default: Core}]) => Core.ready()).then(() => { - QUnit.start(); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/flpSandbox.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/flpSandbox.js.tmpl deleted file mode 100644 index 1f3c835e1b..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/flpSandbox.js.tmpl +++ /dev/null @@ -1,102 +0,0 @@ -sap.ui.define([ - "sap/base/util/ObjectPath", - "sap/ushell/services/Container" -], function (ObjectPath) { - "use strict"; - - // define ushell config - ObjectPath.set(["sap-ushell-config"], { - defaultRenderer: "fiori2", - bootstrapPlugins: { - "RuntimeAuthoringPlugin": { - component: "sap.ushell.plugins.rta", - config: { - validateAppVersion: false - } - }, - "PersonalizePlugin": { - component: "sap.ushell.plugins.rta-personalize", - config: { - validateAppVersion: false - } - } - }, - renderers: { - fiori2: { - componentData: { - config: { - enableSearch: false, - rootIntent: "Shell-home" - } - } - } - }, - services: { - "LaunchPage": { - "adapter": { - "config": { - "groups": [{ - "tiles": [{ - "tileType": "sap.ushell.ui.tile.StaticTile", - "properties": { - {{#if simple.parameters.ApplicationTitle.value}} - "title": "{{simple.parameters.ApplicationTitle.value}}",{{/if}} - "targetURL": "#{{simple.parameters.NavigationIntent}}-display" - } - }] - }] - } - } - }, - "ClientSideTargetResolution": { - "adapter": { - "config": { - "inbounds": { - "{{simple.parameters.NavigationIntent}}-display": { - "semanticObject": "{{simple.parameters.NavigationIntent}}", - "action": "display", - {{#if simple.parameters.ApplicationDescription.value}} - "description": "{{simple.parameters.ApplicationDescription.value}}",{{/if}}{{#if simple.parameters.ApplicationTitle.value}} - "title": "{{simple.parameters.ApplicationTitle.value}}",{{/if}} - "signature": { - "parameters": {} - }, - "resolutionResult": { - "applicationType": "SAPUI5", - "additionalInformation": "SAPUI5.Component={{simple.parameters.AppId.value}}", - "url": sap.ui.require.toUrl("{{formatNamespace simple.parameters.AppId.value}}") - } - } - } - } - } - }, - NavTargetResolution: { - config: { - "enableClientSideTargetResolution": true - } - } - } - }); - - var oFlpSandbox = { - init: function () { - /** - * Initializes the FLP sandbox - * @returns {Promise} a promise that is resolved when the sandbox bootstrap has finshed - */ - - // sandbox is a singleton, so we can start it only once - if (!this._oBootstrapFinished) { - this._oBootstrapFinished = sap.ushell.bootstrap("local"); - this._oBootstrapFinished.then(function () { - sap.ushell.Container.createRenderer().placeAt("content"); - }); - } - - return this._oBootstrapFinished; - } - }; - - return oFlpSandbox; -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/initFlpSandbox.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/initFlpSandbox.js.tmpl deleted file mode 100644 index 7a8f6bcfba..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/initFlpSandbox.js.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -sap.ui.define([ - "./flpSandbox", - "sap/ui/fl/FakeLrepConnectorLocalStorage", - "sap/m/MessageBox" -], function (flpSandbox, FakeLrepConnectorLocalStorage, MessageBox) { - "use strict"; - - flpSandbox.init().then(function () { - FakeLrepConnectorLocalStorage.enableFakeConnector(); - }, function (oError) { - MessageBox.error(oError.message); - }); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/AllJourneys.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/AllJourneys.js.tmpl deleted file mode 100644 index 446661b69d..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/AllJourneys.js.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -sap.ui.define([ - "sap/ui/test/Opa5", - "./arrangements/Startup", - "./NavigationJourney" -], function (Opa5, Startup) { - "use strict"; - - Opa5.extendConfig({ - arrangements: new Startup(), - viewNamespace: "{{simple.parameters.AppId.value}}.view.", - autoWait: true - }); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.js.tmpl deleted file mode 100644 index 7131fc1b29..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.js.tmpl +++ /dev/null @@ -1,23 +0,0 @@ -/*global QUnit*/ - -sap.ui.define([ - "sap/ui/test/opaQunit", - "./pages/App", - "./pages/{{simple.parameters.ViewName.value}}" -], function (opaTest) { - "use strict"; - - QUnit.module("Navigation Journey"); - - opaTest("Should see the initial page of the app", function (Given, When, Then) { - // Arrangements - Given.iStartMyApp(); - - // Assertions - Then.onTheAppPage.iShouldSeeTheApp(); - Then.onTheViewPage.iShouldSeeThePageView(); - - //Cleanup - Then.iTeardownMyApp(); - }); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.ts.tmpl deleted file mode 100644 index ab61f59a43..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/NavigationJourney.ts.tmpl +++ /dev/null @@ -1,34 +0,0 @@ -/*global QUnit*/ -import opaTest from "sap/ui/test/opaQunit"; -import AppPage from "./pages/AppPage"; -import ViewPage from "./pages/{{simple.parameters.ViewName.value}}Page"; - -import Opa5 from "sap/ui/test/Opa5"; - -QUnit.module("Navigation Journey"); - -const onTheAppPage = new AppPage(); -const onTheViewPage = new ViewPage(); -Opa5.extendConfig({ - viewNamespace: "{{simple.parameters.AppId.value}}.view.", - autoWait: true -}); - -opaTest("Should see the initial page of the app", function () { - // Arrangements - // eslint-disable-next-line @typescript-eslint/no-floating-promises - onTheAppPage.iStartMyUIComponent({ - componentConfig: { - name: "{{simple.parameters.AppId.value}}" - } - }); - - // Assertions - onTheAppPage.iShouldSeeTheApp(); - onTheViewPage.iShouldSeeThePageView(); - - - // Cleanup - // eslint-disable-next-line @typescript-eslint/no-floating-promises - onTheAppPage.iTeardownMyApp(); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/arrangements/Startup.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/arrangements/Startup.js.tmpl deleted file mode 100644 index 6c764d9335..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/arrangements/Startup.js.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -sap.ui.define([ - "sap/ui/test/Opa5" -], function (Opa5) { - "use strict"; - - return Opa5.extend("integration.arrangements.Startup", { - - iStartMyApp: function (oOptionsParameter) { - var oOptions = oOptionsParameter || {}; - - // start the app with a minimal delay to make tests fast but still async to discover basic timing issues - oOptions.delay = oOptions.delay || 50; - - // start the app UI component - this.iStartMyUIComponent({ - componentConfig: { - name: "{{simple.parameters.AppId.value}}", - async: true - }, - hash: oOptions.hash, - autoWait: oOptions.autoWait - }); - } - }); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.html.tmpl deleted file mode 100644 index 4e2b65aa9e..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.html.tmpl +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Integration tests for Basic Template - - - - - - - -
-
- - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.js.tmpl deleted file mode 100644 index 752127326e..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.js.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -/* global QUnit */ - -sap.ui.require(["{{formatNamespace simple.parameters.AppId.value}}/test/integration/AllJourneys" -], function () { - QUnit.config.autostart = false; - QUnit.start(); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.ts.tmpl deleted file mode 100644 index 024c1d9041..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/opaTests.qunit.ts.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -/* global QUnit */ -// https://api.qunitjs.com/config/autostart/ -QUnit.config.autostart = false; - -// import all your OPA journeys here -void Promise.all([ - import("integration/NavigationJourney") -]).then(() => { - QUnit.start(); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/App.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/App.js.tmpl deleted file mode 100644 index db276e3fd4..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/App.js.tmpl +++ /dev/null @@ -1,28 +0,0 @@ -sap.ui.define([ - "sap/ui/test/Opa5" -], function (Opa5) { - "use strict"; - var sViewName = "App"; - - Opa5.createPageObjects({ - onTheAppPage: { - - actions: {}, - - assertions: { - - iShouldSeeTheApp: function () { - return this.waitFor({ - id: "app", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - } - } - }); - -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/AppPage.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/AppPage.ts.tmpl deleted file mode 100644 index 8cb42d2a57..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/AppPage.ts.tmpl +++ /dev/null @@ -1,22 +0,0 @@ -import Opa5 from "sap/ui/test/Opa5"; - -const sViewName = "App"; - -export default class AppPage extends Opa5 { - // Actions - - - // Assertions - iShouldSeeTheApp() { - return this.waitFor({ - id: "app", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - -} - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.js.tmpl deleted file mode 100644 index 5ec0839dc2..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.js.tmpl +++ /dev/null @@ -1,28 +0,0 @@ -sap.ui.define([ - "sap/ui/test/Opa5" -], function (Opa5) { - "use strict"; - var sViewName = "{{simple.parameters.ViewName.value}}"; - - Opa5.createPageObjects({ - onTheViewPage: { - - actions: {}, - - assertions: { - - iShouldSeeThePageView: function () { - return this.waitFor({ - id: "page", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - } - } - }); - -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.ts.tmpl deleted file mode 100644 index 1767150c80..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/integration/pages/viewName.ts.tmpl +++ /dev/null @@ -1,23 +0,0 @@ -import Opa5 from "sap/ui/test/Opa5"; - -const sViewName = "{{simple.parameters.ViewName.value}}"; - -export default class {{simple.parameters.ViewNamePage.value}} extends Opa5 { - // Actions - - - // Assertions - iShouldSeeThePageView() { - return this.waitFor({ - id: "page", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - -} - - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.html.tmpl deleted file mode 100644 index 17fec6f239..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.html.tmpl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - QUnit test suite for {{simple.parameters.AppId.value}} - - - - - - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.js.tmpl deleted file mode 100644 index 3df60a28c1..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.js.tmpl +++ /dev/null @@ -1,15 +0,0 @@ -/* global window, parent, location */ - -// eslint-disable-next-line fiori-custom/sap-no-global-define -window.suite = function() { - "use strict"; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); - - oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); - oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); - - return oSuite; -}; \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.ts.tmpl deleted file mode 100644 index 61446459d1..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/testsuite.qunit.ts.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -/* global window, parent, location */ - -// eslint-disable-next-line fiori-custom/sap-no-global-define,@typescript-eslint/ban-ts-comment -// @ts-nocheck -window.suite = function() { - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); - - oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); - oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); - - return oSuite; -}; diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/AllTests.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/AllTests.js.tmpl deleted file mode 100644 index fe65f492c6..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/AllTests.js.tmpl +++ /dev/null @@ -1,5 +0,0 @@ -sap.ui.define([ - "{{simple.parameters.AppIdWithSlash.value}}/test/unit/controller/{{simple.parameters.ViewName.value}}.controller" -], function () { - "use strict"; -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.js.tmpl deleted file mode 100644 index cbc446b9fc..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.js.tmpl +++ /dev/null @@ -1,16 +0,0 @@ -/*global QUnit*/ - -sap.ui.define([ - "{{simple.parameters.AppIdWithSlash.value}}/controller/{{simple.parameters.ViewName.value}}.controller" -], function (Controller) { - "use strict"; - - QUnit.module("{{simple.parameters.ViewName.value}} Controller"); - - QUnit.test("I should test the {{simple.parameters.ViewName.value}} controller", function (assert) { - var oAppController = new Controller(); - oAppController.onInit(); - assert.ok(oAppController); - }); - -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.ts.tmpl deleted file mode 100644 index ebe71640c9..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/controller/viewName.controller.ts.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -/*global QUnit*/ -import Controller from "{{simple.parameters.AppIdWithSlash.value}}/controller/{{simple.parameters.ViewName.value}}.controller"; - -QUnit.module("{{simple.parameters.ViewName.value}} Controller"); - -QUnit.test("I should test the {{simple.parameters.ViewName.value}} controller", function (assert: Assert) { - const oAppController = new Controller("{{simple.parameters.ViewName.value}}"); - oAppController.onInit(); - assert.ok(oAppController); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.html.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.html.tmpl deleted file mode 100644 index f3f6783bda..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.html.tmpl +++ /dev/null @@ -1,27 +0,0 @@ - - - - - Unit tests for {{simple.parameters.AppId.value}} - - - - - - - - - -
-
- - diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.js.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.js.tmpl deleted file mode 100644 index 329eb6912d..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.js.tmpl +++ /dev/null @@ -1,12 +0,0 @@ -/* global QUnit */ -QUnit.config.autostart = false; - -sap.ui.getCore().attachInit(function () { - "use strict"; - - sap.ui.require([ - "{{simple.parameters.AppIdWithSlash.value}}/test/unit/AllTests" - ], function () { - QUnit.start(); - }); -}); diff --git a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.ts.tmpl b/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.ts.tmpl deleted file mode 100644 index f27303b333..0000000000 --- a/packages/ui5-test-writer/templates/simple/webapp/test/1.71.0/unit/unitTests.qunit.ts.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -/* global QUnit */ -// https://api.qunitjs.com/config/autostart/ -QUnit.config.autostart = false; - -// import all your QUnit tests here -void Promise.all([ - import("unit/controller/{{simple.parameters.ViewName.value}}Page.controller") -]).then(() => { - QUnit.start(); -}); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4deac69d26..4970074cb9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1907,6 +1907,9 @@ importers: '@sap-ux/ui5-config': specifier: workspace:* version: link:../ui5-config + '@sap-ux/ui5-test-writer': + specifier: workspace:* + version: link:../ui5-test-writer ejs: specifier: 3.1.10 version: 3.1.10 From 81204cbc381a250248b98286f2c8760696b0ad2f Mon Sep 17 00:00:00 2001 From: I743583 Date: Tue, 11 Feb 2025 13:49:33 +0000 Subject: [PATCH 03/42] clean up --- packages/fiori-freestyle-writer/src/index.ts | 32 +------- packages/ui5-test-writer/src/index.ts | 81 ++++---------------- packages/ui5-test-writer/src/types.ts | 4 +- 3 files changed, 19 insertions(+), 98 deletions(-) diff --git a/packages/fiori-freestyle-writer/src/index.ts b/packages/fiori-freestyle-writer/src/index.ts index 43bb82fa3b..df86b6b70d 100644 --- a/packages/fiori-freestyle-writer/src/index.ts +++ b/packages/fiori-freestyle-writer/src/index.ts @@ -13,7 +13,7 @@ import { initI18n } from './i18n'; import { getBootstrapResourceUrls, getPackageScripts } from '@sap-ux/fiori-generator-shared'; import { getTemplateVersionPath, processDestinationPath } from './utils'; import { applyCAPUpdates, type CapProjectSettings } from '@sap-ux/cap-config-writer'; -import { generateFreestyleTestFiles } from '@sap-ux/ui5-test-writer'; +import { writeTestFiles } from './writeTestFiles'; /** * Generate a UI5 application based on the specified Fiori Freestyle floorplan template. @@ -167,37 +167,9 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor) ui5LocalConfig.addFioriToolsProxydMiddleware({}); fs.write(ui5LocalConfigPath, ui5LocalConfig.toString()); } - - const getApplicationIdWithSlash = (): string => { - let appIdWihSlash; - if (ffApp.appOptions?.typescript=== true) { - appIdWihSlash = `${ffApp.app.namespace?.replace(/\./g, '/').replace(/\/$/, '')}${ - ffApp.app.namespace !== '' ? '/' : '' - }${ffApp.package.name?.replace(/[_-]/g, '')}`; - } else { - appIdWihSlash = `${ffApp.app.namespace?.replace(/\./g, '')}${ffApp.app.namespace !== '' ? '/' : ''}${ - ffApp.package.name - }`; - } - return appIdWihSlash; - } - console.log(); if (ffApp.appOptions?.addTests) { - generateFreestyleTestFiles( - basePath, - { - appId: ffApp.app.id, - viewName: (ffApp.template.settings as BasicAppSettings).viewName, - ui5Theme: ffApp.ui5?.ui5Theme, - appIdWithSlash: getApplicationIdWithSlash(), - applicationTitle: ffApp.app.title, - //navigationIntent: string, - applicationDescription: ffApp.app.description, - hasData: ffApp.service?.hasData, - }, - fs - ); + writeTestFiles(basePath, ffApp, fs); } if (ffApp.service?.capService) { diff --git a/packages/ui5-test-writer/src/index.ts b/packages/ui5-test-writer/src/index.ts index 7a7b2e4525..ac24919fc8 100644 --- a/packages/ui5-test-writer/src/index.ts +++ b/packages/ui5-test-writer/src/index.ts @@ -379,69 +379,12 @@ export function writeOPATsconfigJsonUpdates(fsEditor: Editor, destinationRoot: s if (tsconfig.compilerOptions.paths === undefined) { tsconfig.compilerOptions.paths = {}; } - debugger; tsconfig.compilerOptions.paths['unit/*'] = ['./webapp/test/unit/*']; tsconfig.compilerOptions.paths['integration/*'] = ['./webapp/test/integration/*']; fsEditor.writeJSON(join(destinationRoot, 'tsconfig.json'), tsconfig); } -// export function generateFreestyleTestFiles( -// basePath: string, -// testConfig: { -// appId?: string; -// viewName?: string; -// viewNamePage?: string; -// ui5Theme?: string; -// appIdWithSlash?: string; -// applicationTitle?: string; -// navigationIntent?: string; -// applicationDescription?: string; -// enableTypeScript?: boolean; -// edmx?: boolean; -// }, -// fsEditor?: Editor -// ): Editor { -// const editor: Editor = fsEditor ?? create(createStorage()); -// const freestyleTemplateDirPath = join(__dirname, `../templates/freestyle/simple/webapp/test/1.71.0`); -// const testOutDirPath = join(basePath, 'webapp/test'); - -// // Function to recursively get all files from a directory -// const getAllFiles = (dir: any): string[] | [] => -// fs?.readdirSync(dir).reduce((files: any, file: string) => { -// const name = path.join(dir, file); -// const isDirectory = fs?.statSync(name).isDirectory(); -// return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name]; -// }, []); - -// // Get all template files -// const allTemplateFiles = getAllFiles(freestyleTemplateDirPath); - -// // Filter files based on TypeScript setting -// const filteredFiles = allTemplateFiles.filter(filePath => { -// if (filePath.endsWith('.ts')) { -// return testConfig.enableTypeScript === true; // Keep .ts if TypeScript is enabled -// } else if (filePath.endsWith('.js')) { -// return testConfig.enableTypeScript === false; // Keep .js if TypeScript is disabled -// } -// return true; // Keep other files (e.g., .html, .json, etc.) -// }); - -// // Copy each filtered file using copyTpl -// filteredFiles.forEach(filePath => { -// const relativePath = filePath.replace(freestyleTemplateDirPath, ''); // Preserve folder structure -// editor.copyTpl(filePath, join(testOutDirPath, relativePath), testConfig); -// }); - -// writeOPAPackageJsonUpdates(editor, basePath, !!testConfig.edmx); -// if (testConfig.enableTypeScript === true) { -// writeOPATsconfigJsonUpdates(editor, basePath); -// } - -// return editor; -// } - -// Function to recursively get all files from a directory const getAllFiles = (dir: any): string[] | [] => fs?.readdirSync(dir).reduce((files: any, file: string) => { const name = path.join(dir, file); @@ -450,19 +393,23 @@ const getAllFiles = (dir: any): string[] | [] => }, []); + /** * Generates and copies freestyle test files based on configuration */ export function generateFreestyleTestFiles( basePath: string, - testConfig: TestConfig, + config: TestConfig, fsEditor?: Editor ): Editor { const editor: Editor = fsEditor ?? create(createStorage()); - const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/simple/webapp/test/1.71.0'); + const { appIdWithSlash, enableTypeScript, ui5Version } = config; + + const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/simple/webapp/test', ui5Version); const testOutDirPath = join(basePath, 'webapp/test'); - const viewNamePage = `${testConfig.viewName}Page` + // get test config + const viewNamePage = `${config.viewName}Page`; // Get all template files const allTemplateFiles = getAllFiles(freestyleTemplateDirPath); @@ -470,9 +417,9 @@ export function generateFreestyleTestFiles( // Filter files based on TypeScript setting const filteredFiles = allTemplateFiles.filter(filePath => { if (filePath.endsWith('.ts')) { - return testConfig.enableTypeScript === true; + return enableTypeScript === true; } else if (filePath.endsWith('.js')) { - return testConfig.enableTypeScript === false; + return enableTypeScript === false; } return true; }); @@ -481,16 +428,16 @@ export function generateFreestyleTestFiles( filteredFiles.forEach(filePath => { const relativePath = filePath.replace(freestyleTemplateDirPath, ''); editor.copyTpl(filePath, join(testOutDirPath, relativePath), { - ...testConfig, - viewNamePage + ...config, + viewNamePage, + appIdWithSlash }); }); // Update package.json scripts - writeOPAPackageJsonUpdates(editor, basePath, testConfig.hasData ?? false); - + writeOPAPackageJsonUpdates(editor, basePath, config.hasData ?? false); // Update tsconfig.json if TypeScript is enabled - if (testConfig.enableTypeScript) { + if (config.enableTypeScript) { writeOPATsconfigJsonUpdates(editor, basePath); } diff --git a/packages/ui5-test-writer/src/types.ts b/packages/ui5-test-writer/src/types.ts index 6963f4e1ba..5695dd28b8 100644 --- a/packages/ui5-test-writer/src/types.ts +++ b/packages/ui5-test-writer/src/types.ts @@ -63,7 +63,7 @@ export class ValidationError extends Error { * Configuration interface for generating test files */ export interface TestConfig { - appId?: string; + appId: string; appIdWithSlash?: string; applicationTitle?: string; applicationDescription?: string; @@ -73,4 +73,6 @@ export interface TestConfig { hasData?: boolean; viewName?: string; viewNamePage?: string; + appIdWihSlash: string; + ui5Version: string; } \ No newline at end of file From 373b3ec02a51ba6f9a8327a759f21d9939e4b39c Mon Sep 17 00:00:00 2001 From: I743583 Date: Tue, 11 Feb 2025 16:06:45 +0000 Subject: [PATCH 04/42] progress --- packages/ui5-test-writer/src/index.ts | 21 +++++++++++++-------- packages/ui5-test-writer/src/types.ts | 3 +-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/ui5-test-writer/src/index.ts b/packages/ui5-test-writer/src/index.ts index ac24919fc8..3449868670 100644 --- a/packages/ui5-test-writer/src/index.ts +++ b/packages/ui5-test-writer/src/index.ts @@ -406,6 +406,7 @@ export function generateFreestyleTestFiles( const { appIdWithSlash, enableTypeScript, ui5Version } = config; const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/simple/webapp/test', ui5Version); + console.log(" --- freestyleTemplateDirPath: ", freestyleTemplateDirPath); const testOutDirPath = join(basePath, 'webapp/test'); // get test config @@ -413,25 +414,29 @@ export function generateFreestyleTestFiles( // Get all template files const allTemplateFiles = getAllFiles(freestyleTemplateDirPath); + console.log(" --- allTemplateFiles: ", allTemplateFiles); + const typeScript = enableTypeScript === undefined ? false : true; // Filter files based on TypeScript setting const filteredFiles = allTemplateFiles.filter(filePath => { if (filePath.endsWith('.ts')) { - return enableTypeScript === true; + return typeScript === true; } else if (filePath.endsWith('.js')) { - return enableTypeScript === false; + return typeScript === false; } return true; }); + const testConfig = { + ...config, + viewNamePage, + appIdWithSlash + }; + // Copy each filtered file using copyTpl - filteredFiles.forEach(filePath => { + filteredFiles.forEach((filePath: any) => { const relativePath = filePath.replace(freestyleTemplateDirPath, ''); - editor.copyTpl(filePath, join(testOutDirPath, relativePath), { - ...config, - viewNamePage, - appIdWithSlash - }); + editor.copyTpl(filePath, join(testOutDirPath, relativePath), testConfig); }); // Update package.json scripts diff --git a/packages/ui5-test-writer/src/types.ts b/packages/ui5-test-writer/src/types.ts index 5695dd28b8..a043703158 100644 --- a/packages/ui5-test-writer/src/types.ts +++ b/packages/ui5-test-writer/src/types.ts @@ -64,7 +64,7 @@ export class ValidationError extends Error { */ export interface TestConfig { appId: string; - appIdWithSlash?: string; + appIdWithSlash: string; applicationTitle?: string; applicationDescription?: string; navigationIntent?: string; @@ -73,6 +73,5 @@ export interface TestConfig { hasData?: boolean; viewName?: string; viewNamePage?: string; - appIdWihSlash: string; ui5Version: string; } \ No newline at end of file From e971819358bf22a496f3fc6f97cd2d12cb4b69cf Mon Sep 17 00:00:00 2001 From: I743583 Date: Wed, 12 Feb 2025 14:31:03 +0000 Subject: [PATCH 05/42] testing with templates --- packages/ui5-test-writer/src/index.ts | 74 +++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/packages/ui5-test-writer/src/index.ts b/packages/ui5-test-writer/src/index.ts index 3449868670..3587cc5a65 100644 --- a/packages/ui5-test-writer/src/index.ts +++ b/packages/ui5-test-writer/src/index.ts @@ -414,7 +414,6 @@ export function generateFreestyleTestFiles( // Get all template files const allTemplateFiles = getAllFiles(freestyleTemplateDirPath); - console.log(" --- allTemplateFiles: ", allTemplateFiles); const typeScript = enableTypeScript === undefined ? false : true; // Filter files based on TypeScript setting @@ -425,19 +424,84 @@ export function generateFreestyleTestFiles( return typeScript === false; } return true; + }).map(filePath => { + // Transform the file path to the relative path + const relativePath: string = filePath.replace(freestyleTemplateDirPath, ''); + return relativePath; }); + console.log(" --- filteredFiles: ", filteredFiles); const testConfig = { ...config, viewNamePage, - appIdWithSlash + appIdWithSlash: appIdWithSlash }; + console.log(" -- testConfig: ", testConfig); + + function processDestinationPath(filePath: string): string { + //return filePath.replace('/1.120.0', '').replace('/1.71.0', ''); + //console.log(" --- filePath: ", filePath); + if(filePath === '/integration/pages/viewName.js'){ + return filePath.replace(/viewName/g, 'KITTY'); + } + return filePath; + } + + + // Copy each filtered file using copyTpl - filteredFiles.forEach((filePath: any) => { - const relativePath = filePath.replace(freestyleTemplateDirPath, ''); - editor.copyTpl(filePath, join(testOutDirPath, relativePath), testConfig); + console.log(" ---join(freestyleTemplateDirPath, '*.*')", join(freestyleTemplateDirPath, '*.*')) + console.log(" ---to join(testOutDirPath, 'integration')", testOutDirPath) + // editor.copyTpl(join(freestyleTemplateDirPath, '**', '*.*'), testOutDirPath, testConfig, undefined, { + // globOptions: { dot: true }, + // processDestinationPath: processDestinationPath + // }); + + // Iterate through the filtered files and copy each one + filteredFiles.forEach((filePath: string) => { + // If the file is 'integration/page/viewName.js', rename it to 'integration/page/kitty.js' + let sourceFilePath = join(freestyleTemplateDirPath, filePath); + let destinationFilePath = join(testOutDirPath, filePath); + + // Check if the file is 'integration/page/viewName.js' + if (filePath === '/integration/pages/viewName.js') { + + // Change the file name to 'kitty.js' + destinationFilePath = join(testOutDirPath, `integration/pages/${config.viewName}.js`); + console.log(" --- match found --- ", destinationFilePath) + } + + if (filePath === '/unit/controller/viewName.controller.js') { + + // Change the file name to 'kitty.js' + destinationFilePath = join(testOutDirPath, `unit/controller/${config.viewName}.controller.js`); + console.log(" --- match found --- ", destinationFilePath) + } + + // Copy the file using editor.copyTpl + editor.copyTpl( + sourceFilePath, // Source file path (no change) + destinationFilePath, // Destination file path (changed if necessary) + testConfig, // Configuration for the template + undefined, // Additional options if needed + { + globOptions: { dot: true }, // Glob options if needed + // processDestinationPath: processDestinationPath // Apply the custom path processing if needed + } + ); }); + + + // filteredFiles.forEach((filePath: string) => { + // debugger; + // const relativePath: string = filePath.replace(freestyleTemplateDirPath, ''); + // console.log(" --- relativePath: ", relativePath); + + // editor.copyTpl(filePath, join(testOutDirPath, relativePath), testConfig, undefined, { + // processDestinationPath: processDestinationPath + // }); + // }); // Update package.json scripts writeOPAPackageJsonUpdates(editor, basePath, config.hasData ?? false); From 96fdd0c68bf6e61dce0a0ff175d6268e2c4ceef7 Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 14 Feb 2025 14:17:26 +0000 Subject: [PATCH 06/42] added OPA generate FF --- packages/fiori-freestyle-writer/src/index.ts | 14 +- packages/fiori-freestyle-writer/src/types.ts | 1 - .../npm-package-scripts/getPackageScripts.ts | 13 +- .../src/npm-package-scripts/types.ts | 5 +- packages/ui5-test-writer/src/index.ts | 272 +++++++++--------- packages/ui5-test-writer/src/types.ts | 11 +- 6 files changed, 156 insertions(+), 160 deletions(-) diff --git a/packages/fiori-freestyle-writer/src/index.ts b/packages/fiori-freestyle-writer/src/index.ts index df86b6b70d..5db62396b2 100644 --- a/packages/fiori-freestyle-writer/src/index.ts +++ b/packages/fiori-freestyle-writer/src/index.ts @@ -14,6 +14,7 @@ import { getBootstrapResourceUrls, getPackageScripts } from '@sap-ux/fiori-gener import { getTemplateVersionPath, processDestinationPath } from './utils'; import { applyCAPUpdates, type CapProjectSettings } from '@sap-ux/cap-config-writer'; import { writeTestFiles } from './writeTestFiles'; +import type { Logger } from '@sap-ux/logger'; /** * Generate a UI5 application based on the specified Fiori Freestyle floorplan template. @@ -23,7 +24,7 @@ import { writeTestFiles } from './writeTestFiles'; * @param fs - an optional reference to a mem-fs editor * @returns Reference to a mem-fs-editor */ -async function generate(basePath: string, data: FreestyleApp, fs?: Editor): Promise { +async function generate(basePath: string, data: FreestyleApp, fs?: Editor, log?: Logger): Promise { // Load i18n translations asynchronously to ensure proper initialization. // This addresses occasional issues where i18n is not initialized in time, causing tests to fail. await initI18n(); @@ -134,7 +135,9 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor) JSON.parse(render(fs.read(join(tmplPath, 'common', 'extend', 'package.json')), ffApp, {})) ); + const addTests = ffApp.appOptions?.addTests; const packageJson: Package = JSON.parse(fs.read(packagePath)); + if (isEdmxProjectType) { // Add scripts for non-CAP applications packageJson.scripts = { @@ -146,7 +149,10 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor) flpAppId: ffApp.app.flpAppId, startFile: data?.app?.startFile, localStartFile: data?.app?.localStartFile, - generateIndex: ffApp.appOptions?.generateIndex + generateIndex: ffApp.appOptions?.generateIndex, + addTest: addTests, + // revist this + hasService: !!ffApp.service?.metadata }) }; } else { @@ -168,8 +174,8 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor) fs.write(ui5LocalConfigPath, ui5LocalConfig.toString()); } - if (ffApp.appOptions?.addTests) { - writeTestFiles(basePath, ffApp, fs); + if (addTests && isEdmxProjectType) { + await writeTestFiles(basePath, ffApp, fs, log); } if (ffApp.service?.capService) { diff --git a/packages/fiori-freestyle-writer/src/types.ts b/packages/fiori-freestyle-writer/src/types.ts index f96330d280..87f3fdb94b 100644 --- a/packages/fiori-freestyle-writer/src/types.ts +++ b/packages/fiori-freestyle-writer/src/types.ts @@ -43,7 +43,6 @@ export interface FreestyleApp extends Ui5App { template: Template; service?: OdataService & { capService?: CapServiceCdsInfo; - hasData?: boolean; }; app: FioriApp; appOptions: Partial & { diff --git a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts index f2fff16169..30880dcd6a 100644 --- a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts +++ b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts @@ -120,7 +120,8 @@ export function getPackageScripts({ flpAppId = '', startFile, localStartFile, - generateIndex = true + generateIndex = true, + hasService = true }: PackageScriptsOptions): PackageJsonScripts { const searchParams = buildSearchParams(sapClient); const params = buildParams(searchParams, flpAppId); @@ -140,13 +141,15 @@ export function getPackageScripts({ scripts['start-mock'] = `fiori run --config ./ui5-mock.yaml --open "test/flpSandbox.html${params}"`; } - if (addTest) { - scripts['int-test'] = 'fiori run --config ./ui5-mock.yaml --open "test/integration/opaTests.qunit.html"'; - } - scripts['start-variants-management'] = localOnly ? `echo \\"${t('info.mockOnlyWarning')}\\"` : getVariantPreviewAppScript(sapClient); + if (addTest) { + const ui5MockYamlScript = hasService ? '--config ./ui5-mock.yaml ' : '' ; + scripts['unit-tests'] = `fiori run ${ui5MockYamlScript}--open 'test/unit/unitTests.qunit.html'`, + scripts['int-tests'] = `fiori run ${ui5MockYamlScript}--open 'test/integration/opaTests.qunit.html'`; + } + return scripts; } diff --git a/packages/fiori-generator-shared/src/npm-package-scripts/types.ts b/packages/fiori-generator-shared/src/npm-package-scripts/types.ts index 6b85684a91..bfb8812065 100644 --- a/packages/fiori-generator-shared/src/npm-package-scripts/types.ts +++ b/packages/fiori-generator-shared/src/npm-package-scripts/types.ts @@ -10,8 +10,10 @@ export interface PackageJsonScripts { 'start-noflp'?: string; /** Optional command to start the application with a mock server configuration. */ 'start-mock'?: string; + /** Optional command to run unit tests. */ + 'unit-tests'?: string; /** Optional command to run tests. */ - 'int-test'?: string; + 'int-tests'?: string; /** Optional command to add the variants management script. */ 'start-variants-management'?: string; } @@ -36,4 +38,5 @@ export interface PackageScriptsOptions { localStartFile?: string; /** If true, a script for starting the app without flp will be generated. Defaults to true. */ generateIndex?: boolean; + hasService?: boolean; } diff --git a/packages/ui5-test-writer/src/index.ts b/packages/ui5-test-writer/src/index.ts index 3587cc5a65..ad279712de 100644 --- a/packages/ui5-test-writer/src/index.ts +++ b/packages/ui5-test-writer/src/index.ts @@ -1,13 +1,13 @@ -import { join, parse, basename } from 'path'; -import path from 'path'; +import { join, basename } from 'path'; import { create as createStorage } from 'mem-fs'; import type { Editor } from 'mem-fs-editor'; import { create } from 'mem-fs-editor'; import type { Manifest } from '@sap-ux/project-access'; import type { FEV4OPAConfig, FEV4OPAPageConfig, FEV4ManifestTarget } from './types'; -import { SupportedPageTypes, ValidationError, TestConfig } from './types'; +import { SupportedPageTypes, ValidationError, FFOPAConfig } from './types'; import { t } from './i18n'; -import fs from 'fs'; +import type { Logger } from '@sap-ux/logger'; +import { getFilePaths } from '@sap-ux/project-access'; /** * Reads the manifest for an app. @@ -270,7 +270,8 @@ export function generateOPAFiles( opaConfig: { scriptName?: string; appID?: string; htmlTarget?: string }, fs?: Editor ): Editor { - const editor = fs || create(createStorage()); + debugger; + const editor = fs ?? create(createStorage()); const manifest = readManifest(editor, basePath); const { applicationType, hideFilterBar } = getAppTypeAndHideFilterBarFromManifest(manifest); @@ -359,158 +360,145 @@ export function generatePageObjectFile( return editor; } -function writeOPAPackageJsonUpdates(fsEditor: Editor, destinationRoot: string, hasData: boolean): void { - const ui5MockYamlScript = hasData ? '--config ./ui5-mock.yaml ' : ''; - const scripts = { - 'unit-tests': `fiori run ${ui5MockYamlScript}--open 'test/unit/unitTests.qunit.html'`, - - 'int-tests': `fiori run ${ui5MockYamlScript}--open 'test/integration/opaTests.qunit.html'` - }; - - fsEditor.extendJSON(join(destinationRoot, 'package.json'), { scripts }); -} - -export function writeOPATsconfigJsonUpdates(fsEditor: Editor, destinationRoot: string): void { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const tsconfig: any = fsEditor.readJSON(join(destinationRoot, 'tsconfig.json')); - if (tsconfig.compilerOptions === undefined) { - tsconfig.compilerOptions = {}; - } - if (tsconfig.compilerOptions.paths === undefined) { - tsconfig.compilerOptions.paths = {}; +/** + * Updates tsconfig.json to include paths for unit and integration tests. + * @param {Editor} fs - The file system editor instance. + * @param {string} destinationRoot - The root directory where tsconfig.json exists. + */ +function writeOPATsconfigJsonUpdates(fs: Editor, destinationRoot: string, log?: Logger): void { + try { + const tsconfig:any = fs.readJSON(join(destinationRoot, 'tsconfig.json')) ?? {}; + + tsconfig.compilerOptions = tsconfig.compilerOptions || {}; + tsconfig.compilerOptions.paths = tsconfig.compilerOptions.paths || {}; + + tsconfig.compilerOptions.paths['unit/*'] = ['./webapp/test/unit/*']; + tsconfig.compilerOptions.paths['integration/*'] = ['./webapp/test/integration/*']; + + fs.writeJSON(join(destinationRoot, 'tsconfig.json'), tsconfig); + } catch (error) { + log?.error(`Error updating tsconfig.json: ${error}`); } - tsconfig.compilerOptions.paths['unit/*'] = ['./webapp/test/unit/*']; - tsconfig.compilerOptions.paths['integration/*'] = ['./webapp/test/integration/*']; - - fsEditor.writeJSON(join(destinationRoot, 'tsconfig.json'), tsconfig); } -const getAllFiles = (dir: any): string[] | [] => - fs?.readdirSync(dir).reduce((files: any, file: string) => { - const name = path.join(dir, file); - const isDirectory = fs?.statSync(name).isDirectory(); - return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name]; - }, -[]); - - /** - * Generates and copies freestyle test files based on configuration + * Formats a namespace by replacing dots with slashes. + * @param {string} namespace - The namespace to format. + * @returns {string} - Formatted namespace. */ -export function generateFreestyleTestFiles( - basePath: string, - config: TestConfig, - fsEditor?: Editor -): Editor { - const editor: Editor = fsEditor ?? create(createStorage()); - const { appIdWithSlash, enableTypeScript, ui5Version } = config; - - const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/simple/webapp/test', ui5Version); - console.log(" --- freestyleTemplateDirPath: ", freestyleTemplateDirPath); - const testOutDirPath = join(basePath, 'webapp/test'); +function formatNamespace(namespace: string): string { + return namespace.replace(/\./g, '/'); +} - // get test config - const viewNamePage = `${config.viewName}Page`; +/** + * Copies filtered test template files from source directory to destination directory, + * with file renaming logic based on the view name. + * + * @param {string} freestyleTemplateDirPath - The path to the source directory containing template files. + * @param {string} testOutDirPath - The path to the destination directory where files should be copied. + * @param {string[]} filteredFiles - An array of filtered file paths to copy. + * @param {TestConfig} testConfig - The test configuration object to write into template files. + * @param {Editor} editor - The editor instance used to copy and render template files. + * @param {Logger} [log] - The logger instance. + * + * @returns {Promise} - A promise that resolves to `true` if the files were copied successfully, + * or `false` if there was an error during the process. + * + */ +async function copyTestFiles( + freestyleTemplateDirPath: string, + testOutDirPath: string, + filteredFiles: string[], + opaConfig: FFOPAConfig, + editor: Editor, + log?: Logger +): Promise { + try { + filteredFiles.forEach((filePath: string) => { + const sourceFilePath = join(freestyleTemplateDirPath, filePath); + let destinationFilePath = join(testOutDirPath, filePath); + const viewName = opaConfig.viewName; + + // Rename files: + // - viewName.js files are renamed to include the view name in their file path + // - viewName.ts files are renamed with the view name appended with 'Page' + const renameMap: Record = { + '/integration/pages/viewName.js': `integration/pages/${viewName}.js`, + '/integration/pages/viewName.ts': `integration/pages/${viewName}Page.ts`, + '/unit/controller/viewName.controller.js': `unit/controller/${viewName}.controller.js`, + '/unit/controller/viewName.controller.ts': `unit/controller/${viewName}Page.controller.ts` + }; + + if (renameMap[filePath]) { + destinationFilePath = join(testOutDirPath, renameMap[filePath]); + } - // Get all template files - const allTemplateFiles = getAllFiles(freestyleTemplateDirPath); + editor.copyTpl(sourceFilePath, destinationFilePath, { ...opaConfig, formatNamespace }, undefined, { + globOptions: { dot: true } + }); + }); - const typeScript = enableTypeScript === undefined ? false : true; - // Filter files based on TypeScript setting - const filteredFiles = allTemplateFiles.filter(filePath => { - if (filePath.endsWith('.ts')) { - return typeScript === true; - } else if (filePath.endsWith('.js')) { - return typeScript === false; - } return true; - }).map(filePath => { - // Transform the file path to the relative path - const relativePath: string = filePath.replace(freestyleTemplateDirPath, ''); - return relativePath; - }); - console.log(" --- filteredFiles: ", filteredFiles); - - const testConfig = { - ...config, - viewNamePage, - appIdWithSlash: appIdWithSlash - }; - - console.log(" -- testConfig: ", testConfig); - - function processDestinationPath(filePath: string): string { - //return filePath.replace('/1.120.0', '').replace('/1.71.0', ''); - //console.log(" --- filePath: ", filePath); - if(filePath === '/integration/pages/viewName.js'){ - return filePath.replace(/viewName/g, 'KITTY'); - } - return filePath; + } catch (error) { + log?.error(`Error copying files: ${error}`); + return false; } +} - - - // Copy each filtered file using copyTpl - console.log(" ---join(freestyleTemplateDirPath, '*.*')", join(freestyleTemplateDirPath, '*.*')) - console.log(" ---to join(testOutDirPath, 'integration')", testOutDirPath) - // editor.copyTpl(join(freestyleTemplateDirPath, '**', '*.*'), testOutDirPath, testConfig, undefined, { - // globOptions: { dot: true }, - // processDestinationPath: processDestinationPath - // }); - - // Iterate through the filtered files and copy each one - filteredFiles.forEach((filePath: string) => { - // If the file is 'integration/page/viewName.js', rename it to 'integration/page/kitty.js' - let sourceFilePath = join(freestyleTemplateDirPath, filePath); - let destinationFilePath = join(testOutDirPath, filePath); - - // Check if the file is 'integration/page/viewName.js' - if (filePath === '/integration/pages/viewName.js') { - - // Change the file name to 'kitty.js' - destinationFilePath = join(testOutDirPath, `integration/pages/${config.viewName}.js`); - console.log(" --- match found --- ", destinationFilePath) - } +/** + * Generates and copies freestyle test files based on configuration. + * @param {string} basePath - The base directory path. + * @param {object} config - Configuration object. + * @param {Editor} fs - Optional file system editor instance. + * @returns {Editor} - The modified file system editor. + */ +export async function generateFreestyleOPAFiles( + basePath: string, + opaConfig: FFOPAConfig, + fs?: Editor, + log?: Logger +): Promise { + const fsEditor = fs ?? create(createStorage()); + const { appIdWithSlash, enableTypeScript, ui5Version, viewName } = opaConfig; + const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/webapp/test'); + const testOutDirPath = join(basePath, 'webapp/test'); - if (filePath === '/unit/controller/viewName.controller.js') { - - // Change the file name to 'kitty.js' - destinationFilePath = join(testOutDirPath, `unit/controller/${config.viewName}.controller.js`); - console.log(" --- match found --- ", destinationFilePath) - } - - // Copy the file using editor.copyTpl - editor.copyTpl( - sourceFilePath, // Source file path (no change) - destinationFilePath, // Destination file path (changed if necessary) - testConfig, // Configuration for the template - undefined, // Additional options if needed - { - globOptions: { dot: true }, // Glob options if needed - // processDestinationPath: processDestinationPath // Apply the custom path processing if needed + // Get template files + const templateFiles = await getFilePaths(freestyleTemplateDirPath); + const isTypeScript = Boolean(enableTypeScript); + const commonJSTemplateFiles = ['initFlpSandbox.js', 'flpSandbox.js']; + + // Filter files based on TypeScript setting: + // - If TypeScript is enabled, include only .ts files + // - If TypeScript is disabled, include only .js files + // - Include common JS files regardless of TypeScript setting + const filteredFiles = templateFiles + .filter((filePath: string) => { + if (filePath.endsWith('.ts')) return isTypeScript; + if (filePath.endsWith('.js')) { + const includeCommonJSTemplate = commonJSTemplateFiles.includes(basename(filePath)) && (ui5Version === '1.71.0'); + return !isTypeScript || includeCommonJSTemplate; } - ); - }); + return true; // keep other .html files + }) + .map((filePath: string) => filePath.replace(freestyleTemplateDirPath, '')); - - // filteredFiles.forEach((filePath: string) => { - // debugger; - // const relativePath: string = filePath.replace(freestyleTemplateDirPath, ''); - // console.log(" --- relativePath: ", relativePath); - - // editor.copyTpl(filePath, join(testOutDirPath, relativePath), testConfig, undefined, { - // processDestinationPath: processDestinationPath - // }); - // }); - - // Update package.json scripts - writeOPAPackageJsonUpdates(editor, basePath, config.hasData ?? false); - // Update tsconfig.json if TypeScript is enabled - if (config.enableTypeScript) { - writeOPATsconfigJsonUpdates(editor, basePath); + const config = { + ...opaConfig, + viewNamePage: `${viewName}Page`, + appIdWithSlash, + ui5Version, + navigationIntent: ( + '' + opaConfig.appId + ).replace(new RegExp('\\.|/|\\\\|-|\\s', 'g'), '') + }; + const filesCopiedSuccessfully = await copyTestFiles(freestyleTemplateDirPath, testOutDirPath, filteredFiles, config, fsEditor, log); + + // If files are copied successfully, update the package.json and tsconfig files + if (filesCopiedSuccessfully && isTypeScript) { + writeOPATsconfigJsonUpdates(fsEditor, basePath, log); } - return editor; + return fsEditor; } - diff --git a/packages/ui5-test-writer/src/types.ts b/packages/ui5-test-writer/src/types.ts index a043703158..b0b0d91fd2 100644 --- a/packages/ui5-test-writer/src/types.ts +++ b/packages/ui5-test-writer/src/types.ts @@ -60,18 +60,15 @@ export class ValidationError extends Error { } /** - * Configuration interface for generating test files + * Configuration interface for generating freestyle OPA test files */ -export interface TestConfig { +export interface FFOPAConfig { appId: string; appIdWithSlash: string; applicationTitle?: string; applicationDescription?: string; - navigationIntent?: string; - ui5Theme?: string; enableTypeScript?: boolean; - hasData?: boolean; viewName?: string; - viewNamePage?: string; ui5Version: string; -} \ No newline at end of file + ui5Theme?: string; +} From 9e2a63660b03a25312ff80068e5f39ddb0f02010 Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 14 Feb 2025 15:47:24 +0000 Subject: [PATCH 07/42] add ejs templates --- .../src/writeTestFiles.ts | 67 +++++++ packages/ui5-test-writer/src/index.ts | 8 +- .../templates/common/testsuite.qunit.html | 16 +- .../templates/common/testsuite.qunit.js | 18 +- .../templates/freestyle/model.json | 164 ++++++++++++++++++ .../freestyle/webapp/test/flpSandbox.js | 100 +++++++++++ .../freestyle/webapp/test/initFlpSandbox.js | 13 ++ .../webapp/test/integration/AllJourneys.js | 13 ++ .../test/integration/NavigationJourney.js | 23 +++ .../test/integration/NavigationJourney.ts | 34 ++++ .../test/integration/arrangements/Startup.js | 25 +++ .../test/integration/opaTests.qunit.html | 30 ++++ .../webapp/test/integration/opaTests.qunit.js | 7 + .../webapp/test/integration/opaTests.qunit.ts | 17 ++ .../webapp/test/integration/pages/App.js | 28 +++ .../webapp/test/integration/pages/AppPage.ts | 22 +++ .../webapp/test/integration/pages/viewName.js | 28 +++ .../webapp/test/integration/pages/viewName.ts | 23 +++ .../freestyle/webapp/test/testsuite.qunit.ts | 14 ++ .../freestyle/webapp/test/unit/AllTests.js | 5 + .../unit/controller/viewName.controller.js | 16 ++ .../unit/controller/viewName.controller.ts | 10 ++ .../webapp/test/unit/unitTests.qunit.html | 29 ++++ .../webapp/test/unit/unitTests.qunit.js | 12 ++ .../webapp/test/unit/unitTests.qunit.ts | 21 +++ 25 files changed, 728 insertions(+), 15 deletions(-) create mode 100644 packages/fiori-freestyle-writer/src/writeTestFiles.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/model.json create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/initFlpSandbox.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/AllJourneys.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/arrangements/Startup.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.html create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/App.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/AppPage.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/unit/AllTests.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.html create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts diff --git a/packages/fiori-freestyle-writer/src/writeTestFiles.ts b/packages/fiori-freestyle-writer/src/writeTestFiles.ts new file mode 100644 index 0000000000..6545fcbec0 --- /dev/null +++ b/packages/fiori-freestyle-writer/src/writeTestFiles.ts @@ -0,0 +1,67 @@ +import { generateFreestyleOPAFiles } from '../../ui5-test-writer'; +import { compareUI5VersionGte, ui5LtsVersion_1_71 } from '@sap-ux/ui5-application-writer'; +import { FreestyleApp } from './types'; +import type { Editor } from 'mem-fs-editor'; +import type { BasicAppSettings } from './types'; +import type { Logger } from '@sap-ux/logger'; + +/** + * Generates formatted application ID with slashes based on namespace, name, and TypeScript settings. + * @param {string} [name] - The application name. + * @param {string} [namespace] - The application namespace. + * @param {boolean} [enableTypescript] - Whether TypeScript is enabled. + * @returns {string} The formatted application ID with slashes. + */ +function formatAppId(name?: string, namespace?: string, enableTypescript?: boolean): string { + const sanitizeNamespace = (namespace?: string) => { + if (!namespace) return ''; + // Replace dots with slashes and remove trailing slashes + return namespace.replace(/\./g, '/').replace(/\/$/, ''); + }; + + const sanitizeName = (name?: string) => { + // If the name is defined, remove underscores and hyphens, else return an empty string + return name ? name.replace(/[_-]/g, '') : ''; + }; + + if (enableTypescript) { + const sanitizedNamespace = sanitizeNamespace(namespace); + const sanitizedName = sanitizeName(name); + // If TypeScript is enabled, Return formatted appId with slashes, ensuring no unnecessary slashes at the end + return `${sanitizedNamespace}${sanitizedNamespace && sanitizedName ? '/' : ''}${sanitizedName}`; + } else { + const sanitizedNamespace = sanitizeNamespace(namespace).replace(/\//g, ''); + const sanitizedName = name ?? ''; + // Return formatted appId without slashes in the namespace, adding a slash between namespace and name + return `${sanitizedNamespace}${sanitizedNamespace && sanitizedName ? '/' : ''}${sanitizedName}`; + } +} + +/** + * Generates and writes UI5 test files based on the provided application configuration. + * @template T + * @param {string} basePath - The base path where test files will be generated. + * @param {FreestyleApp} ffApp - The freestyle application configuration. + * @param {Editor} [fs] - The file system editor instance. + * @param {Logger} [log] - The logger instance. + */ +export async function writeTestFiles(basePath: string, ffApp: FreestyleApp, fs?: Editor, log?: Logger): Promise { + const templateLtsVersion_1_120 = '1.120.0'; + const templateUi5Version = ffApp.ui5?.version + ? compareUI5VersionGte(ffApp.ui5.version, templateLtsVersion_1_120) + ? templateLtsVersion_1_120 + : ui5LtsVersion_1_71 + : templateLtsVersion_1_120; + + const config = { + appId: ffApp.app.id, + viewName: (ffApp.template.settings as BasicAppSettings).viewName, + ui5Theme: ffApp.ui5?.ui5Theme, + ui5Version: templateUi5Version, + applicationTitle: ffApp.app.title, + applicationDescription: ffApp.app.description, + appIdWithSlash: formatAppId(ffApp.package.name, ffApp.app.namespace, ffApp.appOptions?.typescript), + enableTypeScript: ffApp.appOptions?.typescript + }; + await generateFreestyleOPAFiles(basePath, config, fs, log); +} \ No newline at end of file diff --git a/packages/ui5-test-writer/src/index.ts b/packages/ui5-test-writer/src/index.ts index ad279712de..e2fd2673f3 100644 --- a/packages/ui5-test-writer/src/index.ts +++ b/packages/ui5-test-writer/src/index.ts @@ -432,11 +432,17 @@ async function copyTestFiles( if (renameMap[filePath]) { destinationFilePath = join(testOutDirPath, renameMap[filePath]); } - editor.copyTpl(sourceFilePath, destinationFilePath, { ...opaConfig, formatNamespace }, undefined, { globOptions: { dot: true } }); }); + const rootCommonTemplateDirPath = join(__dirname, '../templates/common'); + editor.copyTpl(rootCommonTemplateDirPath, testOutDirPath, { + appId: opaConfig.appId, + addUnitTests: true + }, undefined, { + globOptions: { dot: true } + }); return true; } catch (error) { diff --git a/packages/ui5-test-writer/templates/common/testsuite.qunit.html b/packages/ui5-test-writer/templates/common/testsuite.qunit.html index 1fea4a26d9..850363da67 100644 --- a/packages/ui5-test-writer/templates/common/testsuite.qunit.html +++ b/packages/ui5-test-writer/templates/common/testsuite.qunit.html @@ -1,9 +1,11 @@ - - QUnit test suite - - - - - \ No newline at end of file + + + QUnit test suite for <%= appId %> + + + + + + diff --git a/packages/ui5-test-writer/templates/common/testsuite.qunit.js b/packages/ui5-test-writer/templates/common/testsuite.qunit.js index a37a5c973c..9558583ab0 100644 --- a/packages/ui5-test-writer/templates/common/testsuite.qunit.js +++ b/packages/ui5-test-writer/templates/common/testsuite.qunit.js @@ -1,11 +1,15 @@ +<% if (addUnitTests) { %>/* global window, parent, location */ + +// eslint-disable-next-line fiori-custom/sap-no-global-define<% } %> window.suite = function() { - 'use strict'; + "use strict"; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + <% if (addUnitTests === true) { %>oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html");<% } %> + oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); - return oSuite; + return oSuite; }; \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/model.json b/packages/ui5-test-writer/templates/freestyle/model.json new file mode 100644 index 0000000000..0231282c2f --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/model.json @@ -0,0 +1,164 @@ +{ + "neoapp": { + "welcomeFile": "/webapp/test/flpSandbox.html", + "sendWelcomeFileRedirect": true + }, + "datasource": { + "type": "odata", + "url": "" + }, + "simple": { + "environment": { + "internal": "false", + "resourcePath": "" + }, + "parameters": { + "ManifestVersion": { + "value": "" + }, + "ui5Version": { + "value": "" + }, + "ProjectName": { + "value": "" + }, + "AppId": { + "value": "" + }, + "ViewName": { + "value": "" + }, + "ViewNamePage": { + "value": "" + }, + "UI5Theme": { + "value": "" + }, + "sapUiBootstrapSrcUrl": { + "value": "" + }, + "AppIdWithSlash": { + "value": "" + }, + "ApplicationNamespace": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "Namespace" + }, + "wizard": { + "control": "TextField", + "regExp": "^[a-z][a-z 0-9]*(?:\\.[a-z][a-z 0-9]*)*$", + "required": true, + "title": "Namespace", + "regExpErrorMsg": "A namespace must not start with a digit. After the first character you may use any alphanumeric character or number separated by dots. Two successive dots are also forbidden. A namespace must not end with a dot." + } + }, + "ApplicationTitle": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "sap.app.title" + }, + "wizard": { + "control": "TextField", + "required": true, + "title": "Title", + "regExp": "^[\\w][\\w\\.\\-\\ ]*$" + } + }, + "ApplicationDescription": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "sap.app.description" + }, + "wizard": { + "control": "TextField", + "required": false, + "title": "Description" + } + }, + "FioriID": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "sap.fiori.registrationIds" + }, + "wizard": { + "control": "TextField", + "required": false, + "title": "SAP Fiori ID", + "internalOnly": true + } + }, + "ApplicationComponentHierarchy": { + "type": "string", + "value": "", + "appDescriptor": { + "id": "sap.app.ach" + }, + "wizard": { + "control": "TextField", + "required": false, + "title": "Application Component Hierarchy", + "internalOnly": true + } + }, + "FLP": { + "type": "Entity", + "multiplicity": "many", + "isRoot": true, + "binding": [ + { + "name": "SAP Fiori Launchpad Component (optimized for SAP Fiori Launchpad registration)", + "value": true + }, + { + "name": "Standalone App (optimized for individual deployment)", + "value": false + } + ], + "value": "", + "wizard": { + "control": "ComboBox", + "required": true, + "title": "App Type", + "tooltip": "Choose if your app should run in SAP Fiori Launchpad or standalone" + } + }, + "DefineReplacement": { + "type": "string", + "value": "" + } + }, + "forms": [ + { + "type": "appDescriptorGenericStep", + "groups": [ + { + "parameters": [ + "@simple.parameters.ApplicationTitle", + "@simple.parameters.ApplicationNamespace", + "@simple.parameters.ApplicationDescription", + "@simple.parameters.ApplicationComponentHierarchy", + "@simple.parameters.FioriID" + ] + } + ] + }, + { + "groups": [ + { + "title": "Application Scenario", + "parameters": ["@simple.parameters.FLP"] + }, + { + "title": "Data Binding", + "parameters": [] + } + ] + } + ] + } +} diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js new file mode 100644 index 0000000000..db155979e7 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js @@ -0,0 +1,100 @@ +sap.ui.define([ + "sap/base/util/ObjectPath", + "sap/ushell/services/Container" +], function (ObjectPath) { + "use strict"; + + // define ushell config + ObjectPath.set(["sap-ushell-config"], { + defaultRenderer: "fiori2", + bootstrapPlugins: { + "RuntimeAuthoringPlugin": { + component: "sap.ushell.plugins.rta", + config: { + validateAppVersion: false + } + }, + "PersonalizePlugin": { + component: "sap.ushell.plugins.rta-personalize", + config: { + validateAppVersion: false + } + } + }, + renderers: { + fiori2: { + componentData: { + config: { + enableSearch: false, + rootIntent: "Shell-home" + } + } + } + }, + services: { + "LaunchPage": { + "adapter": { + "config": { + "groups": [{ + "tiles": [{ + "tileType": "sap.ushell.ui.tile.StaticTile", + "properties": { + <% if (applicationTitle) { %>"title": "<%= applicationTitle %>",<% } %> + "targetURL": "#<%= navigationIntent %>-display" + } + }] + }] + } + } + }, + "ClientSideTargetResolution": { + "adapter": { + "config": { + "inbounds": { + "<%= navigationIntent %>-display": { + "semanticObject": "<%= navigationIntent %>", + "action": "display", + <% if (applicationDescription) { %>"description": "<%= applicationDescription %>",<% } %><% if (applicationTitle) { %> + "title": "<%= applicationTitle %>",<% } %> + "signature": { + "parameters": {} + }, + "resolutionResult": { + "applicationType": "SAPUI5", + "additionalInformation": "SAPUI5.Component=<%= appId %>", + "url": sap.ui.require.toUrl("<%= formatNamespace(appId) %>") + } + } + } + } + } + }, + NavTargetResolution: { + config: { + "enableClientSideTargetResolution": true + } + } + } + }); + + var oFlpSandbox = { + init: function () { + /** + * Initializes the FLP sandbox + * @returns {Promise} a promise that is resolved when the sandbox bootstrap has finshed + */ + + // sandbox is a singleton, so we can start it only once + if (!this._oBootstrapFinished) { + this._oBootstrapFinished = sap.ushell.bootstrap("local"); + this._oBootstrapFinished.then(function () { + sap.ushell.Container.createRenderer().placeAt("content"); + }); + } + + return this._oBootstrapFinished; + } + }; + + return oFlpSandbox; +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/initFlpSandbox.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/initFlpSandbox.js new file mode 100644 index 0000000000..7a8f6bcfba --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/initFlpSandbox.js @@ -0,0 +1,13 @@ +sap.ui.define([ + "./flpSandbox", + "sap/ui/fl/FakeLrepConnectorLocalStorage", + "sap/m/MessageBox" +], function (flpSandbox, FakeLrepConnectorLocalStorage, MessageBox) { + "use strict"; + + flpSandbox.init().then(function () { + FakeLrepConnectorLocalStorage.enableFakeConnector(); + }, function (oError) { + MessageBox.error(oError.message); + }); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/AllJourneys.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/AllJourneys.js new file mode 100644 index 0000000000..b630e2f815 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/AllJourneys.js @@ -0,0 +1,13 @@ +sap.ui.define([ + "sap/ui/test/Opa5", + "./arrangements/Startup", + "./NavigationJourney" +], function (Opa5, Startup) { + "use strict"; + + Opa5.extendConfig({ + arrangements: new Startup(), + viewNamespace: "<%= appId %>.view.", + autoWait: true + }); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.js new file mode 100644 index 0000000000..fe45eabd01 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.js @@ -0,0 +1,23 @@ +/*global QUnit*/ + +sap.ui.define([ + "sap/ui/test/opaQunit", + "./pages/App", + "./pages/<%= viewName %>" +], function (opaTest) { + "use strict"; + + QUnit.module("Navigation Journey"); + + opaTest("Should see the initial page of the app", function (Given, When, Then) { + // Arrangements + Given.iStartMyApp(); + + // Assertions + Then.onTheAppPage.iShouldSeeTheApp(); + Then.onTheViewPage.iShouldSeeThePageView(); + + //Cleanup + Then.iTeardownMyApp(); + }); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.ts new file mode 100644 index 0000000000..579638030b --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.ts @@ -0,0 +1,34 @@ +/*global QUnit*/ +import opaTest from "sap/ui/test/opaQunit"; +import AppPage from "./pages/AppPage"; +import ViewPage from "./pages/<%= viewName %>Page"; + +import Opa5 from "sap/ui/test/Opa5"; + +QUnit.module("Navigation Journey"); + +const onTheAppPage = new AppPage(); +const onTheViewPage = new ViewPage(); +Opa5.extendConfig({ + viewNamespace: "<%= appId %>.view.", + autoWait: true +}); + +opaTest("Should see the initial page of the app", function () { + // Arrangements + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iStartMyUIComponent({ + componentConfig: { + name: "<%= appId %>" + } + }); + + // Assertions + onTheAppPage.iShouldSeeTheApp(); + onTheViewPage.iShouldSeeThePageView(); + + + // Cleanup + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iTeardownMyApp(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/arrangements/Startup.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/arrangements/Startup.js new file mode 100644 index 0000000000..9127906862 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/arrangements/Startup.js @@ -0,0 +1,25 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + + return Opa5.extend("integration.arrangements.Startup", { + + iStartMyApp: function (oOptionsParameter) { + var oOptions = oOptionsParameter || {}; + + // start the app with a minimal delay to make tests fast but still async to discover basic timing issues + oOptions.delay = oOptions.delay || 50; + + // start the app UI component + this.iStartMyUIComponent({ + componentConfig: { + name: "<%= appId %>", + async: true + }, + hash: oOptions.hash, + autoWait: oOptions.autoWait + }); + } + }); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.html b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.html new file mode 100644 index 0000000000..f9ffa7ff57 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.html @@ -0,0 +1,30 @@ + + + + + Integration tests for Basic Template + + + + + +<% if (ui5Version !== "1.71.0") { %><% } -%> + + +
+
+ + diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js new file mode 100644 index 0000000000..4cae4b312f --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js @@ -0,0 +1,7 @@ +/* global QUnit */ + +sap.ui.require(["<%= formatNamespace(appId) %>/test/integration/AllJourneys" +], function () { + QUnit.config.autostart = false; + QUnit.start(); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.ts new file mode 100644 index 0000000000..645989fec8 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.ts @@ -0,0 +1,17 @@ +/* global QUnit */ +<% if (ui5Version === '1.71.0') { -%> +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +// import all your OPA journeys here +void Promise.all([ + import("integration/NavigationJourney") +]).then(() => { + QUnit.start(); +}); +<% } else { -%> +sap.ui.require(["integration/NavigationJourney" +], function () { + QUnit.config.autostart = false; + QUnit.start(); +});<% } %> \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/App.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/App.js new file mode 100644 index 0000000000..db276e3fd4 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/App.js @@ -0,0 +1,28 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + var sViewName = "App"; + + Opa5.createPageObjects({ + onTheAppPage: { + + actions: {}, + + assertions: { + + iShouldSeeTheApp: function () { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/AppPage.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/AppPage.ts new file mode 100644 index 0000000000..8cb42d2a57 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/AppPage.ts @@ -0,0 +1,22 @@ +import Opa5 from "sap/ui/test/Opa5"; + +const sViewName = "App"; + +export default class AppPage extends Opa5 { + // Actions + + + // Assertions + iShouldSeeTheApp() { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + +} + diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.js new file mode 100644 index 0000000000..99a42c95d6 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.js @@ -0,0 +1,28 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + var sViewName = "<%= viewName %>"; + + Opa5.createPageObjects({ + onTheViewPage: { + + actions: {}, + + assertions: { + + iShouldSeeThePageView: function () { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.ts new file mode 100644 index 0000000000..b27e2a2305 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.ts @@ -0,0 +1,23 @@ +import Opa5 from "sap/ui/test/Opa5"; + +const sViewName = "<%= viewName %>"; + +export default class <%= viewNamePage %> extends Opa5 { + // Actions + + + // Assertions + iShouldSeeThePageView() { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + +} + + diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.ts new file mode 100644 index 0000000000..61446459d1 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.ts @@ -0,0 +1,14 @@ +/* global window, parent, location */ + +// eslint-disable-next-line fiori-custom/sap-no-global-define,@typescript-eslint/ban-ts-comment +// @ts-nocheck +window.suite = function() { + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + + oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); + oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); + + return oSuite; +}; diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/AllTests.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/AllTests.js new file mode 100644 index 0000000000..7b5c8a4ad2 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/AllTests.js @@ -0,0 +1,5 @@ +sap.ui.define([ + "<%= appIdWithSlash %>/test/unit/controller/<%= viewName %>.controller" +], function () { + "use strict"; +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.js new file mode 100644 index 0000000000..de22944c10 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.js @@ -0,0 +1,16 @@ +/*global QUnit*/ + +sap.ui.define([ + "<%= appIdWithSlash %>/controller/<%= viewName %>.controller" +], function (Controller) { + "use strict"; + + QUnit.module("<%= viewName %> Controller"); + + QUnit.test("I should test the <%= viewName %> controller", function (assert) { + var oAppController = new Controller(); + oAppController.onInit(); + assert.ok(oAppController); + }); + +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.ts new file mode 100644 index 0000000000..658f1164e3 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.ts @@ -0,0 +1,10 @@ +/*global QUnit*/ +import Controller from "<%= appIdWithSlash %>/controller/<%= viewName %>.controller"; + +QUnit.module("<%= viewName %> Controller"); + +QUnit.test("I should test the <%= viewName %> controller", function (assert: Assert) { + const oAppController = new Controller("<%= viewName %>"); + oAppController.onInit(); + assert.ok(oAppController); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.html b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.html new file mode 100644 index 0000000000..6cb13cf3f1 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.html @@ -0,0 +1,29 @@ + + + + + Unit tests for <%= appId %> + + + + + + + +<% if (ui5Version !== "1.71.0") { -%> +<% } -%> + + +
+
+ + diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.js new file mode 100644 index 0000000000..0e148cc2ad --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.js @@ -0,0 +1,12 @@ +/* global QUnit */ +QUnit.config.autostart = false; + +sap.ui.getCore().attachInit(function () { + "use strict"; + + sap.ui.require([ + "<%= appIdWithSlash %>/test/unit/AllTests" + ], function () { + QUnit.start(); + }); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts new file mode 100644 index 0000000000..c5813167d7 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts @@ -0,0 +1,21 @@ +<% if (ui5Version === "1.71.0") { -%> +/* global QUnit */ +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +// import all your QUnit tests here +void Promise.all([ + import("unit/controller/<%= viewName %>Page.controller") +]).then(() => { + QUnit.start(); +});<% } else if (ui5Version === "1.120.0") { -%> +/* @sapUiRequire */ +QUnit.config.autostart = false; + +// import all your QUnit tests here +void Promise.all([ + import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests + import("unit/controller/<%= viewName %>Page.controller") +]).then(([{ default: Core }]) => Core.ready()).then(() => { + QUnit.start(); +});<% } %> \ No newline at end of file From 285aacfd6d2632833f90a45865b18b5ae4116ba9 Mon Sep 17 00:00:00 2001 From: I743583 Date: Mon, 17 Feb 2025 12:17:18 +0000 Subject: [PATCH 08/42] clean code --- packages/fiori-elements-writer/src/index.ts | 4 +- packages/fiori-freestyle-writer/src/index.ts | 51 +- packages/fiori-freestyle-writer/src/types.ts | 2 +- .../src/writeTestFiles.ts | 67 --- .../npm-package-scripts/getPackageScripts.ts | 7 +- .../src/npm-package-scripts/types.ts | 4 +- packages/ui5-test-writer/package.json | 3 +- .../src/fiori-elements-opa-writer.ts | 357 ++++++++++++ .../src/fiori-freestyle-opa-writer.ts | 233 ++++++++ packages/ui5-test-writer/src/index.ts | 512 +----------------- .../translations/ui5-test-writer.i18n.json | 3 +- packages/ui5-test-writer/src/types.ts | 4 +- .../templates/common/testsuite.qunit.js | 5 +- .../freestyle/webapp/test/testsuite.qunit.ts | 2 +- .../webapp/test/unit/unitTests.qunit.ts | 18 +- packages/ui5-test-writer/tsconfig.json | 29 +- pnpm-lock.yaml | 3 + 17 files changed, 677 insertions(+), 627 deletions(-) delete mode 100644 packages/fiori-freestyle-writer/src/writeTestFiles.ts create mode 100644 packages/ui5-test-writer/src/fiori-elements-opa-writer.ts create mode 100644 packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts diff --git a/packages/fiori-elements-writer/src/index.ts b/packages/fiori-elements-writer/src/index.ts index 0159545e30..2467f96bfa 100644 --- a/packages/fiori-elements-writer/src/index.ts +++ b/packages/fiori-elements-writer/src/index.ts @@ -4,7 +4,7 @@ import { render } from 'ejs'; import type { App, Package } from '@sap-ux/ui5-application-writer'; import { generate as generateUi5Project } from '@sap-ux/ui5-application-writer'; import { generate as addOdataService, OdataVersion, ServiceType } from '@sap-ux/odata-service-writer'; -import { generateOPAFiles } from '@sap-ux/ui5-test-writer'; +import { generateFioriElementsOPAFiles } from '@sap-ux/ui5-test-writer'; import cloneDeep from 'lodash/cloneDeep'; import type { FioriElementsApp } from './types'; import { TemplateType } from './types'; @@ -206,7 +206,7 @@ async function generate( fs.writeJSON(packagePath, packageJson); if (addTest) { - generateOPAFiles( + generateFioriElementsOPAFiles( basePath, { htmlTarget: feApp.appOptions?.generateIndex diff --git a/packages/fiori-freestyle-writer/src/index.ts b/packages/fiori-freestyle-writer/src/index.ts index 5db62396b2..76a046e404 100644 --- a/packages/fiori-freestyle-writer/src/index.ts +++ b/packages/fiori-freestyle-writer/src/index.ts @@ -13,8 +13,36 @@ import { initI18n } from './i18n'; import { getBootstrapResourceUrls, getPackageScripts } from '@sap-ux/fiori-generator-shared'; import { getTemplateVersionPath, processDestinationPath } from './utils'; import { applyCAPUpdates, type CapProjectSettings } from '@sap-ux/cap-config-writer'; -import { writeTestFiles } from './writeTestFiles'; import type { Logger } from '@sap-ux/logger'; +import { generateFreestyleOPAFiles } from '../../ui5-test-writer'; + +/** + * Generates and writes OPA test files based on the provided application configuration. + * + * @template T + * @param {string} basePath - The base path where test files will be generated. + * @param {FreestyleApp} ffApp - The freestyle application configuration. + * @param {Editor} [fs] - The file system editor instance. + * @param {Logger} [log] - The logger instance. + */ +export async function writeOPATestFiles( + basePath: string, + ffApp: FreestyleApp, + fs?: Editor, + log?: Logger +): Promise { + const config = { + appId: ffApp.app.id, + applicationDescription: ffApp.app.description, + applicationTitle: ffApp.app.title, + namespace: ffApp.app.namespace, + viewName: (ffApp.template.settings as BasicAppSettings).viewName, + ui5Theme: ffApp.ui5?.ui5Theme, + ui5Version: ffApp.ui5?.version, + enableTypeScript: ffApp.appOptions?.typescript + }; + await generateFreestyleOPAFiles(basePath, config, fs, log); +} /** * Generate a UI5 application based on the specified Fiori Freestyle floorplan template. @@ -22,6 +50,7 @@ import type { Logger } from '@sap-ux/logger'; * @param basePath - the absolute target path where the application will be generated * @param data - configuration to generate the freestyle application * @param fs - an optional reference to a mem-fs editor + * @param log - optional logger * @returns Reference to a mem-fs-editor */ async function generate(basePath: string, data: FreestyleApp, fs?: Editor, log?: Logger): Promise { @@ -139,22 +168,30 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor, const packageJson: Package = JSON.parse(fs.read(packagePath)); if (isEdmxProjectType) { + const addMock = !!ffApp.service?.metadata; // Add scripts for non-CAP applications packageJson.scripts = { ...packageJson.scripts, ...getPackageScripts({ localOnly: !!ffApp.service && !ffApp.service?.url, - addMock: !!ffApp.service?.metadata, + addMock, sapClient: ffApp.service?.client, flpAppId: ffApp.app.flpAppId, startFile: data?.app?.startFile, localStartFile: data?.app?.localStartFile, generateIndex: ffApp.appOptions?.generateIndex, - addTest: addTests, - // revist this - hasService: !!ffApp.service?.metadata + addTest: addTests }) }; + if (addTests) { + const ui5MockYamlScript = addMock ? '--config ./ui5-mock.yaml ' : ''; + // Note: 'ui5MockYamlScript' is empty when no data source is selected. + packageJson.scripts['unit-test'] = `fiori run ${ui5MockYamlScript}--open 'test/unit/unitTests.qunit.html'`; + packageJson.scripts[ + 'int-test' + ] = `fiori run ${ui5MockYamlScript}--open 'test/integration/opaTests.qunit.html'`; + await writeOPATestFiles(basePath, ffApp, fs, log); + } } else { // Add deploy-config for CAP applications packageJson.scripts = { @@ -173,10 +210,6 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor, ui5LocalConfig.addFioriToolsProxydMiddleware({}); fs.write(ui5LocalConfigPath, ui5LocalConfig.toString()); } - - if (addTests && isEdmxProjectType) { - await writeTestFiles(basePath, ffApp, fs, log); - } if (ffApp.service?.capService) { const hasCdsUi5PluginInfo = !!ffApp.service.capService.cdsUi5PluginInfo; diff --git a/packages/fiori-freestyle-writer/src/types.ts b/packages/fiori-freestyle-writer/src/types.ts index 87f3fdb94b..bdb0eda097 100644 --- a/packages/fiori-freestyle-writer/src/types.ts +++ b/packages/fiori-freestyle-writer/src/types.ts @@ -1,7 +1,7 @@ import type { Ui5App, App } from '@sap-ux/ui5-application-writer'; import type { OdataService } from '@sap-ux/odata-service-writer'; import type { CapServiceCdsInfo } from '@sap-ux/cap-config-writer'; -import { AppOptions } from '@sap-ux/ui5-application-writer'; +import type { AppOptions } from '@sap-ux/ui5-application-writer'; export const TemplateType = { Basic: 'basic', diff --git a/packages/fiori-freestyle-writer/src/writeTestFiles.ts b/packages/fiori-freestyle-writer/src/writeTestFiles.ts deleted file mode 100644 index 6545fcbec0..0000000000 --- a/packages/fiori-freestyle-writer/src/writeTestFiles.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { generateFreestyleOPAFiles } from '../../ui5-test-writer'; -import { compareUI5VersionGte, ui5LtsVersion_1_71 } from '@sap-ux/ui5-application-writer'; -import { FreestyleApp } from './types'; -import type { Editor } from 'mem-fs-editor'; -import type { BasicAppSettings } from './types'; -import type { Logger } from '@sap-ux/logger'; - -/** - * Generates formatted application ID with slashes based on namespace, name, and TypeScript settings. - * @param {string} [name] - The application name. - * @param {string} [namespace] - The application namespace. - * @param {boolean} [enableTypescript] - Whether TypeScript is enabled. - * @returns {string} The formatted application ID with slashes. - */ -function formatAppId(name?: string, namespace?: string, enableTypescript?: boolean): string { - const sanitizeNamespace = (namespace?: string) => { - if (!namespace) return ''; - // Replace dots with slashes and remove trailing slashes - return namespace.replace(/\./g, '/').replace(/\/$/, ''); - }; - - const sanitizeName = (name?: string) => { - // If the name is defined, remove underscores and hyphens, else return an empty string - return name ? name.replace(/[_-]/g, '') : ''; - }; - - if (enableTypescript) { - const sanitizedNamespace = sanitizeNamespace(namespace); - const sanitizedName = sanitizeName(name); - // If TypeScript is enabled, Return formatted appId with slashes, ensuring no unnecessary slashes at the end - return `${sanitizedNamespace}${sanitizedNamespace && sanitizedName ? '/' : ''}${sanitizedName}`; - } else { - const sanitizedNamespace = sanitizeNamespace(namespace).replace(/\//g, ''); - const sanitizedName = name ?? ''; - // Return formatted appId without slashes in the namespace, adding a slash between namespace and name - return `${sanitizedNamespace}${sanitizedNamespace && sanitizedName ? '/' : ''}${sanitizedName}`; - } -} - -/** - * Generates and writes UI5 test files based on the provided application configuration. - * @template T - * @param {string} basePath - The base path where test files will be generated. - * @param {FreestyleApp} ffApp - The freestyle application configuration. - * @param {Editor} [fs] - The file system editor instance. - * @param {Logger} [log] - The logger instance. - */ -export async function writeTestFiles(basePath: string, ffApp: FreestyleApp, fs?: Editor, log?: Logger): Promise { - const templateLtsVersion_1_120 = '1.120.0'; - const templateUi5Version = ffApp.ui5?.version - ? compareUI5VersionGte(ffApp.ui5.version, templateLtsVersion_1_120) - ? templateLtsVersion_1_120 - : ui5LtsVersion_1_71 - : templateLtsVersion_1_120; - - const config = { - appId: ffApp.app.id, - viewName: (ffApp.template.settings as BasicAppSettings).viewName, - ui5Theme: ffApp.ui5?.ui5Theme, - ui5Version: templateUi5Version, - applicationTitle: ffApp.app.title, - applicationDescription: ffApp.app.description, - appIdWithSlash: formatAppId(ffApp.package.name, ffApp.app.namespace, ffApp.appOptions?.typescript), - enableTypeScript: ffApp.appOptions?.typescript - }; - await generateFreestyleOPAFiles(basePath, config, fs, log); -} \ No newline at end of file diff --git a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts index 30880dcd6a..d0c2034ef5 100644 --- a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts +++ b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts @@ -120,8 +120,7 @@ export function getPackageScripts({ flpAppId = '', startFile, localStartFile, - generateIndex = true, - hasService = true + generateIndex = true }: PackageScriptsOptions): PackageJsonScripts { const searchParams = buildSearchParams(sapClient); const params = buildParams(searchParams, flpAppId); @@ -146,9 +145,7 @@ export function getPackageScripts({ : getVariantPreviewAppScript(sapClient); if (addTest) { - const ui5MockYamlScript = hasService ? '--config ./ui5-mock.yaml ' : '' ; - scripts['unit-tests'] = `fiori run ${ui5MockYamlScript}--open 'test/unit/unitTests.qunit.html'`, - scripts['int-tests'] = `fiori run ${ui5MockYamlScript}--open 'test/integration/opaTests.qunit.html'`; + scripts['int-test'] = 'fiori run --config ./ui5-mock.yaml --open "test/integration/opaTests.qunit.html"'; } return scripts; diff --git a/packages/fiori-generator-shared/src/npm-package-scripts/types.ts b/packages/fiori-generator-shared/src/npm-package-scripts/types.ts index bfb8812065..0078089434 100644 --- a/packages/fiori-generator-shared/src/npm-package-scripts/types.ts +++ b/packages/fiori-generator-shared/src/npm-package-scripts/types.ts @@ -11,9 +11,9 @@ export interface PackageJsonScripts { /** Optional command to start the application with a mock server configuration. */ 'start-mock'?: string; /** Optional command to run unit tests. */ - 'unit-tests'?: string; + 'unit-test'?: string; /** Optional command to run tests. */ - 'int-tests'?: string; + 'int-test'?: string; /** Optional command to add the variants management script. */ 'start-variants-management'?: string; } diff --git a/packages/ui5-test-writer/package.json b/packages/ui5-test-writer/package.json index 3f5daa7494..687a45b707 100644 --- a/packages/ui5-test-writer/package.json +++ b/packages/ui5-test-writer/package.json @@ -35,7 +35,8 @@ "ejs": "3.1.10", "i18next": "20.6.1", "mem-fs": "2.1.0", - "mem-fs-editor": "9.4.0" + "mem-fs-editor": "9.4.0", + "@sap-ux/ui5-application-writer": "workspace:*" }, "devDependencies": { "@sap-ux/project-access": "workspace:*", diff --git a/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts new file mode 100644 index 0000000000..9a39a2fbb4 --- /dev/null +++ b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts @@ -0,0 +1,357 @@ +import { join } from 'path'; +import { create as createStorage } from 'mem-fs'; +import type { Editor } from 'mem-fs-editor'; +import { create } from 'mem-fs-editor'; +import type { Manifest } from '@sap-ux/project-access'; +import type { FEV4OPAConfig, FEV4OPAPageConfig, FEV4ManifestTarget } from './types'; +import { SupportedPageTypes, ValidationError } from './types'; +import { t } from './i18n'; + +/** + * Reads the manifest for an app. + * + * @param fs - a reference to a mem-fs editor + * @param basePath - the root folder of the app + * @returns the manifest object. An exception is thrown if the manifest cannot be read. + */ +export function readManifest(fs: Editor, basePath: string): Manifest { + const manifest = fs.readJSON(join(basePath, 'webapp/manifest.json')) as any as Manifest; + if (!manifest) { + throw new ValidationError( + t('error.cannotReadManifest', { + filePath: join(basePath, 'webapp/manifest.json') + }) + ); + } + return manifest; +} + +/** + * Retrieves the application type of the main datasource (FreeStyle, FE V2 or FE V4). + * + * @param manifest - the app descriptor of the app + * @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 + */ +function getAppTypeAndHideFilterBarFromManifest(manifest: Manifest): { + applicationType: string; + hideFilterBar: boolean; +} { + const appTargets = manifest['sap.ui5']?.routing?.targets; + let hideFilterBar: boolean = false; + let isFEV4 = false; + for (const targetKey in appTargets) { + const target = appTargets[targetKey] as FEV4ManifestTarget; + if (target.type === 'Component' && target.name && target.name in SupportedPageTypes) { + isFEV4 = true; + if (SupportedPageTypes[target.name] === 'ListReport') { + hideFilterBar = target.options?.settings?.hideFilterBar ?? false; + } + } + } + + if (!isFEV4) { + throw new ValidationError(t('error.badApplicationType')); + } + + return { applicationType: 'v4', hideFilterBar }; // For the time being, only FE V4 is supported +} + +/** + * Retrieves appID and appPath from the manifest. + * + * @param manifest - the app descriptor of the app + * @param forcedAppID - the appID in case we don't want to read it from the manifest + * @returns appID and appPath + */ +function getAppFromManifest(manifest: Manifest, forcedAppID?: string): { appID: string; appPath: string } { + const appID = forcedAppID || manifest['sap.app']?.id; + const appPath = appID?.split('.').join('/'); + + if (!appID || !appPath) { + throw new ValidationError(t('error.cannotReadAppID')); + } + + return { appID, appPath }; +} + +/** + * Create the page configuration object from the app descriptor and the target key. + * + * @param manifest - the app descriptor of the app + * @param targetKey - the key of the target in the manifest + * @param forcedAppID - the appID in case we don't want to read it from the manifest + * @returns Page configuration object, or undefined if the target type is not supported + */ +function createPageConfig(manifest: Manifest, targetKey: string, forcedAppID?: string): FEV4OPAPageConfig | undefined { + const appTargets = manifest['sap.ui5']?.routing?.targets; + const target = appTargets && (appTargets[targetKey] as FEV4ManifestTarget); + const { appID, appPath } = getAppFromManifest(manifest, forcedAppID); + + if ( + target?.type === 'Component' && + target?.name && + target.name in SupportedPageTypes && + target?.id && + (target?.options?.settings?.entitySet || target?.options?.settings?.contextPath) + ) { + const pageConfig: FEV4OPAPageConfig = { + appPath, + appID, + targetKey, + componentID: target.id, + template: SupportedPageTypes[target.name], + isStartup: false + }; + + if (target.options.settings.contextPath) { + pageConfig.contextPath = target.options.settings.contextPath; + } else if (target.options.settings.entitySet) { + pageConfig.entitySet = target.options.settings.entitySet; + } + return pageConfig; + } else { + return undefined; + } +} + +/** + * Create the configuration object from the app descriptor. + * + * @param manifest - the app descriptor of the target app + * @param opaConfig - parameters for the generation + * @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used + * @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 + * @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id + * @param hideFilterBar - whether the filter bar should be hidden in the generated tests + * @returns OPA test configuration object + */ +function createConfig( + manifest: Manifest, + opaConfig: { scriptName?: string; appID?: string; htmlTarget?: string }, + hideFilterBar: boolean +): FEV4OPAConfig { + // General application info + const { appID, appPath } = getAppFromManifest(manifest, opaConfig.appID); + + const config: FEV4OPAConfig = { + appID, + appPath, + pages: [], + opaJourneyFileName: opaConfig.scriptName ?? 'FirstJourney', + htmlTarget: opaConfig.htmlTarget ?? 'index.html', + hideFilterBar + }; + + // Identify startup targets from the routes + const appRoutes = (manifest['sap.ui5']?.routing?.routes ?? []) as any[]; + // Find the route with an empty pattern (except for the trailing query part) + const startupRoute = appRoutes.find((route: { pattern: string }) => { + return route.pattern.replace(':?query:', '') === ''; + }); + let startupTargets = startupRoute?.target ?? []; + if (!Array.isArray(startupTargets)) { + startupTargets = [startupTargets]; + } + + // Create page configurations in supported cases + const appTargets = manifest['sap.ui5']?.routing?.targets; + for (const targetKey in appTargets) { + const pageConfig = createPageConfig(manifest, targetKey, opaConfig.appID); + if (pageConfig) { + pageConfig.isStartup = startupTargets.includes(targetKey); + config.pages.push(pageConfig); + } + } + + return config; +} + +/** + * Finds the initial ListReport page and the first Object page from the app. + * + * @param pages - the page configs of the app + * @param manifest - the app descriptor of the target app + * @returns the page fonfigs for the LR and the OP if they're found + */ +function findLROP( + pages: FEV4OPAPageConfig[], + manifest: Manifest +): { pageLR?: FEV4OPAPageConfig; pageOP?: FEV4OPAPageConfig } { + const pageLR = pages.find((page) => { + return page.isStartup && page.template === 'ListReport'; + }); + + if (!pageLR) { + return {}; + } + + const appTargets = manifest['sap.ui5']?.routing?.targets; + const appRoutes = (manifest['sap.ui5']?.routing?.routes ?? []) as any[]; + const target = (appTargets && appTargets[pageLR.targetKey]) as FEV4ManifestTarget; + + if (!target?.options?.settings?.navigation) { + return { pageLR }; // No navigation from LR + } + + // Find all targets that can be navigated from the LR page + const navigatedTargetKeys: string[] = []; + for (const navKey in target.options.settings.navigation) { + const navObject = target.options.settings.navigation[navKey]; + const navigatedRoute = + navObject.detail?.route && + appRoutes.find((route) => { + return route.name === navObject.detail?.route; + }); + + if (Array.isArray(navigatedRoute?.target)) { + navigatedTargetKeys.push(...navigatedRoute.target); + } else if (navigatedRoute?.target) { + navigatedTargetKeys.push(navigatedRoute.target); + } + } + + // Find the first navigated page that is valid and not the starting LR + let pageOP: FEV4OPAPageConfig | undefined; + for (let i = 0; i < navigatedTargetKeys.length && !pageOP; i++) { + if (navigatedTargetKeys[i] === pageLR.targetKey) { + continue; // This can happen in the FCL case where the LR is also part of the route's targets to the OP + } + + pageOP = pages.find((page) => { + return page.targetKey === navigatedTargetKeys[i]; + }); + } + + return { pageLR, pageOP }; +} + +/** + * Writes a page object in a mem-fs-editor. + * + * @param pageConfig - the page configuration object + * @param rootTemplateDirPath - template root directory + * @param testOutDirPath - output test directory (.../webapp/test) + * @param fs - a reference to a mem-fs editor + */ +function writePageObject( + pageConfig: FEV4OPAPageConfig, + rootTemplateDirPath: string, + testOutDirPath: string, + fs: Editor +) { + fs.copyTpl( + join(rootTemplateDirPath, `integration/pages/${pageConfig.template}.js`), + join(testOutDirPath, `integration/pages/${pageConfig.targetKey}.js`), + pageConfig, + undefined, + { + globOptions: { dot: true } + } + ); +} + +/** + * Generate OPA test files for a Fiori elements for OData V4 application. + * Note: this can potentially overwrite existing files in the webapp/test folder. + * + * @param basePath - the absolute target path where the application will be generated + * @param opaConfig - parameters for the generation + * @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used + * @param opaConfig.htmlTarget - the name of the html that will be used in OPA journey file. If not specified, 'index.html' will be used + * @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id + * @param fs - an optional reference to a mem-fs editor + * @returns Reference to a mem-fs-editor + */ +export function generateFioriElementsOPAFiles( + basePath: string, + opaConfig: { scriptName?: string; appID?: string; htmlTarget?: string }, + fs?: Editor +): Editor { + const editor = fs ?? create(createStorage()); + + const manifest = readManifest(editor, basePath); + const { applicationType, hideFilterBar } = getAppTypeAndHideFilterBarFromManifest(manifest); + + const config = createConfig(manifest, opaConfig, hideFilterBar); + + const rootCommonTemplateDirPath = join(__dirname, '../templates/common'); + const rootV4TemplateDirPath = join(__dirname, `../templates/${applicationType}`); // Only v4 is supported for the time being + const testOutDirPath = join(basePath, 'webapp/test'); + + // Common test files + editor.copy(join(rootCommonTemplateDirPath), testOutDirPath); + + // Integration (OPA) test files - version-specific + editor.copyTpl( + join(rootV4TemplateDirPath, 'integration', 'opaTests.*.*'), + join(testOutDirPath, 'integration'), + config, + undefined, + { + globOptions: { dot: true } + } + ); + + // Pages files (one for each page in the app) + config.pages.forEach((page) => { + writePageObject(page, rootV4TemplateDirPath, testOutDirPath, editor); + }); + + // OPA Journey file + const startPages = config.pages.filter((page) => page.isStartup).map((page) => page.targetKey); + const LROP = findLROP(config.pages, manifest); + const journeyParams = { + startPages, + startLR: LROP.pageLR?.targetKey, + navigatedOP: LROP.pageOP?.targetKey, + hideFilterBar: config.hideFilterBar + }; + editor.copyTpl( + join(rootV4TemplateDirPath, 'integration/FirstJourney.js'), + join(testOutDirPath, `integration/${config.opaJourneyFileName}.js`), + journeyParams, + undefined, + { + globOptions: { dot: true } + } + ); + + return editor; +} + +/** + * Generate a page object file for a Fiori elements for OData V4 application. + * Note: this doesn't modify other existing files in the webapp/test folder. + * + * @param basePath - the absolute target path where the application will be generated + * @param pageObjectParameters - parameters for the page + * @param pageObjectParameters.targetKey - the key of the target in the manifest file corresponding to the page + * @param pageObjectParameters.appID - the appID. If not specified, will be read from the manifest in sap.app/id + * @param fs - an optional reference to a mem-fs editor + * @returns Reference to a mem-fs-editor + */ +export function generatePageObjectFile( + basePath: string, + pageObjectParameters: { targetKey: string; appID?: string }, + fs?: Editor +): Editor { + const editor = fs || create(createStorage()); + + const manifest = readManifest(editor, basePath); + const { applicationType } = getAppTypeAndHideFilterBarFromManifest(manifest); + + const pageConfig = createPageConfig(manifest, pageObjectParameters.targetKey, pageObjectParameters.appID); + if (pageConfig) { + const rootTemplateDirPath = join(__dirname, `../templates/${applicationType}`); // Only v4 is supported for the time being + const testOutDirPath = join(basePath, 'webapp/test'); + writePageObject(pageConfig, rootTemplateDirPath, testOutDirPath, editor); + } else { + throw new ValidationError( + t('error.cannotGeneratePageFile', { + targetKey: pageObjectParameters.targetKey + }) + ); + } + + return editor; +} diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts new file mode 100644 index 0000000000..3a7d2646c1 --- /dev/null +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -0,0 +1,233 @@ +import { join, basename } from 'path'; +import { create as createStorage } from 'mem-fs'; +import type { Editor } from 'mem-fs-editor'; +import { create } from 'mem-fs-editor'; +import type { FFOPAConfig } from './types'; +import type { Logger } from '@sap-ux/logger'; +import { getFilePaths } from '@sap-ux/project-access'; +import type { Package } from '@sap-ux/project-access'; +import { ValidationError } from './types'; +import { t } from './i18n'; +import { compareUI5VersionGte, ui5LtsVersion_1_71 } from '@sap-ux/ui5-application-writer'; + +/** + * Reads the Package for an app. + * + * @param fs - a reference to a mem-fs editor + * @param basePath - the root folder of the app + * @returns the Package object. An exception is thrown if the Package cannot be read. + */ +export function readPackage(fs: Editor, basePath: string): Package { + const packageJose = fs.readJSON(join(basePath, 'package.json')) as any as Package; + if (!packageJose) { + throw new ValidationError( + t('error.cannotReadPackage', { + filePath: join(basePath, 'package.json') + }) + ); + } + return packageJose; +} + +/** + * Updates tsconfig.json to include paths for unit and integration tests. + * + * @param {Editor} fs - The file system editor instance. + * @param {string} destinationRoot - The root directory where tsconfig.json exists. + * @param log + */ +function writeOPATsconfigJsonUpdates(fs: Editor, destinationRoot: string, log?: Logger): void { + try { + const tsconfig: any = fs.readJSON(join(destinationRoot, 'tsconfig.json')) ?? {}; + + tsconfig.compilerOptions = tsconfig.compilerOptions || {}; + tsconfig.compilerOptions.paths = tsconfig.compilerOptions.paths || {}; + + tsconfig.compilerOptions.paths['unit/*'] = ['./webapp/test/unit/*']; + tsconfig.compilerOptions.paths['integration/*'] = ['./webapp/test/integration/*']; + + fs.writeJSON(join(destinationRoot, 'tsconfig.json'), tsconfig); + } catch (error) { + log?.error(`Error updating tsconfig.json: ${error}`); + } +} + +/** + * Formats a namespace by replacing dots with slashes. + * + * @param {string} namespace - The namespace to format. + * @returns {string} - Formatted namespace. + */ +function formatNamespace(namespace: string): string { + return namespace.replace(/\./g, '/'); +} + +/** + * Gets the template UI5 version based on the provided UI5 version. + * + * @param ui5Version - The UI5 version. + * @returns template UI5 version. + */ +function getTemplateUi5Version(ui5Version?: string): string { + const templateLtsVersion_1_120 = '1.120.0'; + if (!ui5Version) { + return templateLtsVersion_1_120; + } + return compareUI5VersionGte(ui5Version, templateLtsVersion_1_120) ? templateLtsVersion_1_120 : ui5LtsVersion_1_71; +} + +/** + * Copies filtered test template files from source directory to destination directory, + * with file renaming logic based on the view name. + * + * @param {string} freestyleTemplateDirPath - The path to the source directory containing template files. + * @param {string} testOutDirPath - The path to the destination directory where files should be copied. + * @param {string[]} filteredFiles - An array of filtered file paths to copy. + * @param {FFOPAConfig} opaConfig - The OPA test configuration object to write into template files. + * @param {Editor} editor - The editor instance used to copy and render template files. + * @param {Logger} [log] - The logger instance. + * @returns {Promise} - A promise that resolves to `true` if the files were copied successfully, + * or `false` if there was an error during the process. + */ +async function copyTestFiles( + freestyleTemplateDirPath: string, + testOutDirPath: string, + filteredFiles: string[], + opaConfig: FFOPAConfig, + editor: Editor, + log?: Logger +): Promise { + try { + filteredFiles.forEach((filePath: string) => { + const sourceFilePath = join(freestyleTemplateDirPath, filePath); + let destinationFilePath = join(testOutDirPath, filePath); + const viewName = opaConfig.viewName; + + // Rename files: + // - viewName.js files are renamed to include the view name in their file path + // - viewName.ts files are renamed with the view name appended with 'Page' + const renameMap: Record = { + '/integration/pages/viewName.js': `integration/pages/${viewName}.js`, + '/integration/pages/viewName.ts': `integration/pages/${viewName}Page.ts`, + '/unit/controller/viewName.controller.js': `unit/controller/${viewName}.controller.js`, + '/unit/controller/viewName.controller.ts': `unit/controller/${viewName}Page.controller.ts` + }; + + if (renameMap[filePath]) { + destinationFilePath = join(testOutDirPath, renameMap[filePath]); + } + editor.copyTpl(sourceFilePath, destinationFilePath, { ...opaConfig, formatNamespace }, undefined, { + globOptions: { dot: true } + }); + }); + const rootCommonTemplateDirPath = join(__dirname, '../templates/common'); + editor.copyTpl( + rootCommonTemplateDirPath, + testOutDirPath, + { + appId: opaConfig.appId, + addUnitTests: false + }, + undefined, + { + globOptions: { dot: true } + } + ); + + return true; + } catch (error) { + log?.error(`Error copying files: ${error}`); + return false; + } +} + +/** + * Generates formatted application ID with slashes based on namespace, name, and TypeScript settings. + * + * @param {string} [name] - The application name. + * @param {string} [namespace] - The application namespace. + * @param {boolean} [enableTypescript] - Whether TypeScript is enabled. + * @returns {string} The formatted application ID with slashes. + */ +function getAppIdWithSlash(name: string = '', namespace: string = '', enableTypescript: boolean = false): string { + // Replace dots with slashes in the namespace and remove any trailing slash + const formattedNamespace = namespace.replace(/\./g, '/').replace(/\/$/, ''); + + // Construct the AppIdWithSlash based on the conditions + const appIdWithSlash = enableTypescript + ? `${formattedNamespace}${namespace ? '/' : ''}${name.replace(/[_-]/g, '')}` + : `${namespace.replace(/\./g, '')}${namespace ? '/' : ''}${name}`; + + return appIdWithSlash; +} + +/** + * Generates and copies freestyle test files based on configuration. + * + * @param {string} basePath - The base directory path. + * @param {FFOPAConfig} opaConfig - Configuration object. + * @param {Editor} fs - Optional file system editor instance. + * @param {Logger} log - Optional logger instance. + * @returns {Editor} - The modified file system editor. + */ +export async function generateFreestyleOPAFiles( + basePath: string, + opaConfig: FFOPAConfig, + fs?: Editor, + log?: Logger +): Promise { + const fsEditor = fs ?? create(createStorage()); + const { enableTypeScript, ui5Version, viewName, namespace } = opaConfig; + + const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/webapp/test'); + const testOutDirPath = join(basePath, 'webapp/test'); + const templateUi5Version = getTemplateUi5Version(ui5Version); + const projectName = readPackage(fsEditor, basePath).name; + const appIdWithSlash = getAppIdWithSlash(projectName, namespace, enableTypeScript); + + // Get template files + const templateFiles = await getFilePaths(freestyleTemplateDirPath); + const isTypeScript = Boolean(enableTypeScript); + const commonJSTemplateFiles = ['initFlpSandbox.js', 'flpSandbox.js']; + + // Filter files based on TypeScript setting: + // - If TypeScript is enabled, include only .ts files + // - If TypeScript is disabled, include only .js files + // - Include common JS files regardless of TypeScript setting + const filteredFiles = templateFiles + .filter((filePath: string) => { + if (filePath.endsWith('.ts')) { + return isTypeScript; + } + if (filePath.endsWith('.js')) { + const includeCommonJSTemplate = + commonJSTemplateFiles.includes(basename(filePath)) && templateUi5Version === '1.71.0'; + return !isTypeScript || includeCommonJSTemplate; + } + return true; // keep other .html files + }) + .map((filePath: string) => filePath.replace(freestyleTemplateDirPath, '')); + + const config = { + ...opaConfig, + viewNamePage: `${viewName}Page`, + appIdWithSlash, + ui5Version: templateUi5Version, + navigationIntent: opaConfig.appId.replace(/[./\\\-\s]/g, '') + }; + const filesCopiedSuccessfully = await copyTestFiles( + freestyleTemplateDirPath, + testOutDirPath, + filteredFiles, + config, + fsEditor, + log + ); + + // If files are copied successfully, update the package.json and tsconfig files + if (filesCopiedSuccessfully && isTypeScript) { + writeOPATsconfigJsonUpdates(fsEditor, basePath, log); + } + + return fsEditor; +} diff --git a/packages/ui5-test-writer/src/index.ts b/packages/ui5-test-writer/src/index.ts index e2fd2673f3..e7e7aceb2f 100644 --- a/packages/ui5-test-writer/src/index.ts +++ b/packages/ui5-test-writer/src/index.ts @@ -1,510 +1,2 @@ -import { join, basename } from 'path'; -import { create as createStorage } from 'mem-fs'; -import type { Editor } from 'mem-fs-editor'; -import { create } from 'mem-fs-editor'; -import type { Manifest } from '@sap-ux/project-access'; -import type { FEV4OPAConfig, FEV4OPAPageConfig, FEV4ManifestTarget } from './types'; -import { SupportedPageTypes, ValidationError, FFOPAConfig } from './types'; -import { t } from './i18n'; -import type { Logger } from '@sap-ux/logger'; -import { getFilePaths } from '@sap-ux/project-access'; - -/** - * Reads the manifest for an app. - * - * @param fs - a reference to a mem-fs editor - * @param basePath - the root folder of the app - * @returns the manifest object. An exception is thrown if the manifest cannot be read. - */ -function readManifest(fs: Editor, basePath: string): Manifest { - const manifest = fs.readJSON(join(basePath, 'webapp/manifest.json')) as any as Manifest; - if (!manifest) { - throw new ValidationError( - t('error.cannotReadManifest', { - filePath: join(basePath, 'webapp/manifest.json') - }) - ); - } - - return manifest; -} - -/** - * Retrieves the application type of the main datasource (FreeStyle, FE V2 or FE V4). - * - * @param manifest - the app descriptor of the app - * @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 - */ -function getAppTypeAndHideFilterBarFromManifest(manifest: Manifest): { - applicationType: string; - hideFilterBar: boolean; -} { - const appTargets = manifest['sap.ui5']?.routing?.targets; - let hideFilterBar: boolean = false; - let isFEV4 = false; - for (const targetKey in appTargets) { - const target = appTargets[targetKey] as FEV4ManifestTarget; - if (target.type === 'Component' && target.name && target.name in SupportedPageTypes) { - isFEV4 = true; - if (SupportedPageTypes[target.name] === 'ListReport') { - hideFilterBar = target.options?.settings?.hideFilterBar ?? false; - } - } - } - - if (!isFEV4) { - throw new ValidationError(t('error.badApplicationType')); - } - - return { applicationType: 'v4', hideFilterBar }; // For the time being, only FE V4 is supported -} - -/** - * Retrieves appID and appPath from the manifest. - * - * @param manifest - the app descriptor of the app - * @param forcedAppID - the appID in case we don't want to read it from the manifest - * @returns appID and appPath - */ -function getAppFromManifest(manifest: Manifest, forcedAppID?: string): { appID: string; appPath: string } { - const appID = forcedAppID || manifest['sap.app']?.id; - const appPath = appID?.split('.').join('/'); - - if (!appID || !appPath) { - throw new ValidationError(t('error.cannotReadAppID')); - } - - return { appID, appPath }; -} - -/** - * Create the page configuration object from the app descriptor and the target key. - * - * @param manifest - the app descriptor of the app - * @param targetKey - the key of the target in the manifest - * @param forcedAppID - the appID in case we don't want to read it from the manifest - * @returns Page configuration object, or undefined if the target type is not supported - */ -function createPageConfig(manifest: Manifest, targetKey: string, forcedAppID?: string): FEV4OPAPageConfig | undefined { - const appTargets = manifest['sap.ui5']?.routing?.targets; - const target = appTargets && (appTargets[targetKey] as FEV4ManifestTarget); - const { appID, appPath } = getAppFromManifest(manifest, forcedAppID); - - if ( - target?.type === 'Component' && - target?.name && - target.name in SupportedPageTypes && - target?.id && - (target?.options?.settings?.entitySet || target?.options?.settings?.contextPath) - ) { - const pageConfig: FEV4OPAPageConfig = { - appPath, - appID, - targetKey, - componentID: target.id, - template: SupportedPageTypes[target.name], - isStartup: false - }; - - if (target.options.settings.contextPath) { - pageConfig.contextPath = target.options.settings.contextPath; - } else if (target.options.settings.entitySet) { - pageConfig.entitySet = target.options.settings.entitySet; - } - return pageConfig; - } else { - return undefined; - } -} - -/** - * Create the configuration object from the app descriptor. - * - * @param manifest - the app descriptor of the target app - * @param opaConfig - parameters for the generation - * @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used - * @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 - * @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id - * @param hideFilterBar - whether the filter bar should be hidden in the generated tests - * @returns OPA test configuration object - */ -function createConfig( - manifest: Manifest, - opaConfig: { scriptName?: string; appID?: string; htmlTarget?: string }, - hideFilterBar: boolean -): FEV4OPAConfig { - // General application info - const { appID, appPath } = getAppFromManifest(manifest, opaConfig.appID); - - const config: FEV4OPAConfig = { - appID, - appPath, - pages: [], - opaJourneyFileName: opaConfig.scriptName ?? 'FirstJourney', - htmlTarget: opaConfig.htmlTarget ?? 'index.html', - hideFilterBar - }; - - // Identify startup targets from the routes - const appRoutes = (manifest['sap.ui5']?.routing?.routes ?? []) as any[]; - // Find the route with an empty pattern (except for the trailing query part) - const startupRoute = appRoutes.find((route: { pattern: string }) => { - return route.pattern.replace(':?query:', '') === ''; - }); - let startupTargets = startupRoute?.target ?? []; - if (!Array.isArray(startupTargets)) { - startupTargets = [startupTargets]; - } - - // Create page configurations in supported cases - const appTargets = manifest['sap.ui5']?.routing?.targets; - for (const targetKey in appTargets) { - const pageConfig = createPageConfig(manifest, targetKey, opaConfig.appID); - if (pageConfig) { - pageConfig.isStartup = startupTargets.includes(targetKey); - config.pages.push(pageConfig); - } - } - - return config; -} - -/** - * Finds the initial ListReport page and the first Object page from the app. - * - * @param pages - the page configs of the app - * @param manifest - the app descriptor of the target app - * @returns the page fonfigs for the LR and the OP if they're found - */ -function findLROP( - pages: FEV4OPAPageConfig[], - manifest: Manifest -): { pageLR?: FEV4OPAPageConfig; pageOP?: FEV4OPAPageConfig } { - const pageLR = pages.find((page) => { - return page.isStartup && page.template === 'ListReport'; - }); - - if (!pageLR) { - return {}; - } - - const appTargets = manifest['sap.ui5']?.routing?.targets; - const appRoutes = (manifest['sap.ui5']?.routing?.routes ?? []) as any[]; - const target = (appTargets && appTargets[pageLR.targetKey]) as FEV4ManifestTarget; - - if (!target?.options?.settings?.navigation) { - return { pageLR }; // No navigation from LR - } - - // Find all targets that can be navigated from the LR page - const navigatedTargetKeys: string[] = []; - for (const navKey in target.options.settings.navigation) { - const navObject = target.options.settings.navigation[navKey]; - const navigatedRoute = - navObject.detail?.route && - appRoutes.find((route) => { - return route.name === navObject.detail?.route; - }); - - if (Array.isArray(navigatedRoute?.target)) { - navigatedTargetKeys.push(...navigatedRoute.target); - } else if (navigatedRoute?.target) { - navigatedTargetKeys.push(navigatedRoute.target); - } - } - - // Find the first navigated page that is valid and not the starting LR - let pageOP: FEV4OPAPageConfig | undefined; - for (let i = 0; i < navigatedTargetKeys.length && !pageOP; i++) { - if (navigatedTargetKeys[i] === pageLR.targetKey) { - continue; // This can happen in the FCL case where the LR is also part of the route's targets to the OP - } - - pageOP = pages.find((page) => { - return page.targetKey === navigatedTargetKeys[i]; - }); - } - - return { pageLR, pageOP }; -} - -/** - * Writes a page object in a mem-fs-editor. - * - * @param pageConfig - the page configuration object - * @param rootTemplateDirPath - template root directory - * @param testOutDirPath - output test directory (.../webapp/test) - * @param fs - a reference to a mem-fs editor - */ -function writePageObject( - pageConfig: FEV4OPAPageConfig, - rootTemplateDirPath: string, - testOutDirPath: string, - fs: Editor -) { - fs.copyTpl( - join(rootTemplateDirPath, `integration/pages/${pageConfig.template}.js`), - join(testOutDirPath, `integration/pages/${pageConfig.targetKey}.js`), - pageConfig, - undefined, - { - globOptions: { dot: true } - } - ); -} - -/** - * Generate OPA test files for a Fiori elements for OData V4 application. - * Note: this can potentially overwrite existing files in the webapp/test folder. - * - * @param basePath - the absolute target path where the application will be generated - * @param opaConfig - parameters for the generation - * @param opaConfig.scriptName - the name of the OPA journey file. If not specified, 'FirstJourney' will be used - * @param opaConfig.htmlTarget - the name of the html that will be used in OPA journey file. If not specified, 'index.html' will be used - * @param opaConfig.appID - the appID. If not specified, will be read from the manifest in sap.app/id - * @param fs - an optional reference to a mem-fs editor - * @returns Reference to a mem-fs-editor - */ -export function generateOPAFiles( - basePath: string, - opaConfig: { scriptName?: string; appID?: string; htmlTarget?: string }, - fs?: Editor -): Editor { - debugger; - const editor = fs ?? create(createStorage()); - - const manifest = readManifest(editor, basePath); - const { applicationType, hideFilterBar } = getAppTypeAndHideFilterBarFromManifest(manifest); - - const config = createConfig(manifest, opaConfig, hideFilterBar); - - const rootCommonTemplateDirPath = join(__dirname, '../templates/common'); - const rootV4TemplateDirPath = join(__dirname, `../templates/${applicationType}`); // Only v4 is supported for the time being - const testOutDirPath = join(basePath, 'webapp/test'); - - // Common test files - editor.copy(join(rootCommonTemplateDirPath), testOutDirPath); - - // Integration (OPA) test files - version-specific - editor.copyTpl( - join(rootV4TemplateDirPath, 'integration', 'opaTests.*.*'), - join(testOutDirPath, 'integration'), - config, - undefined, - { - globOptions: { dot: true } - } - ); - - // Pages files (one for each page in the app) - config.pages.forEach((page) => { - writePageObject(page, rootV4TemplateDirPath, testOutDirPath, editor); - }); - - // OPA Journey file - const startPages = config.pages.filter((page) => page.isStartup).map((page) => page.targetKey); - const LROP = findLROP(config.pages, manifest); - const journeyParams = { - startPages, - startLR: LROP.pageLR?.targetKey, - navigatedOP: LROP.pageOP?.targetKey, - hideFilterBar: config.hideFilterBar - }; - editor.copyTpl( - join(rootV4TemplateDirPath, 'integration/FirstJourney.js'), - join(testOutDirPath, `integration/${config.opaJourneyFileName}.js`), - journeyParams, - undefined, - { - globOptions: { dot: true } - } - ); - - return editor; -} - -/** - * Generate a page object file for a Fiori elements for OData V4 application. - * Note: this doesn't modify other existing files in the webapp/test folder. - * - * @param basePath - the absolute target path where the application will be generated - * @param pageObjectParameters - parameters for the page - * @param pageObjectParameters.targetKey - the key of the target in the manifest file corresponding to the page - * @param pageObjectParameters.appID - the appID. If not specified, will be read from the manifest in sap.app/id - * @param fs - an optional reference to a mem-fs editor - * @returns Reference to a mem-fs-editor - */ -export function generatePageObjectFile( - basePath: string, - pageObjectParameters: { targetKey: string; appID?: string }, - fs?: Editor -): Editor { - const editor = fs || create(createStorage()); - - const manifest = readManifest(editor, basePath); - const { applicationType } = getAppTypeAndHideFilterBarFromManifest(manifest); - - const pageConfig = createPageConfig(manifest, pageObjectParameters.targetKey, pageObjectParameters.appID); - if (pageConfig) { - const rootTemplateDirPath = join(__dirname, `../templates/${applicationType}`); // Only v4 is supported for the time being - const testOutDirPath = join(basePath, 'webapp/test'); - writePageObject(pageConfig, rootTemplateDirPath, testOutDirPath, editor); - } else { - throw new ValidationError( - t('error.cannotGeneratePageFile', { - targetKey: pageObjectParameters.targetKey - }) - ); - } - - return editor; -} - -/** - * Updates tsconfig.json to include paths for unit and integration tests. - * @param {Editor} fs - The file system editor instance. - * @param {string} destinationRoot - The root directory where tsconfig.json exists. - */ -function writeOPATsconfigJsonUpdates(fs: Editor, destinationRoot: string, log?: Logger): void { - try { - const tsconfig:any = fs.readJSON(join(destinationRoot, 'tsconfig.json')) ?? {}; - - tsconfig.compilerOptions = tsconfig.compilerOptions || {}; - tsconfig.compilerOptions.paths = tsconfig.compilerOptions.paths || {}; - - tsconfig.compilerOptions.paths['unit/*'] = ['./webapp/test/unit/*']; - tsconfig.compilerOptions.paths['integration/*'] = ['./webapp/test/integration/*']; - - fs.writeJSON(join(destinationRoot, 'tsconfig.json'), tsconfig); - } catch (error) { - log?.error(`Error updating tsconfig.json: ${error}`); - } -} - -/** - * Formats a namespace by replacing dots with slashes. - * @param {string} namespace - The namespace to format. - * @returns {string} - Formatted namespace. - */ -function formatNamespace(namespace: string): string { - return namespace.replace(/\./g, '/'); -} - -/** - * Copies filtered test template files from source directory to destination directory, - * with file renaming logic based on the view name. - * - * @param {string} freestyleTemplateDirPath - The path to the source directory containing template files. - * @param {string} testOutDirPath - The path to the destination directory where files should be copied. - * @param {string[]} filteredFiles - An array of filtered file paths to copy. - * @param {TestConfig} testConfig - The test configuration object to write into template files. - * @param {Editor} editor - The editor instance used to copy and render template files. - * @param {Logger} [log] - The logger instance. - * - * @returns {Promise} - A promise that resolves to `true` if the files were copied successfully, - * or `false` if there was an error during the process. - * - */ -async function copyTestFiles( - freestyleTemplateDirPath: string, - testOutDirPath: string, - filteredFiles: string[], - opaConfig: FFOPAConfig, - editor: Editor, - log?: Logger -): Promise { - try { - filteredFiles.forEach((filePath: string) => { - const sourceFilePath = join(freestyleTemplateDirPath, filePath); - let destinationFilePath = join(testOutDirPath, filePath); - const viewName = opaConfig.viewName; - - // Rename files: - // - viewName.js files are renamed to include the view name in their file path - // - viewName.ts files are renamed with the view name appended with 'Page' - const renameMap: Record = { - '/integration/pages/viewName.js': `integration/pages/${viewName}.js`, - '/integration/pages/viewName.ts': `integration/pages/${viewName}Page.ts`, - '/unit/controller/viewName.controller.js': `unit/controller/${viewName}.controller.js`, - '/unit/controller/viewName.controller.ts': `unit/controller/${viewName}Page.controller.ts` - }; - - if (renameMap[filePath]) { - destinationFilePath = join(testOutDirPath, renameMap[filePath]); - } - editor.copyTpl(sourceFilePath, destinationFilePath, { ...opaConfig, formatNamespace }, undefined, { - globOptions: { dot: true } - }); - }); - const rootCommonTemplateDirPath = join(__dirname, '../templates/common'); - editor.copyTpl(rootCommonTemplateDirPath, testOutDirPath, { - appId: opaConfig.appId, - addUnitTests: true - }, undefined, { - globOptions: { dot: true } - }); - - return true; - } catch (error) { - log?.error(`Error copying files: ${error}`); - return false; - } -} - -/** - * Generates and copies freestyle test files based on configuration. - * @param {string} basePath - The base directory path. - * @param {object} config - Configuration object. - * @param {Editor} fs - Optional file system editor instance. - * @returns {Editor} - The modified file system editor. - */ -export async function generateFreestyleOPAFiles( - basePath: string, - opaConfig: FFOPAConfig, - fs?: Editor, - log?: Logger -): Promise { - const fsEditor = fs ?? create(createStorage()); - const { appIdWithSlash, enableTypeScript, ui5Version, viewName } = opaConfig; - const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/webapp/test'); - const testOutDirPath = join(basePath, 'webapp/test'); - - // Get template files - const templateFiles = await getFilePaths(freestyleTemplateDirPath); - const isTypeScript = Boolean(enableTypeScript); - const commonJSTemplateFiles = ['initFlpSandbox.js', 'flpSandbox.js']; - - // Filter files based on TypeScript setting: - // - If TypeScript is enabled, include only .ts files - // - If TypeScript is disabled, include only .js files - // - Include common JS files regardless of TypeScript setting - const filteredFiles = templateFiles - .filter((filePath: string) => { - if (filePath.endsWith('.ts')) return isTypeScript; - if (filePath.endsWith('.js')) { - const includeCommonJSTemplate = commonJSTemplateFiles.includes(basename(filePath)) && (ui5Version === '1.71.0'); - return !isTypeScript || includeCommonJSTemplate; - } - return true; // keep other .html files - }) - .map((filePath: string) => filePath.replace(freestyleTemplateDirPath, '')); - - const config = { - ...opaConfig, - viewNamePage: `${viewName}Page`, - appIdWithSlash, - ui5Version, - navigationIntent: ( - '' + opaConfig.appId - ).replace(new RegExp('\\.|/|\\\\|-|\\s', 'g'), '') - }; - const filesCopiedSuccessfully = await copyTestFiles(freestyleTemplateDirPath, testOutDirPath, filteredFiles, config, fsEditor, log); - - // If files are copied successfully, update the package.json and tsconfig files - if (filesCopiedSuccessfully && isTypeScript) { - writeOPATsconfigJsonUpdates(fsEditor, basePath, log); - } - - return fsEditor; -} - +export { generateFioriElementsOPAFiles } from './fiori-elements-opa-writer'; +export { generateFreestyleOPAFiles } from './fiori-freestyle-opa-writer'; diff --git a/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json b/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json index ebb774267c..14ecb4cb8c 100644 --- a/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json +++ b/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json @@ -3,6 +3,7 @@ "cannotReadManifest": "Cannot read manifest file {{ filePath }}", "cannotReadAppID": "Cannot read appID in the manifest file", "badApplicationType": "Cannot determine application type from the manifest, or unsupported type", - "cannotGeneratePageFile": "Cannot generate page file for target {{ targetKey }}" + "cannotGeneratePageFile": "Cannot generate page file for target {{ targetKey }}", + "cannotReadPackage": "Cannot read package.json file {{ filePath }}" } } diff --git a/packages/ui5-test-writer/src/types.ts b/packages/ui5-test-writer/src/types.ts index b0b0d91fd2..174b29f65a 100644 --- a/packages/ui5-test-writer/src/types.ts +++ b/packages/ui5-test-writer/src/types.ts @@ -64,11 +64,11 @@ export class ValidationError extends Error { */ export interface FFOPAConfig { appId: string; - appIdWithSlash: string; + namespace?: string; applicationTitle?: string; applicationDescription?: string; enableTypeScript?: boolean; viewName?: string; - ui5Version: string; + ui5Version?: string; ui5Theme?: string; } diff --git a/packages/ui5-test-writer/templates/common/testsuite.qunit.js b/packages/ui5-test-writer/templates/common/testsuite.qunit.js index 9558583ab0..050b8c5119 100644 --- a/packages/ui5-test-writer/templates/common/testsuite.qunit.js +++ b/packages/ui5-test-writer/templates/common/testsuite.qunit.js @@ -1,6 +1,7 @@ -<% if (addUnitTests) { %>/* global window, parent, location */ +<% if (addUnitTests === true) { %>/* global window, parent, location */ -// eslint-disable-next-line fiori-custom/sap-no-global-define<% } %> +// eslint-disable-next-line fiori-custom/sap-no-global-define +<% } -%> window.suite = function() { "use strict"; diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.ts index 61446459d1..33709325af 100644 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.ts +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.ts @@ -5,7 +5,7 @@ window.suite = function() { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts index c5813167d7..9f6de76464 100644 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts @@ -1,21 +1,15 @@ <% if (ui5Version === "1.71.0") { -%> /* global QUnit */ // https://api.qunitjs.com/config/autostart/ -QUnit.config.autostart = false; - -// import all your QUnit tests here -void Promise.all([ - import("unit/controller/<%= viewName %>Page.controller") -]).then(() => { - QUnit.start(); -});<% } else if (ui5Version === "1.120.0") { -%> +<% } else { -%> /* @sapUiRequire */ +<% } -%> QUnit.config.autostart = false; // import all your QUnit tests here void Promise.all([ - import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests - import("unit/controller/<%= viewName %>Page.controller") -]).then(([{ default: Core }]) => Core.ready()).then(() => { + <% if (ui5Version !== "1.71.0") { -%>import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests <% }-%> +import("unit/controller/<%= viewName %>Page.controller") +]).then((<% if (ui5Version !== "1.71.0") { -%>[{ default: Core }]<% } %>) => { QUnit.start(); -});<% } %> \ No newline at end of file +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/tsconfig.json b/packages/ui5-test-writer/tsconfig.json index 8510b9a1c6..1e10b382d8 100644 --- a/packages/ui5-test-writer/tsconfig.json +++ b/packages/ui5-test-writer/tsconfig.json @@ -1,15 +1,20 @@ { - "extends": "../../tsconfig.json", - "include": [ - "../../types/mem-fs-editor.d.ts", - "src", - "src/**/*.json" - ], - "compilerOptions": { - "rootDir": "src", - "outDir": "dist" + "extends": "../../tsconfig.json", + "include": [ + "../../types/mem-fs-editor.d.ts", + "src", + "src/**/*.json" + ], + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "references": [ + { + "path": "../project-access" }, - "references": [ - { "path": "../project-access" } - ] + { + "path": "../ui5-application-writer" + } + ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4970074cb9..c27e604baf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3818,6 +3818,9 @@ importers: packages/ui5-test-writer: dependencies: + '@sap-ux/ui5-application-writer': + specifier: workspace:* + version: link:../ui5-application-writer ejs: specifier: 3.1.10 version: 3.1.10 From 76f172aea3e0032979fa7b91d6793386426fdcdd Mon Sep 17 00:00:00 2001 From: I743583 Date: Mon, 17 Feb 2025 12:22:00 +0000 Subject: [PATCH 09/42] revert shared gen util --- .../src/npm-package-scripts/getPackageScripts.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts index d0c2034ef5..cc6f026bc4 100644 --- a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts +++ b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts @@ -140,13 +140,13 @@ export function getPackageScripts({ scripts['start-mock'] = `fiori run --config ./ui5-mock.yaml --open "test/flpSandbox.html${params}"`; } - scripts['start-variants-management'] = localOnly - ? `echo \\"${t('info.mockOnlyWarning')}\\"` - : getVariantPreviewAppScript(sapClient); - if (addTest) { scripts['int-test'] = 'fiori run --config ./ui5-mock.yaml --open "test/integration/opaTests.qunit.html"'; } + + scripts['start-variants-management'] = localOnly + ? `echo \\"${t('info.mockOnlyWarning')}\\"` + : getVariantPreviewAppScript(sapClient); return scripts; } From 5362388be51a41d494c785dae6c1c0679bcd11a7 Mon Sep 17 00:00:00 2001 From: I743583 Date: Tue, 18 Feb 2025 09:59:49 +0000 Subject: [PATCH 10/42] removing namespace use for freestyle tests --- packages/fiori-elements-writer/src/index.ts | 4 ++-- packages/fiori-freestyle-writer/src/index.ts | 3 +-- packages/fiori-freestyle-writer/src/types.ts | 1 - .../npm-package-scripts/getPackageScripts.ts | 2 +- .../src/fiori-elements-opa-writer.ts | 13 +++++++++++-- .../src/fiori-freestyle-opa-writer.ts | 18 ++++++------------ packages/ui5-test-writer/src/index.ts | 2 +- packages/ui5-test-writer/src/types.ts | 1 - .../templates/common/testsuite.qunit.html | 16 ++++++++-------- .../templates/common/testsuite.qunit.js | 8 ++++---- 10 files changed, 34 insertions(+), 34 deletions(-) diff --git a/packages/fiori-elements-writer/src/index.ts b/packages/fiori-elements-writer/src/index.ts index 2467f96bfa..0159545e30 100644 --- a/packages/fiori-elements-writer/src/index.ts +++ b/packages/fiori-elements-writer/src/index.ts @@ -4,7 +4,7 @@ import { render } from 'ejs'; import type { App, Package } from '@sap-ux/ui5-application-writer'; import { generate as generateUi5Project } from '@sap-ux/ui5-application-writer'; import { generate as addOdataService, OdataVersion, ServiceType } from '@sap-ux/odata-service-writer'; -import { generateFioriElementsOPAFiles } from '@sap-ux/ui5-test-writer'; +import { generateOPAFiles } from '@sap-ux/ui5-test-writer'; import cloneDeep from 'lodash/cloneDeep'; import type { FioriElementsApp } from './types'; import { TemplateType } from './types'; @@ -206,7 +206,7 @@ async function generate( fs.writeJSON(packagePath, packageJson); if (addTest) { - generateFioriElementsOPAFiles( + generateOPAFiles( basePath, { htmlTarget: feApp.appOptions?.generateIndex diff --git a/packages/fiori-freestyle-writer/src/index.ts b/packages/fiori-freestyle-writer/src/index.ts index 76a046e404..1d2c51cc31 100644 --- a/packages/fiori-freestyle-writer/src/index.ts +++ b/packages/fiori-freestyle-writer/src/index.ts @@ -14,7 +14,7 @@ import { getBootstrapResourceUrls, getPackageScripts } from '@sap-ux/fiori-gener import { getTemplateVersionPath, processDestinationPath } from './utils'; import { applyCAPUpdates, type CapProjectSettings } from '@sap-ux/cap-config-writer'; import type { Logger } from '@sap-ux/logger'; -import { generateFreestyleOPAFiles } from '../../ui5-test-writer'; +import { generateFreestyleOPAFiles } from '@sap-ux/ui5-test-writer'; /** * Generates and writes OPA test files based on the provided application configuration. @@ -35,7 +35,6 @@ export async function writeOPATestFiles( appId: ffApp.app.id, applicationDescription: ffApp.app.description, applicationTitle: ffApp.app.title, - namespace: ffApp.app.namespace, viewName: (ffApp.template.settings as BasicAppSettings).viewName, ui5Theme: ffApp.ui5?.ui5Theme, ui5Version: ffApp.ui5?.version, diff --git a/packages/fiori-freestyle-writer/src/types.ts b/packages/fiori-freestyle-writer/src/types.ts index bdb0eda097..c33411f1b4 100644 --- a/packages/fiori-freestyle-writer/src/types.ts +++ b/packages/fiori-freestyle-writer/src/types.ts @@ -37,7 +37,6 @@ export interface Template { } export interface FioriApp extends App { flpAppId?: string; - namespace?: string; } export interface FreestyleApp extends Ui5App { template: Template; diff --git a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts index cc6f026bc4..f2fff16169 100644 --- a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts +++ b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts @@ -143,7 +143,7 @@ export function getPackageScripts({ if (addTest) { scripts['int-test'] = 'fiori run --config ./ui5-mock.yaml --open "test/integration/opaTests.qunit.html"'; } - + scripts['start-variants-management'] = localOnly ? `echo \\"${t('info.mockOnlyWarning')}\\"` : getVariantPreviewAppScript(sapClient); diff --git a/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts index 9a39a2fbb4..1fcdd04dae 100644 --- a/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts @@ -262,7 +262,7 @@ function writePageObject( * @param fs - an optional reference to a mem-fs editor * @returns Reference to a mem-fs-editor */ -export function generateFioriElementsOPAFiles( +export function generateOPAFiles( basePath: string, opaConfig: { scriptName?: string; appID?: string; htmlTarget?: string }, fs?: Editor @@ -279,7 +279,16 @@ export function generateFioriElementsOPAFiles( const testOutDirPath = join(basePath, 'webapp/test'); // Common test files - editor.copy(join(rootCommonTemplateDirPath), testOutDirPath); + editor.copyTpl( + join(rootCommonTemplateDirPath), + testOutDirPath, + // unit tests are not added for Fiori elements app + { appId: config.appID, addUnitTests: false }, + undefined, + { + globOptions: { dot: true } + } + ); // Integration (OPA) test files - version-specific editor.copyTpl( diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 3a7d2646c1..9f0887c1f9 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -126,7 +126,7 @@ async function copyTestFiles( testOutDirPath, { appId: opaConfig.appId, - addUnitTests: false + addUnitTests: Boolean(true) // EJS requires value to be explicitly set to Boolean(true) to render as true }, undefined, { @@ -144,19 +144,13 @@ async function copyTestFiles( /** * Generates formatted application ID with slashes based on namespace, name, and TypeScript settings. * - * @param {string} [name] - The application name. - * @param {string} [namespace] - The application namespace. + * @param {string} [appId] - The application id. * @param {boolean} [enableTypescript] - Whether TypeScript is enabled. * @returns {string} The formatted application ID with slashes. */ -function getAppIdWithSlash(name: string = '', namespace: string = '', enableTypescript: boolean = false): string { - // Replace dots with slashes in the namespace and remove any trailing slash - const formattedNamespace = namespace.replace(/\./g, '/').replace(/\/$/, ''); - +function getAppIdWithSlash(appId: string = '', enableTypescript: boolean = false): string { // Construct the AppIdWithSlash based on the conditions - const appIdWithSlash = enableTypescript - ? `${formattedNamespace}${namespace ? '/' : ''}${name.replace(/[_-]/g, '')}` - : `${namespace.replace(/\./g, '')}${namespace ? '/' : ''}${name}`; + const appIdWithSlash = enableTypescript ? appId.replace(/\_/g, '') : appId; return appIdWithSlash; } @@ -177,13 +171,13 @@ export async function generateFreestyleOPAFiles( log?: Logger ): Promise { const fsEditor = fs ?? create(createStorage()); - const { enableTypeScript, ui5Version, viewName, namespace } = opaConfig; + const { enableTypeScript, ui5Version, viewName } = opaConfig; const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/webapp/test'); const testOutDirPath = join(basePath, 'webapp/test'); const templateUi5Version = getTemplateUi5Version(ui5Version); const projectName = readPackage(fsEditor, basePath).name; - const appIdWithSlash = getAppIdWithSlash(projectName, namespace, enableTypeScript); + const appIdWithSlash = getAppIdWithSlash(projectName, enableTypeScript); // Get template files const templateFiles = await getFilePaths(freestyleTemplateDirPath); diff --git a/packages/ui5-test-writer/src/index.ts b/packages/ui5-test-writer/src/index.ts index e7e7aceb2f..0427ffe41c 100644 --- a/packages/ui5-test-writer/src/index.ts +++ b/packages/ui5-test-writer/src/index.ts @@ -1,2 +1,2 @@ -export { generateFioriElementsOPAFiles } from './fiori-elements-opa-writer'; +export { generateOPAFiles } from './fiori-elements-opa-writer'; export { generateFreestyleOPAFiles } from './fiori-freestyle-opa-writer'; diff --git a/packages/ui5-test-writer/src/types.ts b/packages/ui5-test-writer/src/types.ts index 174b29f65a..04ddbd3a55 100644 --- a/packages/ui5-test-writer/src/types.ts +++ b/packages/ui5-test-writer/src/types.ts @@ -64,7 +64,6 @@ export class ValidationError extends Error { */ export interface FFOPAConfig { appId: string; - namespace?: string; applicationTitle?: string; applicationDescription?: string; enableTypeScript?: boolean; diff --git a/packages/ui5-test-writer/templates/common/testsuite.qunit.html b/packages/ui5-test-writer/templates/common/testsuite.qunit.html index 850363da67..13e19b05c2 100644 --- a/packages/ui5-test-writer/templates/common/testsuite.qunit.html +++ b/packages/ui5-test-writer/templates/common/testsuite.qunit.html @@ -1,11 +1,11 @@ - - - QUnit test suite for <%= appId %> - - - - - + + + QUnit test suite for <%= appId %> + + + + + diff --git a/packages/ui5-test-writer/templates/common/testsuite.qunit.js b/packages/ui5-test-writer/templates/common/testsuite.qunit.js index 050b8c5119..9b64c09779 100644 --- a/packages/ui5-test-writer/templates/common/testsuite.qunit.js +++ b/packages/ui5-test-writer/templates/common/testsuite.qunit.js @@ -3,14 +3,14 @@ // eslint-disable-next-line fiori-custom/sap-no-global-define <% } -%> window.suite = function() { - "use strict"; + 'use strict'; // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); - <% if (addUnitTests === true) { %>oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html");<% } %> - oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + <% if (addUnitTests === true) { %>oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html');<% } %> + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); return oSuite; }; \ No newline at end of file From 79398f53959222dc825a197c6389863f053e1d56 Mon Sep 17 00:00:00 2001 From: I743583 Date: Tue, 18 Feb 2025 10:05:29 +0000 Subject: [PATCH 11/42] add logger to package json --- packages/fiori-freestyle-writer/package.json | 1 + packages/ui5-test-writer/package.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/fiori-freestyle-writer/package.json b/packages/fiori-freestyle-writer/package.json index 178a9278eb..00094267ce 100644 --- a/packages/fiori-freestyle-writer/package.json +++ b/packages/fiori-freestyle-writer/package.json @@ -38,6 +38,7 @@ "@sap-ux/fiori-generator-shared": "workspace:*", "@sap-ux/cap-config-writer": "workspace:*", "@sap-ux/ui5-test-writer": "workspace:*", + "@sap-ux/logger": "workspace:*", "ejs": "3.1.10", "i18next": "20.6.1", "lodash": "4.17.21", diff --git a/packages/ui5-test-writer/package.json b/packages/ui5-test-writer/package.json index 687a45b707..666beaddec 100644 --- a/packages/ui5-test-writer/package.json +++ b/packages/ui5-test-writer/package.json @@ -36,7 +36,8 @@ "i18next": "20.6.1", "mem-fs": "2.1.0", "mem-fs-editor": "9.4.0", - "@sap-ux/ui5-application-writer": "workspace:*" + "@sap-ux/ui5-application-writer": "workspace:*", + "@sap-ux/logger": "workspace:*" }, "devDependencies": { "@sap-ux/project-access": "workspace:*", From 095383360514b09023ae2afb0dcc8b8a9ad9e7cf Mon Sep 17 00:00:00 2001 From: I743583 Date: Tue, 18 Feb 2025 10:13:30 +0000 Subject: [PATCH 12/42] pnpm recursive install --- packages/fiori-freestyle-writer/tsconfig.json | 3 +++ packages/ui5-test-writer/tsconfig.json | 3 +++ pnpm-lock.yaml | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/packages/fiori-freestyle-writer/tsconfig.json b/packages/fiori-freestyle-writer/tsconfig.json index 4fa4674b37..c2cf5f7754 100644 --- a/packages/fiori-freestyle-writer/tsconfig.json +++ b/packages/fiori-freestyle-writer/tsconfig.json @@ -19,6 +19,9 @@ { "path": "../fiori-generator-shared" }, + { + "path": "../logger" + }, { "path": "../odata-service-writer" }, diff --git a/packages/ui5-test-writer/tsconfig.json b/packages/ui5-test-writer/tsconfig.json index 1e10b382d8..720c0e4986 100644 --- a/packages/ui5-test-writer/tsconfig.json +++ b/packages/ui5-test-writer/tsconfig.json @@ -10,6 +10,9 @@ "outDir": "dist" }, "references": [ + { + "path": "../logger" + }, { "path": "../project-access" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c27e604baf..83be9f8418 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1898,6 +1898,9 @@ importers: '@sap-ux/fiori-generator-shared': specifier: workspace:* version: link:../fiori-generator-shared + '@sap-ux/logger': + specifier: workspace:* + version: link:../logger '@sap-ux/odata-service-writer': specifier: workspace:* version: link:../odata-service-writer @@ -3818,6 +3821,9 @@ importers: packages/ui5-test-writer: dependencies: + '@sap-ux/logger': + specifier: workspace:* + version: link:../logger '@sap-ux/ui5-application-writer': specifier: workspace:* version: link:../ui5-application-writer From 50021a0084d38679ec37c3652d96a7a4f44dfee3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Feb 2025 11:04:03 +0000 Subject: [PATCH 13/42] Linting auto fix commit --- packages/fiori-freestyle-writer/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fiori-freestyle-writer/src/index.ts b/packages/fiori-freestyle-writer/src/index.ts index 1d2c51cc31..8e860382ca 100644 --- a/packages/fiori-freestyle-writer/src/index.ts +++ b/packages/fiori-freestyle-writer/src/index.ts @@ -165,7 +165,7 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor, const addTests = ffApp.appOptions?.addTests; const packageJson: Package = JSON.parse(fs.read(packagePath)); - + if (isEdmxProjectType) { const addMock = !!ffApp.service?.metadata; // Add scripts for non-CAP applications From 06cd7feaaeda3d3d5cafcf65076906f33ca7bcaa Mon Sep 17 00:00:00 2001 From: I743583 Date: Tue, 18 Feb 2025 14:13:23 +0000 Subject: [PATCH 14/42] remove namespace reference and improvise code --- .../src/fiori-freestyle-opa-writer.ts | 188 +++++++----------- .../translations/ui5-test-writer.i18n.json | 2 +- .../freestyle/webapp/test/flpSandbox.js | 2 +- .../webapp/test/integration/opaTests.qunit.js | 2 +- 4 files changed, 75 insertions(+), 119 deletions(-) diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 9f0887c1f9..0155038e5f 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -5,30 +5,9 @@ import { create } from 'mem-fs-editor'; import type { FFOPAConfig } from './types'; import type { Logger } from '@sap-ux/logger'; import { getFilePaths } from '@sap-ux/project-access'; -import type { Package } from '@sap-ux/project-access'; -import { ValidationError } from './types'; import { t } from './i18n'; import { compareUI5VersionGte, ui5LtsVersion_1_71 } from '@sap-ux/ui5-application-writer'; -/** - * Reads the Package for an app. - * - * @param fs - a reference to a mem-fs editor - * @param basePath - the root folder of the app - * @returns the Package object. An exception is thrown if the Package cannot be read. - */ -export function readPackage(fs: Editor, basePath: string): Package { - const packageJose = fs.readJSON(join(basePath, 'package.json')) as any as Package; - if (!packageJose) { - throw new ValidationError( - t('error.cannotReadPackage', { - filePath: join(basePath, 'package.json') - }) - ); - } - return packageJose; -} - /** * Updates tsconfig.json to include paths for unit and integration tests. * @@ -52,16 +31,6 @@ function writeOPATsconfigJsonUpdates(fs: Editor, destinationRoot: string, log?: } } -/** - * Formats a namespace by replacing dots with slashes. - * - * @param {string} namespace - The namespace to format. - * @returns {string} - Formatted namespace. - */ -function formatNamespace(namespace: string): string { - return namespace.replace(/\./g, '/'); -} - /** * Gets the template UI5 version based on the provided UI5 version. * @@ -80,81 +49,45 @@ function getTemplateUi5Version(ui5Version?: string): string { * Copies filtered test template files from source directory to destination directory, * with file renaming logic based on the view name. * - * @param {string} freestyleTemplateDirPath - The path to the source directory containing template files. - * @param {string} testOutDirPath - The path to the destination directory where files should be copied. + * @param {string} sourceDir - The path to the source directory containing template files. + * @param {string} ouputDir - The path to the destination directory where files should be copied. * @param {string[]} filteredFiles - An array of filtered file paths to copy. * @param {FFOPAConfig} opaConfig - The OPA test configuration object to write into template files. * @param {Editor} editor - The editor instance used to copy and render template files. * @param {Logger} [log] - The logger instance. - * @returns {Promise} - A promise that resolves to `true` if the files were copied successfully, + * @param {Record} [renameMap] - Optional rename mapping for file paths. + * @returns {boolean} - resolves to `true` if the files were copied successfully, * or `false` if there was an error during the process. */ -async function copyTestFiles( - freestyleTemplateDirPath: string, - testOutDirPath: string, +function copyTemplates( + sourceDir: string, + ouputDir: string, filteredFiles: string[], - opaConfig: FFOPAConfig, + opaConfig: FFOPAConfig & { addUnitTests?: boolean }, editor: Editor, - log?: Logger -): Promise { + log?: Logger, + renameMap?: Record +): boolean { try { filteredFiles.forEach((filePath: string) => { - const sourceFilePath = join(freestyleTemplateDirPath, filePath); - let destinationFilePath = join(testOutDirPath, filePath); - const viewName = opaConfig.viewName; - - // Rename files: - // - viewName.js files are renamed to include the view name in their file path - // - viewName.ts files are renamed with the view name appended with 'Page' - const renameMap: Record = { - '/integration/pages/viewName.js': `integration/pages/${viewName}.js`, - '/integration/pages/viewName.ts': `integration/pages/${viewName}Page.ts`, - '/unit/controller/viewName.controller.js': `unit/controller/${viewName}.controller.js`, - '/unit/controller/viewName.controller.ts': `unit/controller/${viewName}Page.controller.ts` - }; - - if (renameMap[filePath]) { - destinationFilePath = join(testOutDirPath, renameMap[filePath]); - } - editor.copyTpl(sourceFilePath, destinationFilePath, { ...opaConfig, formatNamespace }, undefined, { - globOptions: { dot: true } - }); + const destFilePath = filePath.replace(sourceDir, ''); + const destinationFilePath = join(ouputDir, renameMap?.[destFilePath] ?? destFilePath); + editor.copyTpl( + filePath, + destinationFilePath, + opaConfig, + undefined, { + globOptions: { dot: true } + } + ); }); - const rootCommonTemplateDirPath = join(__dirname, '../templates/common'); - editor.copyTpl( - rootCommonTemplateDirPath, - testOutDirPath, - { - appId: opaConfig.appId, - addUnitTests: Boolean(true) // EJS requires value to be explicitly set to Boolean(true) to render as true - }, - undefined, - { - globOptions: { dot: true } - } - ); - return true; } catch (error) { - log?.error(`Error copying files: ${error}`); + log?.error(t('error.errorCopyingFreestyleTestTemplates: ', error)); return false; } } -/** - * Generates formatted application ID with slashes based on namespace, name, and TypeScript settings. - * - * @param {string} [appId] - The application id. - * @param {boolean} [enableTypescript] - Whether TypeScript is enabled. - * @returns {string} The formatted application ID with slashes. - */ -function getAppIdWithSlash(appId: string = '', enableTypescript: boolean = false): string { - // Construct the AppIdWithSlash based on the conditions - const appIdWithSlash = enableTypescript ? appId.replace(/\_/g, '') : appId; - - return appIdWithSlash; -} - /** * Generates and copies freestyle test files based on configuration. * @@ -171,55 +104,78 @@ export async function generateFreestyleOPAFiles( log?: Logger ): Promise { const fsEditor = fs ?? create(createStorage()); - const { enableTypeScript, ui5Version, viewName } = opaConfig; + const { enableTypeScript, ui5Version, viewName, appId } = opaConfig; + + const freestyleTemplateDir = join(__dirname, '../templates/freestyle/webapp/test'); + const commonTemplateDir = join(__dirname, '../templates/common'); + const testOutDir = join(basePath, 'webapp/test'); - const freestyleTemplateDirPath = join(__dirname, '../templates/freestyle/webapp/test'); - const testOutDirPath = join(basePath, 'webapp/test'); const templateUi5Version = getTemplateUi5Version(ui5Version); - const projectName = readPackage(fsEditor, basePath).name; - const appIdWithSlash = getAppIdWithSlash(projectName, enableTypeScript); + const appIdWithSlash = appId.replace(/\./g, '/'); // Replace all dots with slashes + const navigationIntent = appId.replace(/[./\\\-\s]/g, ''); // Remove all dots, slashes, dashes, and spaces - // Get template files - const templateFiles = await getFilePaths(freestyleTemplateDirPath); + const templateFiles = await getFilePaths(freestyleTemplateDir); const isTypeScript = Boolean(enableTypeScript); - const commonJSTemplateFiles = ['initFlpSandbox.js', 'flpSandbox.js']; + const commonJSTemplates = ['initFlpSandbox.js', 'flpSandbox.js']; // Filter files based on TypeScript setting: // - If TypeScript is enabled, include only .ts files // - If TypeScript is disabled, include only .js files // - Include common JS files regardless of TypeScript setting - const filteredFiles = templateFiles - .filter((filePath: string) => { - if (filePath.endsWith('.ts')) { - return isTypeScript; - } - if (filePath.endsWith('.js')) { - const includeCommonJSTemplate = - commonJSTemplateFiles.includes(basename(filePath)) && templateUi5Version === '1.71.0'; - return !isTypeScript || includeCommonJSTemplate; - } - return true; // keep other .html files - }) - .map((filePath: string) => filePath.replace(freestyleTemplateDirPath, '')); + const filteredFiles = templateFiles.filter((filePath: string) => { + if (filePath.endsWith('.ts')) { + return isTypeScript; + } + if (filePath.endsWith('.js')) { + const includeCommonJSTemplate = + commonJSTemplates.includes(basename(filePath)) && templateUi5Version === '1.71.0'; + return !isTypeScript || includeCommonJSTemplate; + } + return true; // keep other .html files + }); const config = { ...opaConfig, viewNamePage: `${viewName}Page`, appIdWithSlash, ui5Version: templateUi5Version, - navigationIntent: opaConfig.appId.replace(/[./\\\-\s]/g, '') + navigationIntent }; - const filesCopiedSuccessfully = await copyTestFiles( - freestyleTemplateDirPath, - testOutDirPath, + + // Rename files: + // - viewName.js files are renamed to include the view name in their file path + // - viewName.ts files are renamed with the view name appended with 'Page' + const renameMap: Record = { + '/integration/pages/viewName.js': `integration/pages/${viewName}.js`, + '/integration/pages/viewName.ts': `integration/pages/${viewName}Page.ts`, + '/unit/controller/viewName.controller.js': `unit/controller/${viewName}.controller.js`, + '/unit/controller/viewName.controller.ts': `unit/controller/${viewName}Page.controller.ts` + }; + // copy freestyle templates + const freestyleTestTemplatesCopied = copyTemplates( + freestyleTemplateDir, + testOutDir, filteredFiles, config, fsEditor, + log, + renameMap + ); + + // copy common templates + const commonFiles = await getFilePaths(commonTemplateDir); + const filteredCommonFiles = commonFiles.filter((filePath: string) => !filePath.endsWith('.js') || !isTypeScript); + + const commonTemplatesCopied = copyTemplates( + commonTemplateDir, + testOutDir, + filteredCommonFiles, + { appId, addUnitTests: true }, + fsEditor, log ); - // If files are copied successfully, update the package.json and tsconfig files - if (filesCopiedSuccessfully && isTypeScript) { + if (commonTemplatesCopied && freestyleTestTemplatesCopied && isTypeScript) { writeOPATsconfigJsonUpdates(fsEditor, basePath, log); } diff --git a/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json b/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json index 14ecb4cb8c..f7c67c3779 100644 --- a/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json +++ b/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json @@ -4,6 +4,6 @@ "cannotReadAppID": "Cannot read appID in the manifest file", "badApplicationType": "Cannot determine application type from the manifest, or unsupported type", "cannotGeneratePageFile": "Cannot generate page file for target {{ targetKey }}", - "cannotReadPackage": "Cannot read package.json file {{ filePath }}" + "errorCopyingFreestyleTestTemplates": "Error copying freestyle test templates" } } diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js index db155979e7..684c6ddb22 100644 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js @@ -62,7 +62,7 @@ sap.ui.define([ "resolutionResult": { "applicationType": "SAPUI5", "additionalInformation": "SAPUI5.Component=<%= appId %>", - "url": sap.ui.require.toUrl("<%= formatNamespace(appId) %>") + "url": sap.ui.require.toUrl("<%= appIdWithSlash %>") } } } diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js index 4cae4b312f..9f61e8cf7e 100644 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js @@ -1,6 +1,6 @@ /* global QUnit */ -sap.ui.require(["<%= formatNamespace(appId) %>/test/integration/AllJourneys" +sap.ui.require(["<%= appIdWithSlash %>/test/integration/AllJourneys" ], function () { QUnit.config.autostart = false; QUnit.start(); From c1af110f8d01aad598aa3fb8cd761b865d05135d Mon Sep 17 00:00:00 2001 From: I743583 Date: Tue, 18 Feb 2025 14:17:40 +0000 Subject: [PATCH 15/42] remove unwanted type --- packages/fiori-generator-shared/src/npm-package-scripts/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/fiori-generator-shared/src/npm-package-scripts/types.ts b/packages/fiori-generator-shared/src/npm-package-scripts/types.ts index 0078089434..ff913b92de 100644 --- a/packages/fiori-generator-shared/src/npm-package-scripts/types.ts +++ b/packages/fiori-generator-shared/src/npm-package-scripts/types.ts @@ -38,5 +38,4 @@ export interface PackageScriptsOptions { localStartFile?: string; /** If true, a script for starting the app without flp will be generated. Defaults to true. */ generateIndex?: boolean; - hasService?: boolean; } From cfebc57e0d9e84cb031e36f267429dbdf9a64065 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Feb 2025 14:25:07 +0000 Subject: [PATCH 16/42] Linting auto fix commit --- .../ui5-test-writer/src/fiori-freestyle-opa-writer.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 0155038e5f..58720b3987 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -72,14 +72,9 @@ function copyTemplates( filteredFiles.forEach((filePath: string) => { const destFilePath = filePath.replace(sourceDir, ''); const destinationFilePath = join(ouputDir, renameMap?.[destFilePath] ?? destFilePath); - editor.copyTpl( - filePath, - destinationFilePath, - opaConfig, - undefined, { - globOptions: { dot: true } - } - ); + editor.copyTpl(filePath, destinationFilePath, opaConfig, undefined, { + globOptions: { dot: true } + }); }); return true; } catch (error) { From a146d300ade82c34861dae1fabc81fa0621e0840 Mon Sep 17 00:00:00 2001 From: I743583 Date: Wed, 19 Feb 2025 09:08:31 +0000 Subject: [PATCH 17/42] add tests for freestyle templates --- .../src/fiori-freestyle-opa-writer.ts | 22 +++++++++---------- .../translations/ui5-test-writer.i18n.json | 3 ++- .../ui5-test-writer/test/unit/index.test.ts | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 0155038e5f..3ce693b4cf 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -27,7 +27,9 @@ function writeOPATsconfigJsonUpdates(fs: Editor, destinationRoot: string, log?: fs.writeJSON(join(destinationRoot, 'tsconfig.json'), tsconfig); } catch (error) { - log?.error(`Error updating tsconfig.json: ${error}`); + log?.error(t('error.errorWritingTsConfig', { + error: error + })); } } @@ -72,18 +74,15 @@ function copyTemplates( filteredFiles.forEach((filePath: string) => { const destFilePath = filePath.replace(sourceDir, ''); const destinationFilePath = join(ouputDir, renameMap?.[destFilePath] ?? destFilePath); - editor.copyTpl( - filePath, - destinationFilePath, - opaConfig, - undefined, { - globOptions: { dot: true } - } - ); + editor.copyTpl(filePath, destinationFilePath, opaConfig, undefined, { + globOptions: { dot: true } + }); }); return true; } catch (error) { - log?.error(t('error.errorCopyingFreestyleTestTemplates: ', error)); + log?.error(t('error.errorCopyingFreestyleTestTemplates', { + error: error + })); return false; } } @@ -139,7 +138,8 @@ export async function generateFreestyleOPAFiles( viewNamePage: `${viewName}Page`, appIdWithSlash, ui5Version: templateUi5Version, - navigationIntent + navigationIntent, + ui5Theme: opaConfig.ui5Theme ?? '' }; // Rename files: diff --git a/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json b/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json index f7c67c3779..39bd08855b 100644 --- a/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json +++ b/packages/ui5-test-writer/src/translations/ui5-test-writer.i18n.json @@ -4,6 +4,7 @@ "cannotReadAppID": "Cannot read appID in the manifest file", "badApplicationType": "Cannot determine application type from the manifest, or unsupported type", "cannotGeneratePageFile": "Cannot generate page file for target {{ targetKey }}", - "errorCopyingFreestyleTestTemplates": "Error copying freestyle test templates" + "errorCopyingFreestyleTestTemplates": "Error copying freestyle test templates: {{ error }}", + "errorWritingTsConfig": "Error writing tsconfig.json: {{ error }}" } } diff --git a/packages/ui5-test-writer/test/unit/index.test.ts b/packages/ui5-test-writer/test/unit/index.test.ts index d0878e29b7..3ca7ade315 100644 --- a/packages/ui5-test-writer/test/unit/index.test.ts +++ b/packages/ui5-test-writer/test/unit/index.test.ts @@ -1,4 +1,4 @@ -import { generateOPAFiles, generatePageObjectFile } from '../../src'; +import { generateOPAFiles, generatePageObjectFile } from '../../src/fiori-elements-opa-writer'; import { join } from 'path'; import type { Editor } from 'mem-fs-editor'; import { create as createStorage } from 'mem-fs'; From 0922a9868559dd7c45b670f4243a0304fa3a4c5e Mon Sep 17 00:00:00 2001 From: I743583 Date: Wed, 19 Feb 2025 09:17:26 +0000 Subject: [PATCH 18/42] update fiori elements tests --- .../src/fiori-freestyle-opa-writer.ts | 16 +- .../unit/__snapshots__/index.test.ts.snap | 242 ++--- .../test/unit/fiori-freestyle.test.ts | 834 ++++++++++++++++++ 3 files changed, 987 insertions(+), 105 deletions(-) create mode 100644 packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 3ce693b4cf..ee5f6ed5c7 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -27,9 +27,11 @@ function writeOPATsconfigJsonUpdates(fs: Editor, destinationRoot: string, log?: fs.writeJSON(join(destinationRoot, 'tsconfig.json'), tsconfig); } catch (error) { - log?.error(t('error.errorWritingTsConfig', { - error: error - })); + log?.error( + t('error.errorWritingTsConfig', { + error: error + }) + ); } } @@ -80,9 +82,11 @@ function copyTemplates( }); return true; } catch (error) { - log?.error(t('error.errorCopyingFreestyleTestTemplates', { - error: error - })); + log?.error( + t('error.errorCopyingFreestyleTestTemplates', { + error: error + }) + ); return false; } } diff --git a/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap b/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap index 765b9266ea..f788bc5dd3 100644 --- a/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap +++ b/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap @@ -314,25 +314,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for ui5-test-writer.test.employees + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - return oSuite; + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + + return oSuite; };", "state": "modified", }, @@ -656,25 +660,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for ui5-test-writer.test.employees + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -973,25 +981,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for ui5-test-writer.test.employees + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - return oSuite; + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + + return oSuite; };", "state": "modified", }, @@ -1290,25 +1302,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for ui5-test-writer.test.employees + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -1559,25 +1575,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for ui5-test-writer.test.employees + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -1817,25 +1837,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for ui5-test-writer.test.employees + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -2082,25 +2106,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for ui5-test-writer.test.employees + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -2486,25 +2514,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for vesc.demo.employee.project2 + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - return oSuite; + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + + return oSuite; };", "state": "modified", }, @@ -2890,25 +2922,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for vesc.demo.employee.project2 + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -3247,25 +3283,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for projectservice + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - return oSuite; + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + + return oSuite; };", "state": "modified", }, @@ -3511,25 +3551,29 @@ Object { "contents": " - QUnit test suite + + QUnit test suite for test.ui5-test-writer + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, diff --git a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts new file mode 100644 index 0000000000..9b7016e1d2 --- /dev/null +++ b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts @@ -0,0 +1,834 @@ +import { generateFreestyleOPAFiles } from '../../src'; +import { join } from 'path'; +import { create as createStorage } from 'mem-fs'; +import { create, type Editor } from 'mem-fs-editor'; +import type { Logger } from '@sap-ux/logger'; +import { t } from '../../src/i18n'; + +describe('ui5-test-writer - Freestyle OPA Integration tests', () => { + let fs: Editor | undefined; + + beforeEach(() => { + // remove specific generated app folder + fs = create(createStorage()); + }); + + /** Helper function to remove whitespaces */ + function removeSpaces(str: string) { + return str.replace(/\s+/g, ''); + } + + test('Generate OPA test files correctly when typescript is enabled', async () => { + const opaConfig = { + appId: 'test-app-typescript', + applicationTitle: 'App test', + applicationDescription: 'App description', + enableTypeScript: true, + viewName: 'view-test', + ui5Version: '1.71.0' + }; + const basePath = join('some/path'); + const testOutputPath = join(basePath, 'webapp/test'); + fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); + + const expectedFiles = [ + 'flpSandbox.js', + 'initFlpSandbox.js', + 'integration/NavigationJourney.ts', + 'integration/opaTests.qunit.html', + 'integration/pages/AppPage.ts', + 'integration/pages/view-testPage.ts', + 'testsuite.qunit.ts', + 'unit/controller/view-testPage.controller.ts', + 'unit/unitTests.qunit.html', + 'unit/unitTests.qunit.ts' + ]; + expectedFiles.map((file: string) => { + expect(fs?.exists(join(testOutputPath, file))).toBe(true); + }); + // check tsconfig.json + const tsConfigJson = fs?.readJSON(join(basePath, 'tsconfig.json')); + expect(tsConfigJson).toEqual({ + 'compilerOptions': { + 'paths': { + 'unit/*': ['./webapp/test/unit/*'], + 'integration/*': ['./webapp/test/integration/*'] + } + } + }); + + // check testsuite.qunit.html + const testSuiteHTML = fs?.read(join(testOutputPath, 'testsuite.qunit.html')); + expect(removeSpaces(testSuiteHTML)).toBe( + removeSpaces(` + + + + + QUnit test suite for ${opaConfig.appId} + + + + + + `) + ); + + // check unit/unitTests.qunit.ts + const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.ts')); + expect(removeSpaces(unitTestQUnit)).toBe( + removeSpaces(` + /* global QUnit */ + // https://api.qunitjs.com/config/autostart/ + QUnit.config.autostart = false; + + // import all your QUnit tests here + void Promise.all([ + import("unit/controller/view-testPage.controller") + ]).then(() => { + QUnit.start(); + });`) + ); + + // check unit/unitTests.qunit.html + const unitTestHTML = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.html')); + expect(removeSpaces(unitTestHTML)).toBe( + removeSpaces(` + + + + + Unit tests for ${opaConfig.appId} + + + + + + + + + +
+
+ + `) + ); + + // check unit/controller/view-testPage.controller.ts + const viewTestController = fs?.read(join(testOutputPath, 'unit/controller/view-testPage.controller.ts')); + expect(removeSpaces(viewTestController)).toBe( + removeSpaces(` + /*global QUnit*/ + import Controller from "${opaConfig.appId}/controller/${opaConfig.viewName}.controller"; + + QUnit.module("${opaConfig.viewName} Controller"); + + QUnit.test("I should test the ${opaConfig.viewName} controller", function (assert: Assert) { + const oAppController = new Controller("${opaConfig.viewName}"); + oAppController.onInit(); + assert.ok(oAppController); + }); + `) + ); + + // check test/testsuite.qunit.ts + const testSuiteQUnit = fs?.read(join(testOutputPath, 'testsuite.qunit.ts')); + expect(removeSpaces(testSuiteQUnit)).toBe( + removeSpaces(` + /* global window, parent, location */ + + // eslint-disable-next-line fiori-custom/sap-no-global-define,@typescript-eslint/ban-ts-comment + // @ts-nocheck + window.suite = function() { + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + + oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); + oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); + + return oSuite; + }; + `) + ); + + // check integration/pages/view-testPage.ts + const viewTestPage = fs?.read(join(testOutputPath, 'integration/pages/view-testPage.ts')); + expect(removeSpaces(viewTestPage)).toBe( + removeSpaces(` + import Opa5 from "sap/ui/test/Opa5"; + + const sViewName = "${opaConfig.viewName}"; + + export default class ${opaConfig.viewName}Page extends Opa5 { + // Actions + + + // Assertions + iShouldSeeThePageView() { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + + }`) + ); + + // check integration/pages/AppPage.ts + const appPage = fs?.read(join(testOutputPath, 'integration/pages/AppPage.ts')); + expect(removeSpaces(appPage)).toBe( + removeSpaces(` + import Opa5 from "sap/ui/test/Opa5"; + + const sViewName = "App"; + + export default class AppPage extends Opa5 { + // Actions + + + // Assertions + iShouldSeeTheApp() { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + + } + `) + ); + + // check integration/opaTests.qunit.ts + const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.ts')); + expect(removeSpaces(opaTests)).toBe( + removeSpaces(` + /* global QUnit */ + // https://api.qunitjs.com/config/autostart/ + QUnit.config.autostart = false; + + // import all your OPA journeys here + void Promise.all([ + import("integration/NavigationJourney") + ]).then(() => { + QUnit.start(); + });`) + ); + + // check integration/opaTests.qunit.html + const opaTestsHTML = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.html')); + expect(removeSpaces(opaTestsHTML)).toBe( + removeSpaces(` + + + + + Integration tests for Basic Template + + + + + + + +
+
+ + + `) + ); + + // check integration/NavigationJourney.ts + const navigationJourney = fs?.read(join(testOutputPath, 'integration/NavigationJourney.ts')); + expect(removeSpaces(navigationJourney)).toBe( + removeSpaces(` + /*global QUnit*/ + import opaTest from "sap/ui/test/opaQunit"; + import AppPage from "./pages/AppPage"; + import ViewPage from "./pages/view-testPage"; + + import Opa5 from "sap/ui/test/Opa5"; + + QUnit.module("Navigation Journey"); + + const onTheAppPage = new AppPage(); + const onTheViewPage = new ViewPage(); + Opa5.extendConfig({ + viewNamespace: "test-app-typescript.view.", + autoWait: true + }); + + opaTest("Should see the initial page of the app", function () { + // Arrangements + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iStartMyUIComponent({ + componentConfig: { + name: "${opaConfig.appId}" + } + }); + + // Assertions + onTheAppPage.iShouldSeeTheApp(); + onTheViewPage.iShouldSeeThePageView(); + + + // Cleanup + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iTeardownMyApp(); + }); + `) + ); + + // check initFlpSandbox.js + const initFlpSandbox = fs?.read(join(testOutputPath, 'initFlpSandbox.js')); + expect(removeSpaces(initFlpSandbox)).toBe( + removeSpaces(` + sap.ui.define([ + "./flpSandbox", + "sap/ui/fl/FakeLrepConnectorLocalStorage", + "sap/m/MessageBox" + ], function (flpSandbox, FakeLrepConnectorLocalStorage, MessageBox) { + "use strict"; + + flpSandbox.init().then(function () { + FakeLrepConnectorLocalStorage.enableFakeConnector(); + }, function (oError) { + MessageBox.error(oError.message); + }); + }); + `) + ); + + // check flpSandbox.js + const flpSandbox = fs?.read(join(testOutputPath, 'flpSandbox.js')); + expect(removeSpaces(flpSandbox)).toBe( + removeSpaces(` + sap.ui.define([ + "sap/base/util/ObjectPath", + "sap/ushell/services/Container" + ], function (ObjectPath) { + "use strict"; + + // define ushell config + ObjectPath.set(["sap-ushell-config"], { + defaultRenderer: "fiori2", + bootstrapPlugins: { + "RuntimeAuthoringPlugin": { + component: "sap.ushell.plugins.rta", + config: { + validateAppVersion: false + } + }, + "PersonalizePlugin": { + component: "sap.ushell.plugins.rta-personalize", + config: { + validateAppVersion: false + } + } + }, + renderers: { + fiori2: { + componentData: { + config: { + enableSearch: false, + rootIntent: "Shell-home" + } + } + } + }, + services: { + "LaunchPage": { + "adapter": { + "config": { + "groups": [{ + "tiles": [{ + "tileType": "sap.ushell.ui.tile.StaticTile", + "properties": { + "title": "${opaConfig.applicationTitle}", + "targetURL": "#testapptypescript-display" + } + }] + }] + } + } + }, + "ClientSideTargetResolution": { + "adapter": { + "config": { + "inbounds": { + "testapptypescript-display": { + "semanticObject": "testapptypescript", + "action": "display", + "description": "${opaConfig.applicationDescription}", + "title": "${opaConfig.applicationTitle}", + "signature": { + "parameters": {} + }, + "resolutionResult": { + "applicationType": "SAPUI5", + "additionalInformation": "SAPUI5.Component=test-app-typescript", + "url": sap.ui.require.toUrl("test-app-typescript") + } + } + } + } + } + }, + NavTargetResolution: { + config: { + "enableClientSideTargetResolution": true + } + } + } + }); + + var oFlpSandbox = { + init: function () { + /** + * Initializes the FLP sandbox + * @returns {Promise} a promise that is resolved when the sandbox bootstrap has finshed + */ + + // sandbox is a singleton, so we can start it only once + if (!this._oBootstrapFinished) { + this._oBootstrapFinished = sap.ushell.bootstrap("local"); + this._oBootstrapFinished.then(function () { + sap.ushell.Container.createRenderer().placeAt("content"); + }); + } + + return this._oBootstrapFinished; + } + }; + + return oFlpSandbox; + }); + `) + ); + }); + + test('Generate OPA test files correctly when typescript is not enabled', async () => { + const opaConfig = { + appId: 'test-app-js', + applicationTitle: 'App test', + applicationDescription: 'App description', + viewName: 'view-test', + ui5Version: '1.71.0' + }; + const basePath = join('some/path'); + const testOutputPath = join(basePath, 'webapp/test'); + fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); + + //console.log("--fs.dump", fs.dump()) + const expectedFiles = [ + 'flpSandbox.js', + 'initFlpSandbox.js', + 'integration/NavigationJourney.js', + 'integration/opaTests.qunit.html', + 'integration/pages/App.js', + 'integration/pages/view-test.js', + 'testsuite.qunit.js', + 'unit/controller/view-test.controller.js', + 'unit/unitTests.qunit.html', + 'unit/unitTests.qunit.js' + ]; + expectedFiles.map((file: string) => { + expect(fs?.exists(join(testOutputPath, file))).toBe(true); + }); + + // check unit/unitTests.qunit.js + const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.js')); + expect(removeSpaces(unitTestQUnit)).toBe( + removeSpaces(` + /* global QUnit */ + QUnit.config.autostart = false; + + sap.ui.getCore().attachInit(function () { + "use strict"; + + sap.ui.require([ + "test-app-js/test/unit/AllTests" + ], function () { + QUnit.start(); + }); + });`) + ); + + // check unit/controller/view-test.controller.js + const viewTestController = fs?.read(join(testOutputPath, 'unit/controller/view-test.controller.js')); + expect(removeSpaces(viewTestController)).toBe( + removeSpaces(` + /*global QUnit*/ + + sap.ui.define([ + "test-app-js/controller/view-test.controller" + ], function (Controller) { + "use strict"; + + QUnit.module("view-test Controller"); + + QUnit.test("I should test the view-test controller", function (assert) { + var oAppController = new Controller(); + oAppController.onInit(); + assert.ok(oAppController); + }); + + }); + `) + ); + + // check test/testsuite.qunit.js + const testSuiteQUnit = fs?.read(join(testOutputPath, 'testsuite.qunit.js')); + expect(removeSpaces(testSuiteQUnit)).toBe( + removeSpaces(` + /* global window, parent, location */ + + // eslint-disable-next-line fiori-custom/sap-no-global-define + window.suite = function() { + 'use strict'; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html'); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + + return oSuite; + }; + `) + ); + + // check integration/pages/view-test.js + const viewTest = fs?.read(join(testOutputPath, 'integration/pages/view-test.js')); + expect(removeSpaces(viewTest)).toBe( + removeSpaces(` + sap.ui.define([ + "sap/ui/test/Opa5" + ], function (Opa5) { + "use strict"; + var sViewName = "view-test"; + + Opa5.createPageObjects({ + onTheViewPage: { + + actions: {}, + + assertions: { + + iShouldSeeThePageView: function () { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + + });`) + ); + + // check integration/pages/App.js + const app = fs?.read(join(testOutputPath, 'integration/pages/App.js')); + expect(removeSpaces(app)).toBe( + removeSpaces(` + sap.ui.define([ + "sap/ui/test/Opa5" + ], function (Opa5) { + "use strict"; + var sViewName = "App"; + + Opa5.createPageObjects({ + onTheAppPage: { + + actions: {}, + + assertions: { + + iShouldSeeTheApp: function () { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + + }); + `) + ); + + // check integration/opaTests.qunit.js + const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.js')); + expect(removeSpaces(opaTests)).toBe( + removeSpaces(` + /* global QUnit */ + + sap.ui.require(["test-app-js/test/integration/AllJourneys" + ], function () { + QUnit.config.autostart = false; + QUnit.start(); + });`) + ); + + // check integration/NavigationJourney.js + const navigationJourney = fs?.read(join(testOutputPath, 'integration/NavigationJourney.js')); + expect(removeSpaces(navigationJourney)).toBe( + removeSpaces(` + /*global QUnit*/ + + sap.ui.define([ + "sap/ui/test/opaQunit", + "./pages/App", + "./pages/view-test" + ], function (opaTest) { + "use strict"; + + QUnit.module("Navigation Journey"); + + opaTest("Should see the initial page of the app", function (Given, When, Then) { + // Arrangements + Given.iStartMyApp(); + + // Assertions + Then.onTheAppPage.iShouldSeeTheApp(); + Then.onTheViewPage.iShouldSeeThePageView(); + + //Cleanup + Then.iTeardownMyApp(); + }); + }); + `) + ); + }); + + test('Generate OPA test files correctly when ui5Version is 1.120.0', async () => { + const opaConfig = { + appId: 'test-app-typescript', + applicationTitle: 'App test', + applicationDescription: 'App description', + enableTypeScript: true, + viewName: 'view-test', + ui5Version: '1.120.0' + }; + const basePath = join('some/path'); + const testOutputPath = join(basePath, 'webapp/test'); + fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); + + const expectedFiles = [ + 'integration/NavigationJourney.ts', + 'integration/opaTests.qunit.html', + 'integration/pages/AppPage.ts', + 'integration/pages/view-testPage.ts', + 'testsuite.qunit.ts', + 'unit/controller/view-testPage.controller.ts', + 'unit/unitTests.qunit.html', + 'unit/unitTests.qunit.ts' + ]; + expectedFiles.map((file: string) => { + expect(fs?.exists(join(testOutputPath, file))).toBe(true); + }); + + // check that flpSandbox & initFlpSandbox are not generated for ui5Version 1.120.0 + expect(fs.exists(join(testOutputPath, 'flpSandbox.js'))).toBe(false); + expect(fs.exists(join(testOutputPath, 'initFlpSandbox.js'))).toBe(false); + + // check unit/unitTests.qunit.ts + const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.ts')); + expect(removeSpaces(unitTestQUnit)).toBe( + removeSpaces(` + /* @sapUiRequire */ + QUnit.config.autostart = false; + + // import all your QUnit tests here + void Promise.all([ + import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests import("unit/controller/view-testPage.controller") + ]).then(([{ default: Core }]) => { + QUnit.start(); + });`) + ); + + // check unit/unitTests.qunit.html + const unitTestHTML = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.html')); + expect(removeSpaces(unitTestHTML)).toBe( + removeSpaces(` + + + + + Unit tests for test-app-typescript + + + + + + + + + + +
+
+ + `) + ); + + // check integration/opaTests.qunit.ts + const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.ts')); + expect(removeSpaces(opaTests)).toBe( + removeSpaces(` + /* global QUnit */ + sap.ui.require(["integration/NavigationJourney" + ], function () { + QUnit.config.autostart = false; + QUnit.start(); + });`) + ); + + // check integration/opaTests.qunit.html + const opaTestsHTML = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.html')); + expect(removeSpaces(opaTestsHTML)).toBe( + removeSpaces(` + + + + + Integration tests for Basic Template + + + + + + + +
+
+ + + `) + ); + }); +}); + +describe('writeOPATsconfigJsonUpdates', () => { + let fs: Editor; + let log: Logger; + + const opaConfig = { + appId: 'test-app-typescript', + applicationTitle: 'App test', + applicationDescription: 'App description', + enableTypeScript: true, + viewName: 'view-test', + ui5Version: '1.71.0' + }; + + beforeEach(() => { + fs = { + readJSON: jest.fn(), + writeJSON: jest.fn(), + copyTpl: jest.fn() + } as unknown as Editor; + + log = { + error: jest.fn() + } as unknown as Logger; + }); + + test('should log an error when writing to tsconfig.json fails', async () => { + const mockError = new Error('Write error'); + + (fs.writeJSON as jest.Mock).mockImplementation(() => { + throw mockError; + }); + const basePath = join('some/path'); + fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); + + expect(log.error).toHaveBeenCalled(); + expect(log.error).toHaveBeenCalledWith( + t('error.errorWritingTsConfig', { + error: mockError + }) + ); + }); + + test('should log an error when copying templates', async () => { + const mockError = new Error('copy template error'); + + (fs.copyTpl as jest.Mock).mockImplementation(() => { + throw mockError; + }); + + const basePath = join('some/path'); + fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); + + expect(log.error).toHaveBeenCalled(); + expect(log.error).toHaveBeenCalledWith( + t('error.errorCopyingFreestyleTestTemplates', { + error: mockError + }) + ); + }); +}); From 2882a4591d5c0f3afd739b2bd44f2fa1b991d751 Mon Sep 17 00:00:00 2001 From: I743583 Date: Wed, 19 Feb 2025 09:23:34 +0000 Subject: [PATCH 19/42] add correct path to fe integration test --- packages/ui5-test-writer/test/integration/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui5-test-writer/test/integration/index.test.ts b/packages/ui5-test-writer/test/integration/index.test.ts index 65acb109ad..e89b2b9903 100644 --- a/packages/ui5-test-writer/test/integration/index.test.ts +++ b/packages/ui5-test-writer/test/integration/index.test.ts @@ -1,4 +1,4 @@ -import { generateOPAFiles, generatePageObjectFile } from '../../src'; +import { generateOPAFiles, generatePageObjectFile } from '../../src/fiori-elements-opa-writer'; import { join } from 'path'; import type { Editor } from 'mem-fs-editor'; import { create as createStorage } from 'mem-fs'; From 8c4575f5290ec694a2aac33836b3d43689e00d69 Mon Sep 17 00:00:00 2001 From: I743583 Date: Wed, 19 Feb 2025 09:33:20 +0000 Subject: [PATCH 20/42] update ff snapshots --- .../test/__snapshots__/lrop.test.ts.snap | 88 +++++++++++-------- .../test/__snapshots__/worklist.test.ts.snap | 22 +++-- packages/fiori-freestyle-writer/src/types.ts | 2 +- 3 files changed, 66 insertions(+), 46 deletions(-) diff --git a/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap b/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap index 990df9bcc2..b6e6fb8263 100644 --- a/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap +++ b/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap @@ -21954,25 +21954,29 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - QUnit test suite + + QUnit test suite for lrop_v4_addtests + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -22771,25 +22775,29 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - QUnit test suite + + QUnit test suite for lrop_v4_addtests_cds + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -23655,25 +23663,29 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - QUnit test suite + + QUnit test suite for lrop_v4_addtests_cds + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -24999,25 +25011,29 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - QUnit test suite + + QUnit test suite for lrop_v4_annotation_reuse_lib + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, diff --git a/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap b/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap index cf559c1838..6ba1a4c9d1 100644 --- a/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap +++ b/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap @@ -14789,25 +14789,29 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - QUnit test suite + + QUnit test suite for fewrk2 + -", + +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; + 'use strict'; - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, diff --git a/packages/fiori-freestyle-writer/src/types.ts b/packages/fiori-freestyle-writer/src/types.ts index c33411f1b4..b9f54db435 100644 --- a/packages/fiori-freestyle-writer/src/types.ts +++ b/packages/fiori-freestyle-writer/src/types.ts @@ -44,7 +44,7 @@ export interface FreestyleApp extends Ui5App { capService?: CapServiceCdsInfo; }; app: FioriApp; - appOptions: Partial & { + appOptions?: Partial & { /** * Generate OPA based tests, for Simple template. * This will eventually move up to {@link Ui5App.appOptions} From d52877a7ca29d37a4b5b1afef2201fe584e28f26 Mon Sep 17 00:00:00 2001 From: I743583 Date: Wed, 19 Feb 2025 09:50:44 +0000 Subject: [PATCH 21/42] update snapshots for ff and fe writers --- .../test/__snapshots__/lrop.test.ts.snap | 8 +++---- .../test/__snapshots__/worklist.test.ts.snap | 2 +- .../templates/common/testsuite.qunit.js | 2 +- .../unit/__snapshots__/index.test.ts.snap | 22 +++++++++---------- .../test/unit/fiori-freestyle.test.ts | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap b/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap index b6e6fb8263..14be1cce5f 100644 --- a/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap +++ b/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap @@ -21972,7 +21972,7 @@ sap.registerComponentDependencyPaths(manifestUri) // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -22793,7 +22793,7 @@ sap.registerComponentDependencyPaths(manifestUri) // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -23681,7 +23681,7 @@ sap.registerComponentDependencyPaths(manifestUri) // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -25029,7 +25029,7 @@ sap.registerComponentDependencyPaths(manifestUri) // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); diff --git a/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap b/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap index 6ba1a4c9d1..cb53248443 100644 --- a/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap +++ b/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap @@ -14807,7 +14807,7 @@ sap.registerComponentDependencyPaths(manifestUri) // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); diff --git a/packages/ui5-test-writer/templates/common/testsuite.qunit.js b/packages/ui5-test-writer/templates/common/testsuite.qunit.js index 9b64c09779..fa16335962 100644 --- a/packages/ui5-test-writer/templates/common/testsuite.qunit.js +++ b/packages/ui5-test-writer/templates/common/testsuite.qunit.js @@ -8,7 +8,7 @@ window.suite = function() { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); <% if (addUnitTests === true) { %>oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html');<% } %> oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); diff --git a/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap b/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap index f788bc5dd3..4c94713a77 100644 --- a/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap +++ b/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap @@ -332,7 +332,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -678,7 +678,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -999,7 +999,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -1320,7 +1320,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -1593,7 +1593,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -1855,7 +1855,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -2124,7 +2124,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -2532,7 +2532,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -2940,7 +2940,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -3301,7 +3301,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); @@ -3569,7 +3569,7 @@ Object { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); diff --git a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts index 9b7016e1d2..a3e67fee5f 100644 --- a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts +++ b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts @@ -520,7 +520,7 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html'); oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); From bdf4248575887c1fedecd68500873416d71a5cc8 Mon Sep 17 00:00:00 2001 From: I743583 Date: Wed, 19 Feb 2025 10:18:43 +0000 Subject: [PATCH 22/42] sonar issues --- packages/fiori-freestyle-writer/src/types.ts | 3 +-- packages/ui5-test-writer/src/fiori-elements-opa-writer.ts | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/fiori-freestyle-writer/src/types.ts b/packages/fiori-freestyle-writer/src/types.ts index b9f54db435..d2f0c212f9 100644 --- a/packages/fiori-freestyle-writer/src/types.ts +++ b/packages/fiori-freestyle-writer/src/types.ts @@ -1,7 +1,6 @@ -import type { Ui5App, App } from '@sap-ux/ui5-application-writer'; +import type { Ui5App, App, AppOptions } from '@sap-ux/ui5-application-writer'; import type { OdataService } from '@sap-ux/odata-service-writer'; import type { CapServiceCdsInfo } from '@sap-ux/cap-config-writer'; -import type { AppOptions } from '@sap-ux/ui5-application-writer'; export const TemplateType = { Basic: 'basic', diff --git a/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts index 1fcdd04dae..b93fe225af 100644 --- a/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts @@ -64,7 +64,7 @@ function getAppTypeAndHideFilterBarFromManifest(manifest: Manifest): { * @returns appID and appPath */ function getAppFromManifest(manifest: Manifest, forcedAppID?: string): { appID: string; appPath: string } { - const appID = forcedAppID || manifest['sap.app']?.id; + const appID = forcedAppID ?? manifest['sap.app']?.id; const appPath = appID?.split('.').join('/'); if (!appID || !appPath) { @@ -187,7 +187,7 @@ function findLROP( const appTargets = manifest['sap.ui5']?.routing?.targets; const appRoutes = (manifest['sap.ui5']?.routing?.routes ?? []) as any[]; - const target = (appTargets && appTargets[pageLR.targetKey]) as FEV4ManifestTarget; + const target = appTargets?.[pageLR.targetKey] as FEV4ManifestTarget; if (!target?.options?.settings?.navigation) { return { pageLR }; // No navigation from LR From 039b1916737c4781b5259a7a093da61e8fad3803 Mon Sep 17 00:00:00 2001 From: I743583 Date: Thu, 20 Feb 2025 08:53:57 +0000 Subject: [PATCH 23/42] get app id slash logic --- packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index ee5f6ed5c7..734e4d0056 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -114,7 +114,7 @@ export async function generateFreestyleOPAFiles( const testOutDir = join(basePath, 'webapp/test'); const templateUi5Version = getTemplateUi5Version(ui5Version); - const appIdWithSlash = appId.replace(/\./g, '/'); // Replace all dots with slashes + const appIdWithSlash = appId.replace(/[.]/g, '/'); // Replace all dots with slashes const navigationIntent = appId.replace(/[./\\\-\s]/g, ''); // Remove all dots, slashes, dashes, and spaces const templateFiles = await getFilePaths(freestyleTemplateDir); From d1880593a89930d661f63f732d7b8882c0fa28a6 Mon Sep 17 00:00:00 2001 From: I743583 Date: Thu, 20 Feb 2025 09:21:38 +0000 Subject: [PATCH 24/42] change in test order in package scripts --- .../src/npm-package-scripts/getPackageScripts.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts index f2fff16169..d0c2034ef5 100644 --- a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts +++ b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts @@ -140,13 +140,13 @@ export function getPackageScripts({ scripts['start-mock'] = `fiori run --config ./ui5-mock.yaml --open "test/flpSandbox.html${params}"`; } - if (addTest) { - scripts['int-test'] = 'fiori run --config ./ui5-mock.yaml --open "test/integration/opaTests.qunit.html"'; - } - scripts['start-variants-management'] = localOnly ? `echo \\"${t('info.mockOnlyWarning')}\\"` : getVariantPreviewAppScript(sapClient); + if (addTest) { + scripts['int-test'] = 'fiori run --config ./ui5-mock.yaml --open "test/integration/opaTests.qunit.html"'; + } + return scripts; } From a955637ba7f52b15b8dfaab6e97e2190a5ca2e2a Mon Sep 17 00:00:00 2001 From: I743583 Date: Thu, 20 Feb 2025 09:31:41 +0000 Subject: [PATCH 25/42] updating int test scripts --- .../src/npm-package-scripts/getPackageScripts.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts index d0c2034ef5..f2fff16169 100644 --- a/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts +++ b/packages/fiori-generator-shared/src/npm-package-scripts/getPackageScripts.ts @@ -140,13 +140,13 @@ export function getPackageScripts({ scripts['start-mock'] = `fiori run --config ./ui5-mock.yaml --open "test/flpSandbox.html${params}"`; } - scripts['start-variants-management'] = localOnly - ? `echo \\"${t('info.mockOnlyWarning')}\\"` - : getVariantPreviewAppScript(sapClient); - if (addTest) { scripts['int-test'] = 'fiori run --config ./ui5-mock.yaml --open "test/integration/opaTests.qunit.html"'; } + scripts['start-variants-management'] = localOnly + ? `echo \\"${t('info.mockOnlyWarning')}\\"` + : getVariantPreviewAppScript(sapClient); + return scripts; } From 0b90e9582b8fcd5196ac0079dba2d75244c277ec Mon Sep 17 00:00:00 2001 From: I743583 Date: Thu, 20 Feb 2025 11:24:10 +0000 Subject: [PATCH 26/42] removing use of flp sandbox and int flp sandbox --- .../src/fiori-freestyle-opa-writer.ts | 6 +- .../freestyle/webapp/test/flpSandbox.js | 100 ------------- .../freestyle/webapp/test/initFlpSandbox.js | 13 -- .../test/unit/fiori-freestyle.test.ts | 135 ------------------ 4 files changed, 1 insertion(+), 253 deletions(-) delete mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js delete mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/initFlpSandbox.js diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 734e4d0056..405fbb88aa 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -119,20 +119,16 @@ export async function generateFreestyleOPAFiles( const templateFiles = await getFilePaths(freestyleTemplateDir); const isTypeScript = Boolean(enableTypeScript); - const commonJSTemplates = ['initFlpSandbox.js', 'flpSandbox.js']; // Filter files based on TypeScript setting: // - If TypeScript is enabled, include only .ts files // - If TypeScript is disabled, include only .js files - // - Include common JS files regardless of TypeScript setting const filteredFiles = templateFiles.filter((filePath: string) => { if (filePath.endsWith('.ts')) { return isTypeScript; } if (filePath.endsWith('.js')) { - const includeCommonJSTemplate = - commonJSTemplates.includes(basename(filePath)) && templateUi5Version === '1.71.0'; - return !isTypeScript || includeCommonJSTemplate; + return !isTypeScript; } return true; // keep other .html files }); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js deleted file mode 100644 index 684c6ddb22..0000000000 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/flpSandbox.js +++ /dev/null @@ -1,100 +0,0 @@ -sap.ui.define([ - "sap/base/util/ObjectPath", - "sap/ushell/services/Container" -], function (ObjectPath) { - "use strict"; - - // define ushell config - ObjectPath.set(["sap-ushell-config"], { - defaultRenderer: "fiori2", - bootstrapPlugins: { - "RuntimeAuthoringPlugin": { - component: "sap.ushell.plugins.rta", - config: { - validateAppVersion: false - } - }, - "PersonalizePlugin": { - component: "sap.ushell.plugins.rta-personalize", - config: { - validateAppVersion: false - } - } - }, - renderers: { - fiori2: { - componentData: { - config: { - enableSearch: false, - rootIntent: "Shell-home" - } - } - } - }, - services: { - "LaunchPage": { - "adapter": { - "config": { - "groups": [{ - "tiles": [{ - "tileType": "sap.ushell.ui.tile.StaticTile", - "properties": { - <% if (applicationTitle) { %>"title": "<%= applicationTitle %>",<% } %> - "targetURL": "#<%= navigationIntent %>-display" - } - }] - }] - } - } - }, - "ClientSideTargetResolution": { - "adapter": { - "config": { - "inbounds": { - "<%= navigationIntent %>-display": { - "semanticObject": "<%= navigationIntent %>", - "action": "display", - <% if (applicationDescription) { %>"description": "<%= applicationDescription %>",<% } %><% if (applicationTitle) { %> - "title": "<%= applicationTitle %>",<% } %> - "signature": { - "parameters": {} - }, - "resolutionResult": { - "applicationType": "SAPUI5", - "additionalInformation": "SAPUI5.Component=<%= appId %>", - "url": sap.ui.require.toUrl("<%= appIdWithSlash %>") - } - } - } - } - } - }, - NavTargetResolution: { - config: { - "enableClientSideTargetResolution": true - } - } - } - }); - - var oFlpSandbox = { - init: function () { - /** - * Initializes the FLP sandbox - * @returns {Promise} a promise that is resolved when the sandbox bootstrap has finshed - */ - - // sandbox is a singleton, so we can start it only once - if (!this._oBootstrapFinished) { - this._oBootstrapFinished = sap.ushell.bootstrap("local"); - this._oBootstrapFinished.then(function () { - sap.ushell.Container.createRenderer().placeAt("content"); - }); - } - - return this._oBootstrapFinished; - } - }; - - return oFlpSandbox; -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/initFlpSandbox.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/initFlpSandbox.js deleted file mode 100644 index 7a8f6bcfba..0000000000 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/initFlpSandbox.js +++ /dev/null @@ -1,13 +0,0 @@ -sap.ui.define([ - "./flpSandbox", - "sap/ui/fl/FakeLrepConnectorLocalStorage", - "sap/m/MessageBox" -], function (flpSandbox, FakeLrepConnectorLocalStorage, MessageBox) { - "use strict"; - - flpSandbox.init().then(function () { - FakeLrepConnectorLocalStorage.enableFakeConnector(); - }, function (oError) { - MessageBox.error(oError.message); - }); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts index a3e67fee5f..fdddf48ef9 100644 --- a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts +++ b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts @@ -32,8 +32,6 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); const expectedFiles = [ - 'flpSandbox.js', - 'initFlpSandbox.js', 'integration/NavigationJourney.ts', 'integration/opaTests.qunit.html', 'integration/pages/AppPage.ts', @@ -308,133 +306,6 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { }); `) ); - - // check initFlpSandbox.js - const initFlpSandbox = fs?.read(join(testOutputPath, 'initFlpSandbox.js')); - expect(removeSpaces(initFlpSandbox)).toBe( - removeSpaces(` - sap.ui.define([ - "./flpSandbox", - "sap/ui/fl/FakeLrepConnectorLocalStorage", - "sap/m/MessageBox" - ], function (flpSandbox, FakeLrepConnectorLocalStorage, MessageBox) { - "use strict"; - - flpSandbox.init().then(function () { - FakeLrepConnectorLocalStorage.enableFakeConnector(); - }, function (oError) { - MessageBox.error(oError.message); - }); - }); - `) - ); - - // check flpSandbox.js - const flpSandbox = fs?.read(join(testOutputPath, 'flpSandbox.js')); - expect(removeSpaces(flpSandbox)).toBe( - removeSpaces(` - sap.ui.define([ - "sap/base/util/ObjectPath", - "sap/ushell/services/Container" - ], function (ObjectPath) { - "use strict"; - - // define ushell config - ObjectPath.set(["sap-ushell-config"], { - defaultRenderer: "fiori2", - bootstrapPlugins: { - "RuntimeAuthoringPlugin": { - component: "sap.ushell.plugins.rta", - config: { - validateAppVersion: false - } - }, - "PersonalizePlugin": { - component: "sap.ushell.plugins.rta-personalize", - config: { - validateAppVersion: false - } - } - }, - renderers: { - fiori2: { - componentData: { - config: { - enableSearch: false, - rootIntent: "Shell-home" - } - } - } - }, - services: { - "LaunchPage": { - "adapter": { - "config": { - "groups": [{ - "tiles": [{ - "tileType": "sap.ushell.ui.tile.StaticTile", - "properties": { - "title": "${opaConfig.applicationTitle}", - "targetURL": "#testapptypescript-display" - } - }] - }] - } - } - }, - "ClientSideTargetResolution": { - "adapter": { - "config": { - "inbounds": { - "testapptypescript-display": { - "semanticObject": "testapptypescript", - "action": "display", - "description": "${opaConfig.applicationDescription}", - "title": "${opaConfig.applicationTitle}", - "signature": { - "parameters": {} - }, - "resolutionResult": { - "applicationType": "SAPUI5", - "additionalInformation": "SAPUI5.Component=test-app-typescript", - "url": sap.ui.require.toUrl("test-app-typescript") - } - } - } - } - } - }, - NavTargetResolution: { - config: { - "enableClientSideTargetResolution": true - } - } - } - }); - - var oFlpSandbox = { - init: function () { - /** - * Initializes the FLP sandbox - * @returns {Promise} a promise that is resolved when the sandbox bootstrap has finshed - */ - - // sandbox is a singleton, so we can start it only once - if (!this._oBootstrapFinished) { - this._oBootstrapFinished = sap.ushell.bootstrap("local"); - this._oBootstrapFinished.then(function () { - sap.ushell.Container.createRenderer().placeAt("content"); - }); - } - - return this._oBootstrapFinished; - } - }; - - return oFlpSandbox; - }); - `) - ); }); test('Generate OPA test files correctly when typescript is not enabled', async () => { @@ -451,8 +322,6 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { //console.log("--fs.dump", fs.dump()) const expectedFiles = [ - 'flpSandbox.js', - 'initFlpSandbox.js', 'integration/NavigationJourney.js', 'integration/opaTests.qunit.html', 'integration/pages/App.js', @@ -669,10 +538,6 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { expect(fs?.exists(join(testOutputPath, file))).toBe(true); }); - // check that flpSandbox & initFlpSandbox are not generated for ui5Version 1.120.0 - expect(fs.exists(join(testOutputPath, 'flpSandbox.js'))).toBe(false); - expect(fs.exists(join(testOutputPath, 'initFlpSandbox.js'))).toBe(false); - // check unit/unitTests.qunit.ts const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.ts')); expect(removeSpaces(unitTestQUnit)).toBe( From af28e13a7f162f6667a00b846692ed9b9e624ab6 Mon Sep 17 00:00:00 2001 From: I743583 Date: Thu, 20 Feb 2025 11:25:29 +0000 Subject: [PATCH 27/42] removing console log --- packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts index fdddf48ef9..939d0c1b06 100644 --- a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts +++ b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts @@ -320,7 +320,6 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { const testOutputPath = join(basePath, 'webapp/test'); fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); - //console.log("--fs.dump", fs.dump()) const expectedFiles = [ 'integration/NavigationJourney.js', 'integration/opaTests.qunit.html', From 9bbd30f03b6f8d101f33a80081d05749e69e6da1 Mon Sep 17 00:00:00 2001 From: I743583 Date: Thu, 20 Feb 2025 11:45:13 +0000 Subject: [PATCH 28/42] lint issues --- packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts | 2 +- .../templates/freestyle/webapp/test/unit/unitTests.qunit.ts | 3 ++- packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 405fbb88aa..6ed90c18b3 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -1,4 +1,4 @@ -import { join, basename } from 'path'; +import { join } from 'path'; import { create as createStorage } from 'mem-fs'; import type { Editor } from 'mem-fs-editor'; import { create } from 'mem-fs-editor'; diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts index 9f6de76464..c89c708cc9 100644 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts @@ -8,7 +8,8 @@ QUnit.config.autostart = false; // import all your QUnit tests here void Promise.all([ - <% if (ui5Version !== "1.71.0") { -%>import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests <% }-%> + <% if (ui5Version !== "1.71.0") { -%>import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests + <% }-%> import("unit/controller/<%= viewName %>Page.controller") ]).then((<% if (ui5Version !== "1.71.0") { -%>[{ default: Core }]<% } %>) => { QUnit.start(); diff --git a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts index 939d0c1b06..e36c7eccba 100644 --- a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts +++ b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts @@ -546,7 +546,8 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { // import all your QUnit tests here void Promise.all([ - import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests import("unit/controller/view-testPage.controller") + import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests + import("unit/controller/view-testPage.controller") ]).then(([{ default: Core }]) => { QUnit.start(); });`) From a648ebe7074ac295c7ac69fb0f60d61d80811ca1 Mon Sep 17 00:00:00 2001 From: I743583 Date: Thu, 20 Feb 2025 13:24:37 +0000 Subject: [PATCH 29/42] add changeset --- .changeset/swift-radios-provide.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/swift-radios-provide.md diff --git a/.changeset/swift-radios-provide.md b/.changeset/swift-radios-provide.md new file mode 100644 index 0000000000..b98f806ecf --- /dev/null +++ b/.changeset/swift-radios-provide.md @@ -0,0 +1,8 @@ +--- +'@sap-ux/fiori-freestyle-writer': minor +'@sap-ux/fiori-generator-shared': minor +'@sap-ux/ui5-test-writer': minor +'@sap-ux/fiori-elements-writer': patch +--- + +Add Freestyle OPA templates to ui5-test-writer From 31f4c16ac536d4642c4316fe344903ad451e0cff Mon Sep 17 00:00:00 2001 From: I743583 Date: Thu, 20 Feb 2025 15:20:09 +0000 Subject: [PATCH 30/42] refactoring --- packages/fiori-freestyle-writer/src/index.ts | 50 ++++++++------------ 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/packages/fiori-freestyle-writer/src/index.ts b/packages/fiori-freestyle-writer/src/index.ts index 3590a6a47e..ceb4647a7a 100644 --- a/packages/fiori-freestyle-writer/src/index.ts +++ b/packages/fiori-freestyle-writer/src/index.ts @@ -17,32 +17,20 @@ import type { Logger } from '@sap-ux/logger'; import { generateFreestyleOPAFiles } from '@sap-ux/ui5-test-writer'; /** - * Generates and writes OPA test files based on the provided application configuration. + * Adds test scripts to the package.json object. * - * @template T - * @param {string} basePath - The base path where test files will be generated. - * @param {FreestyleApp} ffApp - The freestyle application configuration. - * @param {Editor} [fs] - The file system editor instance. - * @param {Logger} [log] - The logger instance. + * @param {object} packageJson - The package.json object to update. + * @param {boolean} addMock - Whether to include the UI5 mock YAML configuration. */ -export async function writeOPATestFiles( - basePath: string, - ffApp: FreestyleApp, - fs?: Editor, - log?: Logger -): Promise { - const config = { - appId: ffApp.app.id, - applicationDescription: ffApp.app.description, - applicationTitle: ffApp.app.title, - viewName: (ffApp.template.settings as BasicAppSettings).viewName, - ui5Theme: ffApp.ui5?.ui5Theme, - ui5Version: ffApp.ui5?.version, - enableTypeScript: ffApp.appOptions?.typescript +function addTestScripts(packageJson: Package, addMock: boolean): void { + // Note: 'ui5MockYamlScript' is empty when no data source is selected. + const ui5MockYamlScript = addMock ? '--config ./ui5-mock.yaml ' : ''; + packageJson.scripts = { + ...packageJson.scripts, + 'unit-test': `fiori run ${ui5MockYamlScript}--open 'test/unit/unitTests.qunit.html'`, + 'int-test': `fiori run ${ui5MockYamlScript}--open 'test/integration/opaTests.qunit.html'` }; - await generateFreestyleOPAFiles(basePath, config, fs, log); } - /** * Generate a UI5 application based on the specified Fiori Freestyle floorplan template. * @@ -183,13 +171,17 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor, }) }; if (addTests) { - const ui5MockYamlScript = addMock ? '--config ./ui5-mock.yaml ' : ''; - // Note: 'ui5MockYamlScript' is empty when no data source is selected. - packageJson.scripts['unit-test'] = `fiori run ${ui5MockYamlScript}--open 'test/unit/unitTests.qunit.html'`; - packageJson.scripts[ - 'int-test' - ] = `fiori run ${ui5MockYamlScript}--open 'test/integration/opaTests.qunit.html'`; - await writeOPATestFiles(basePath, ffApp, fs, log); + addTestScripts(packageJson, addMock); + const config = { + appId: ffApp.app.id, + applicationDescription: ffApp.app.description, + applicationTitle: ffApp.app.title, + viewName: (ffApp.template.settings as BasicAppSettings).viewName, + ui5Theme: ffApp.ui5?.ui5Theme, + ui5Version: ffApp.ui5?.version, + enableTypeScript: ffApp.appOptions?.typescript + }; + await generateFreestyleOPAFiles(basePath, config, fs, log); } } else { // Add deploy-config for CAP applications From eea78578126cf1df74bb55015ffbdeab40004766 Mon Sep 17 00:00:00 2001 From: I743583 Date: Thu, 20 Feb 2025 15:50:36 +0000 Subject: [PATCH 31/42] use project acces utils --- packages/ui5-test-writer/src/fiori-elements-opa-writer.ts | 5 +++-- packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts index b93fe225af..cdebe340ed 100644 --- a/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts @@ -6,6 +6,7 @@ import type { Manifest } from '@sap-ux/project-access'; import type { FEV4OPAConfig, FEV4OPAPageConfig, FEV4ManifestTarget } from './types'; import { SupportedPageTypes, ValidationError } from './types'; import { t } from './i18n'; +import { FileName, DirName } from '@sap-ux/project-access'; /** * Reads the manifest for an app. @@ -15,11 +16,11 @@ import { t } from './i18n'; * @returns the manifest object. An exception is thrown if the manifest cannot be read. */ export function readManifest(fs: Editor, basePath: string): Manifest { - const manifest = fs.readJSON(join(basePath, 'webapp/manifest.json')) as any as Manifest; + const manifest = fs.readJSON(join(basePath, DirName.Webapp, FileName.Manifest)) as any as Manifest; if (!manifest) { throw new ValidationError( t('error.cannotReadManifest', { - filePath: join(basePath, 'webapp/manifest.json') + filePath: join(basePath, DirName.Webapp, FileName.Manifest) }) ); } diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 6ed90c18b3..1fd88fc60d 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -7,6 +7,7 @@ import type { Logger } from '@sap-ux/logger'; import { getFilePaths } from '@sap-ux/project-access'; import { t } from './i18n'; import { compareUI5VersionGte, ui5LtsVersion_1_71 } from '@sap-ux/ui5-application-writer'; +import { FileName } from '@sap-ux/project-access'; /** * Updates tsconfig.json to include paths for unit and integration tests. @@ -17,7 +18,7 @@ import { compareUI5VersionGte, ui5LtsVersion_1_71 } from '@sap-ux/ui5-applicatio */ function writeOPATsconfigJsonUpdates(fs: Editor, destinationRoot: string, log?: Logger): void { try { - const tsconfig: any = fs.readJSON(join(destinationRoot, 'tsconfig.json')) ?? {}; + const tsconfig: any = fs.readJSON(join(destinationRoot, FileName.Tsconfig)) ?? {}; tsconfig.compilerOptions = tsconfig.compilerOptions || {}; tsconfig.compilerOptions.paths = tsconfig.compilerOptions.paths || {}; @@ -25,7 +26,7 @@ function writeOPATsconfigJsonUpdates(fs: Editor, destinationRoot: string, log?: tsconfig.compilerOptions.paths['unit/*'] = ['./webapp/test/unit/*']; tsconfig.compilerOptions.paths['integration/*'] = ['./webapp/test/integration/*']; - fs.writeJSON(join(destinationRoot, 'tsconfig.json'), tsconfig); + fs.writeJSON(join(destinationRoot, FileName.Tsconfig), tsconfig); } catch (error) { log?.error( t('error.errorWritingTsConfig', { From 0934e345b1cc1c72a7c2509f28fe9e15faab073d Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 08:01:55 +0000 Subject: [PATCH 32/42] Following the FE templates --- .../test/__snapshots__/lrop.test.ts.snap | 88 +++---- .../test/__snapshots__/worklist.test.ts.snap | 22 +- .../src/fiori-elements-opa-writer.ts | 2 +- .../src/fiori-freestyle-opa-writer.ts | 4 +- .../templates/common/testsuite.qunit.html | 6 +- .../templates/common/testsuite.qunit.js | 19 +- .../freestyle/webapp/test/testsuite.qunit.js | 16 ++ .../unit/__snapshots__/index.test.ts.snap | 242 +++++++----------- .../test/unit/fiori-freestyle.test.ts | 2 +- 9 files changed, 173 insertions(+), 228 deletions(-) create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.js diff --git a/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap b/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap index 7e96653874..ae15da1a97 100644 --- a/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap +++ b/packages/fiori-elements-writer/test/__snapshots__/lrop.test.ts.snap @@ -21954,29 +21954,25 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - - QUnit test suite for lrop_v4_addtests - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -22775,29 +22771,25 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - - QUnit test suite for lrop_v4_addtests_cds - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -23663,29 +23655,25 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - - QUnit test suite for lrop_v4_addtests_cds - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -25011,29 +24999,25 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - - QUnit test suite for lrop_v4_annotation_reuse_lib - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, diff --git a/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap b/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap index d5d39cd8b8..7a112407f7 100644 --- a/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap +++ b/packages/fiori-elements-writer/test/__snapshots__/worklist.test.ts.snap @@ -14789,29 +14789,25 @@ sap.registerComponentDependencyPaths(manifestUri) "contents": " - - QUnit test suite for fewrk2 - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, diff --git a/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts index cdebe340ed..d9762e8261 100644 --- a/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-elements-opa-writer.ts @@ -284,7 +284,7 @@ export function generateOPAFiles( join(rootCommonTemplateDirPath), testOutDirPath, // unit tests are not added for Fiori elements app - { appId: config.appID, addUnitTests: false }, + { appId: config.appID }, undefined, { globOptions: { dot: true } diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 1fd88fc60d..bc7b79f8a5 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -165,13 +165,13 @@ export async function generateFreestyleOPAFiles( // copy common templates const commonFiles = await getFilePaths(commonTemplateDir); - const filteredCommonFiles = commonFiles.filter((filePath: string) => !filePath.endsWith('.js') || !isTypeScript); + const filteredCommonFiles = commonFiles.filter((filePath: string) => filePath.endsWith('.html')); const commonTemplatesCopied = copyTemplates( commonTemplateDir, testOutDir, filteredCommonFiles, - { appId, addUnitTests: true }, + { appId }, fsEditor, log ); diff --git a/packages/ui5-test-writer/templates/common/testsuite.qunit.html b/packages/ui5-test-writer/templates/common/testsuite.qunit.html index 13e19b05c2..1fea4a26d9 100644 --- a/packages/ui5-test-writer/templates/common/testsuite.qunit.html +++ b/packages/ui5-test-writer/templates/common/testsuite.qunit.html @@ -1,11 +1,9 @@ - - QUnit test suite for <%= appId %> - + QUnit test suite - + \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/common/testsuite.qunit.js b/packages/ui5-test-writer/templates/common/testsuite.qunit.js index fa16335962..a37a5c973c 100644 --- a/packages/ui5-test-writer/templates/common/testsuite.qunit.js +++ b/packages/ui5-test-writer/templates/common/testsuite.qunit.js @@ -1,16 +1,11 @@ -<% if (addUnitTests === true) { %>/* global window, parent, location */ - -// eslint-disable-next-line fiori-custom/sap-no-global-define -<% } -%> window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - <% if (addUnitTests === true) { %>oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html');<% } %> - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; }; \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.js new file mode 100644 index 0000000000..db577f4f0a --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.js @@ -0,0 +1,16 @@ +/* global window, parent, location */ + +// eslint-disable-next-line fiori-custom/sap-no-global-define + +window.suite = function() { + 'use strict'; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html'); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + + return oSuite; +}; \ No newline at end of file diff --git a/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap b/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap index 4c94713a77..765b9266ea 100644 --- a/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap +++ b/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap @@ -314,29 +314,25 @@ Object { "contents": " - - QUnit test suite for ui5-test-writer.test.employees - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -660,29 +656,25 @@ Object { "contents": " - - QUnit test suite for ui5-test-writer.test.employees - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -981,29 +973,25 @@ Object { "contents": " - - QUnit test suite for ui5-test-writer.test.employees - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -1302,29 +1290,25 @@ Object { "contents": " - - QUnit test suite for ui5-test-writer.test.employees - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -1575,29 +1559,25 @@ Object { "contents": " - - QUnit test suite for ui5-test-writer.test.employees - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -1837,29 +1817,25 @@ Object { "contents": " - - QUnit test suite for ui5-test-writer.test.employees - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -2106,29 +2082,25 @@ Object { "contents": " - - QUnit test suite for ui5-test-writer.test.employees - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -2514,29 +2486,25 @@ Object { "contents": " - - QUnit test suite for vesc.demo.employee.project2 - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -2922,29 +2890,25 @@ Object { "contents": " - - QUnit test suite for vesc.demo.employee.project2 - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -3283,29 +3247,25 @@ Object { "contents": " - - QUnit test suite for projectservice - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, @@ -3551,29 +3511,25 @@ Object { "contents": " - - QUnit test suite for test.ui5-test-writer - + QUnit test suite - -", +", "state": "modified", }, "webapp/test/testsuite.qunit.js": Object { "contents": "window.suite = function() { - 'use strict'; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), + 'use strict'; - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - return oSuite; + return oSuite; };", "state": "modified", }, diff --git a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts index e36c7eccba..7260867732 100644 --- a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts +++ b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts @@ -63,7 +63,7 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { - QUnit test suite for ${opaConfig.appId} + QUnit test suite From 50b1f5940bdc8cf7a145577efa53309dac60f925 Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 08:12:52 +0000 Subject: [PATCH 33/42] change index test names to fiori elements --- packages/fiori-freestyle-writer/src/index.ts | 2 +- .../{index.test.ts.snap => fiori-elements.test.ts.snap} | 0 .../test/integration/{index.test.ts => fiori-elements.test.ts} | 0 .../{index.test.ts.snap => fiori-elements.test.ts.snap} | 0 .../test/unit/{index.test.ts => fiori-elements.test.ts} | 0 5 files changed, 1 insertion(+), 1 deletion(-) rename packages/ui5-test-writer/test/integration/__snapshots__/{index.test.ts.snap => fiori-elements.test.ts.snap} (100%) rename packages/ui5-test-writer/test/integration/{index.test.ts => fiori-elements.test.ts} (100%) rename packages/ui5-test-writer/test/unit/__snapshots__/{index.test.ts.snap => fiori-elements.test.ts.snap} (100%) rename packages/ui5-test-writer/test/unit/{index.test.ts => fiori-elements.test.ts} (100%) diff --git a/packages/fiori-freestyle-writer/src/index.ts b/packages/fiori-freestyle-writer/src/index.ts index ceb4647a7a..f9a36dc669 100644 --- a/packages/fiori-freestyle-writer/src/index.ts +++ b/packages/fiori-freestyle-writer/src/index.ts @@ -19,7 +19,7 @@ import { generateFreestyleOPAFiles } from '@sap-ux/ui5-test-writer'; /** * Adds test scripts to the package.json object. * - * @param {object} packageJson - The package.json object to update. + * @param {Package} packageJson - The package.json object to update. * @param {boolean} addMock - Whether to include the UI5 mock YAML configuration. */ function addTestScripts(packageJson: Package, addMock: boolean): void { diff --git a/packages/ui5-test-writer/test/integration/__snapshots__/index.test.ts.snap b/packages/ui5-test-writer/test/integration/__snapshots__/fiori-elements.test.ts.snap similarity index 100% rename from packages/ui5-test-writer/test/integration/__snapshots__/index.test.ts.snap rename to packages/ui5-test-writer/test/integration/__snapshots__/fiori-elements.test.ts.snap diff --git a/packages/ui5-test-writer/test/integration/index.test.ts b/packages/ui5-test-writer/test/integration/fiori-elements.test.ts similarity index 100% rename from packages/ui5-test-writer/test/integration/index.test.ts rename to packages/ui5-test-writer/test/integration/fiori-elements.test.ts diff --git a/packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap b/packages/ui5-test-writer/test/unit/__snapshots__/fiori-elements.test.ts.snap similarity index 100% rename from packages/ui5-test-writer/test/unit/__snapshots__/index.test.ts.snap rename to packages/ui5-test-writer/test/unit/__snapshots__/fiori-elements.test.ts.snap diff --git a/packages/ui5-test-writer/test/unit/index.test.ts b/packages/ui5-test-writer/test/unit/fiori-elements.test.ts similarity index 100% rename from packages/ui5-test-writer/test/unit/index.test.ts rename to packages/ui5-test-writer/test/unit/fiori-elements.test.ts From 7846812c932b70f3d28e80bdca26a0531e9de00a Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 08:15:28 +0000 Subject: [PATCH 34/42] changeset --- .changeset/swift-radios-provide.md | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 .changeset/swift-radios-provide.md diff --git a/.changeset/swift-radios-provide.md b/.changeset/swift-radios-provide.md deleted file mode 100644 index b98f806ecf..0000000000 --- a/.changeset/swift-radios-provide.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@sap-ux/fiori-freestyle-writer': minor -'@sap-ux/fiori-generator-shared': minor -'@sap-ux/ui5-test-writer': minor -'@sap-ux/fiori-elements-writer': patch ---- - -Add Freestyle OPA templates to ui5-test-writer From 2c9819546e61f518ceeac598d0c9f01aee7ea7aa Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 08:16:16 +0000 Subject: [PATCH 35/42] changeset --- .changeset/shaggy-houses-pretend.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/shaggy-houses-pretend.md diff --git a/.changeset/shaggy-houses-pretend.md b/.changeset/shaggy-houses-pretend.md new file mode 100644 index 0000000000..9604b875ee --- /dev/null +++ b/.changeset/shaggy-houses-pretend.md @@ -0,0 +1,7 @@ +--- +'@sap-ux/fiori-freestyle-writer': minor +'@sap-ux/fiori-generator-shared': minor +'@sap-ux/ui5-test-writer': minor +--- + +Add Freestyle OPA templates to ui5-test-writer From a41d5718f557236b785ce9cb6e36883928592c7f Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 08:28:11 +0000 Subject: [PATCH 36/42] sonar issue fix --- packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index bc7b79f8a5..8ebf1de9f1 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -4,10 +4,9 @@ import type { Editor } from 'mem-fs-editor'; import { create } from 'mem-fs-editor'; import type { FFOPAConfig } from './types'; import type { Logger } from '@sap-ux/logger'; -import { getFilePaths } from '@sap-ux/project-access'; +import { getFilePaths, FileName } from '@sap-ux/project-access'; import { t } from './i18n'; import { compareUI5VersionGte, ui5LtsVersion_1_71 } from '@sap-ux/ui5-application-writer'; -import { FileName } from '@sap-ux/project-access'; /** * Updates tsconfig.json to include paths for unit and integration tests. From e1356c1ded465b4e7f2ead68038d52ad024ac4a8 Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 11:38:38 +0000 Subject: [PATCH 37/42] split templates based on ui5 versions --- .../src/fiori-freestyle-opa-writer.ts | 64 +++++-- .../templates/freestyle/model.json | 164 ------------------ .../{ => 1.120.0}/integration/AllJourneys.js | 0 .../integration/NavigationJourney.js | 0 .../integration/NavigationJourney.ts | 0 .../integration/arrangements/Startup.js | 0 .../1.120.0/integration/opaTests.qunit.html | 29 ++++ .../integration/opaTests.qunit.js | 0 .../1.120.0/integration/opaTests.qunit.ts | 6 + .../{ => 1.120.0}/integration/pages/App.js | 0 .../integration/pages/AppPage.ts | 0 .../integration/pages/viewName.js | 0 .../integration/pages/viewName.ts | 0 .../test/{ => 1.120.0}/unit/AllTests.js | 0 .../unit/controller/viewName.controller.js | 0 .../unit/controller/viewName.controller.ts | 0 .../{ => 1.120.0}/unit/unitTests.qunit.html | 5 +- .../{ => 1.120.0}/unit/unitTests.qunit.js | 0 .../test/1.120.0/unit/unitTests.qunit.ts | 10 ++ .../test/1.71.0/integration/AllJourneys.js | 13 ++ .../1.71.0/integration/NavigationJourney.js | 23 +++ .../1.71.0/integration/NavigationJourney.ts | 34 ++++ .../integration/arrangements/Startup.js | 25 +++ .../integration/opaTests.qunit.html | 3 +- .../test/1.71.0/integration/opaTests.qunit.js | 7 + .../integration/opaTests.qunit.ts | 9 +- .../test/1.71.0/integration/pages/App.js | 28 +++ .../test/1.71.0/integration/pages/AppPage.ts | 22 +++ .../test/1.71.0/integration/pages/viewName.js | 28 +++ .../test/1.71.0/integration/pages/viewName.ts | 23 +++ .../webapp/test/1.71.0/unit/AllTests.js | 5 + .../unit/controller/viewName.controller.js | 16 ++ .../unit/controller/viewName.controller.ts | 10 ++ .../test/1.71.0/unit/unitTests.qunit.html | 27 +++ .../test/1.71.0/unit/unitTests.qunit.js | 12 ++ .../test/1.71.0/unit/unitTests.qunit.ts | 10 ++ .../freestyle/webapp/test/testsuite.qunit.js | 2 +- .../webapp/test/unit/unitTests.qunit.ts | 16 -- .../test/unit/fiori-freestyle.test.ts | 2 +- 39 files changed, 381 insertions(+), 212 deletions(-) delete mode 100644 packages/ui5-test-writer/templates/freestyle/model.json rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/integration/AllJourneys.js (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/integration/NavigationJourney.js (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/integration/NavigationJourney.ts (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/integration/arrangements/Startup.js (100%) create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.html rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/integration/opaTests.qunit.js (100%) create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.ts rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/integration/pages/App.js (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/integration/pages/AppPage.ts (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/integration/pages/viewName.js (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/integration/pages/viewName.ts (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/unit/AllTests.js (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/unit/controller/viewName.controller.js (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/unit/controller/viewName.controller.ts (100%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/unit/unitTests.qunit.html (78%) rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.120.0}/unit/unitTests.qunit.js (100%) create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/AllJourneys.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/arrangements/Startup.js rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.71.0}/integration/opaTests.qunit.html (80%) create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.js rename packages/ui5-test-writer/templates/freestyle/webapp/test/{ => 1.71.0}/integration/opaTests.qunit.ts (55%) create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/App.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/AppPage.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/AllTests.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.ts create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.html create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.js create mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.ts delete mode 100644 packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index 8ebf1de9f1..a08da3dec4 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -60,6 +60,7 @@ function getTemplateUi5Version(ui5Version?: string): string { * @param {Editor} editor - The editor instance used to copy and render template files. * @param {Logger} [log] - The logger instance. * @param {Record} [renameMap] - Optional rename mapping for file paths. + * @param {string} [templateUi5Version] - The template UI5 version. * @returns {boolean} - resolves to `true` if the files were copied successfully, * or `false` if there was an error during the process. */ @@ -70,11 +71,13 @@ function copyTemplates( opaConfig: FFOPAConfig & { addUnitTests?: boolean }, editor: Editor, log?: Logger, - renameMap?: Record + renameMap?: Record, + templateUi5Version?: string ): boolean { try { filteredFiles.forEach((filePath: string) => { - const destFilePath = filePath.replace(sourceDir, ''); + // remove template UI5 version from the path + const destFilePath = filePath.replace(sourceDir, '').replace(`/${templateUi5Version}/`, '/'); const destinationFilePath = join(ouputDir, renameMap?.[destFilePath] ?? destFilePath); editor.copyTpl(filePath, destinationFilePath, opaConfig, undefined, { globOptions: { dot: true } @@ -91,6 +94,44 @@ function copyTemplates( } } +/** + * Filters files based on the template UI5 version. + * + * @param files - Array of file paths. + * @param templateUi5Version - The current template Ui5 Version. + * @returns Files that either are testsuite files or reside in the current template UI5 version folder. + */ +function filterByUi5Version(files: string[], templateUi5Version: string): string[] { + return files.filter((filePath: string) => { + // Always include testsuite files. + if (filePath.includes('testsuite.qunit')) { + return true; + } + // For all other files, include only those in the current UI5 version directory. + return filePath.includes(`/${templateUi5Version}/`); + }); +} + +/** + * Filters files based on the TypeScript setting. + * + * @param files - Array of file paths. + * @param isTypeScript - If true, include .ts files; if false, include .js files. + * @returns Files filtered based on the file extension. + */ +function filterByTypeScript(files: string[], isTypeScript: boolean): string[] { + return files.filter((filePath: string) => { + if (filePath.endsWith('.ts')) { + return isTypeScript; + } + if (filePath.endsWith('.js')) { + return !isTypeScript; + } + // Keep all .html file types + return true; + }); +} + /** * Generates and copies freestyle test files based on configuration. * @@ -120,24 +161,13 @@ export async function generateFreestyleOPAFiles( const templateFiles = await getFilePaths(freestyleTemplateDir); const isTypeScript = Boolean(enableTypeScript); - // Filter files based on TypeScript setting: - // - If TypeScript is enabled, include only .ts files - // - If TypeScript is disabled, include only .js files - const filteredFiles = templateFiles.filter((filePath: string) => { - if (filePath.endsWith('.ts')) { - return isTypeScript; - } - if (filePath.endsWith('.js')) { - return !isTypeScript; - } - return true; // keep other .html files - }); + const templateFilteredFiles = filterByUi5Version(templateFiles, templateUi5Version); + const filteredFiles = filterByTypeScript(templateFilteredFiles, isTypeScript); const config = { ...opaConfig, viewNamePage: `${viewName}Page`, appIdWithSlash, - ui5Version: templateUi5Version, navigationIntent, ui5Theme: opaConfig.ui5Theme ?? '' }; @@ -159,7 +189,8 @@ export async function generateFreestyleOPAFiles( config, fsEditor, log, - renameMap + renameMap, + templateUi5Version ); // copy common templates @@ -174,7 +205,6 @@ export async function generateFreestyleOPAFiles( fsEditor, log ); - if (commonTemplatesCopied && freestyleTestTemplatesCopied && isTypeScript) { writeOPATsconfigJsonUpdates(fsEditor, basePath, log); } diff --git a/packages/ui5-test-writer/templates/freestyle/model.json b/packages/ui5-test-writer/templates/freestyle/model.json deleted file mode 100644 index 0231282c2f..0000000000 --- a/packages/ui5-test-writer/templates/freestyle/model.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "neoapp": { - "welcomeFile": "/webapp/test/flpSandbox.html", - "sendWelcomeFileRedirect": true - }, - "datasource": { - "type": "odata", - "url": "" - }, - "simple": { - "environment": { - "internal": "false", - "resourcePath": "" - }, - "parameters": { - "ManifestVersion": { - "value": "" - }, - "ui5Version": { - "value": "" - }, - "ProjectName": { - "value": "" - }, - "AppId": { - "value": "" - }, - "ViewName": { - "value": "" - }, - "ViewNamePage": { - "value": "" - }, - "UI5Theme": { - "value": "" - }, - "sapUiBootstrapSrcUrl": { - "value": "" - }, - "AppIdWithSlash": { - "value": "" - }, - "ApplicationNamespace": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "Namespace" - }, - "wizard": { - "control": "TextField", - "regExp": "^[a-z][a-z 0-9]*(?:\\.[a-z][a-z 0-9]*)*$", - "required": true, - "title": "Namespace", - "regExpErrorMsg": "A namespace must not start with a digit. After the first character you may use any alphanumeric character or number separated by dots. Two successive dots are also forbidden. A namespace must not end with a dot." - } - }, - "ApplicationTitle": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "sap.app.title" - }, - "wizard": { - "control": "TextField", - "required": true, - "title": "Title", - "regExp": "^[\\w][\\w\\.\\-\\ ]*$" - } - }, - "ApplicationDescription": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "sap.app.description" - }, - "wizard": { - "control": "TextField", - "required": false, - "title": "Description" - } - }, - "FioriID": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "sap.fiori.registrationIds" - }, - "wizard": { - "control": "TextField", - "required": false, - "title": "SAP Fiori ID", - "internalOnly": true - } - }, - "ApplicationComponentHierarchy": { - "type": "string", - "value": "", - "appDescriptor": { - "id": "sap.app.ach" - }, - "wizard": { - "control": "TextField", - "required": false, - "title": "Application Component Hierarchy", - "internalOnly": true - } - }, - "FLP": { - "type": "Entity", - "multiplicity": "many", - "isRoot": true, - "binding": [ - { - "name": "SAP Fiori Launchpad Component (optimized for SAP Fiori Launchpad registration)", - "value": true - }, - { - "name": "Standalone App (optimized for individual deployment)", - "value": false - } - ], - "value": "", - "wizard": { - "control": "ComboBox", - "required": true, - "title": "App Type", - "tooltip": "Choose if your app should run in SAP Fiori Launchpad or standalone" - } - }, - "DefineReplacement": { - "type": "string", - "value": "" - } - }, - "forms": [ - { - "type": "appDescriptorGenericStep", - "groups": [ - { - "parameters": [ - "@simple.parameters.ApplicationTitle", - "@simple.parameters.ApplicationNamespace", - "@simple.parameters.ApplicationDescription", - "@simple.parameters.ApplicationComponentHierarchy", - "@simple.parameters.FioriID" - ] - } - ] - }, - { - "groups": [ - { - "title": "Application Scenario", - "parameters": ["@simple.parameters.FLP"] - }, - { - "title": "Data Binding", - "parameters": [] - } - ] - } - ] - } -} diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/AllJourneys.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/AllJourneys.js similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/AllJourneys.js rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/AllJourneys.js diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/NavigationJourney.js similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.js rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/NavigationJourney.js diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/NavigationJourney.ts similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/NavigationJourney.ts rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/NavigationJourney.ts diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/arrangements/Startup.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/arrangements/Startup.js similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/arrangements/Startup.js rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/arrangements/Startup.js diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.html b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.html new file mode 100644 index 0000000000..b4a4910681 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.html @@ -0,0 +1,29 @@ + + + + + Integration tests for Basic Template + + + + + + + + +
+
+ + diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.js similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.js rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.js diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.ts new file mode 100644 index 0000000000..4d652f1533 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/opaTests.qunit.ts @@ -0,0 +1,6 @@ +/* global QUnit */ +sap.ui.require(["integration/NavigationJourney" +], function () { + QUnit.config.autostart = false; + QUnit.start(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/App.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/pages/App.js similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/App.js rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/pages/App.js diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/AppPage.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/pages/AppPage.ts similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/AppPage.ts rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/pages/AppPage.ts diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/pages/viewName.js similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.js rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/pages/viewName.js diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/pages/viewName.ts similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/pages/viewName.ts rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/integration/pages/viewName.ts diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/AllTests.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/AllTests.js similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/unit/AllTests.js rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/AllTests.js diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/controller/viewName.controller.js similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.js rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/controller/viewName.controller.js diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/controller/viewName.controller.ts similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/unit/controller/viewName.controller.ts rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/controller/viewName.controller.ts diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.html b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.html similarity index 78% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.html rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.html index 6cb13cf3f1..b198ead12b 100644 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.html +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.html @@ -11,7 +11,7 @@ "unit": "." }' data-sap-ui-async="true" - <% if (ui5Version === "1.71.0") { %>data-sap-ui-oninit="module:unit/unitTests.qunit"<% } else { %>data-sap-ui-compat-version="edge"<% } %>> + data-sap-ui-compat-version="edge"> @@ -19,8 +19,7 @@ -<% if (ui5Version !== "1.71.0") { -%> -<% } -%> +
diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.js similarity index 100% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.js rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.js diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.ts new file mode 100644 index 0000000000..9aa7b1c79a --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.120.0/unit/unitTests.qunit.ts @@ -0,0 +1,10 @@ +/* @sapUiRequire */ +QUnit.config.autostart = false; + +// import all your QUnit tests here +void Promise.all([ + import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests +import("unit/controller/<%= viewName %>Page.controller") +]).then(([{ default: Core }]) => { + QUnit.start(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/AllJourneys.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/AllJourneys.js new file mode 100644 index 0000000000..b630e2f815 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/AllJourneys.js @@ -0,0 +1,13 @@ +sap.ui.define([ + "sap/ui/test/Opa5", + "./arrangements/Startup", + "./NavigationJourney" +], function (Opa5, Startup) { + "use strict"; + + Opa5.extendConfig({ + arrangements: new Startup(), + viewNamespace: "<%= appId %>.view.", + autoWait: true + }); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.js new file mode 100644 index 0000000000..fe45eabd01 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.js @@ -0,0 +1,23 @@ +/*global QUnit*/ + +sap.ui.define([ + "sap/ui/test/opaQunit", + "./pages/App", + "./pages/<%= viewName %>" +], function (opaTest) { + "use strict"; + + QUnit.module("Navigation Journey"); + + opaTest("Should see the initial page of the app", function (Given, When, Then) { + // Arrangements + Given.iStartMyApp(); + + // Assertions + Then.onTheAppPage.iShouldSeeTheApp(); + Then.onTheViewPage.iShouldSeeThePageView(); + + //Cleanup + Then.iTeardownMyApp(); + }); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.ts new file mode 100644 index 0000000000..579638030b --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/NavigationJourney.ts @@ -0,0 +1,34 @@ +/*global QUnit*/ +import opaTest from "sap/ui/test/opaQunit"; +import AppPage from "./pages/AppPage"; +import ViewPage from "./pages/<%= viewName %>Page"; + +import Opa5 from "sap/ui/test/Opa5"; + +QUnit.module("Navigation Journey"); + +const onTheAppPage = new AppPage(); +const onTheViewPage = new ViewPage(); +Opa5.extendConfig({ + viewNamespace: "<%= appId %>.view.", + autoWait: true +}); + +opaTest("Should see the initial page of the app", function () { + // Arrangements + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iStartMyUIComponent({ + componentConfig: { + name: "<%= appId %>" + } + }); + + // Assertions + onTheAppPage.iShouldSeeTheApp(); + onTheViewPage.iShouldSeeThePageView(); + + + // Cleanup + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iTeardownMyApp(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/arrangements/Startup.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/arrangements/Startup.js new file mode 100644 index 0000000000..9127906862 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/arrangements/Startup.js @@ -0,0 +1,25 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + + return Opa5.extend("integration.arrangements.Startup", { + + iStartMyApp: function (oOptionsParameter) { + var oOptions = oOptionsParameter || {}; + + // start the app with a minimal delay to make tests fast but still async to discover basic timing issues + oOptions.delay = oOptions.delay || 50; + + // start the app UI component + this.iStartMyUIComponent({ + componentConfig: { + name: "<%= appId %>", + async: true + }, + hash: oOptions.hash, + autoWait: oOptions.autoWait + }); + } + }); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.html b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.html similarity index 80% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.html rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.html index f9ffa7ff57..0bb4e404e8 100644 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.html +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.html @@ -16,12 +16,11 @@ data-sap-ui-compatVersion="edge" data-sap-ui-async="true" data-sap-ui-preload="async" - <% if (ui5Version === "1.71.0") { %>data-sap-ui-oninit="module:integration/opaTests.qunit"<% } %>> + data-sap-ui-oninit="module:integration/opaTests.qunit"> -<% if (ui5Version !== "1.71.0") { %><% } -%>
diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.js new file mode 100644 index 0000000000..9f61e8cf7e --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.js @@ -0,0 +1,7 @@ +/* global QUnit */ + +sap.ui.require(["<%= appIdWithSlash %>/test/integration/AllJourneys" +], function () { + QUnit.config.autostart = false; + QUnit.start(); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.ts similarity index 55% rename from packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.ts rename to packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.ts index 645989fec8..3ab24d9783 100644 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/integration/opaTests.qunit.ts +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/opaTests.qunit.ts @@ -1,5 +1,4 @@ /* global QUnit */ -<% if (ui5Version === '1.71.0') { -%> // https://api.qunitjs.com/config/autostart/ QUnit.config.autostart = false; @@ -8,10 +7,4 @@ void Promise.all([ import("integration/NavigationJourney") ]).then(() => { QUnit.start(); -}); -<% } else { -%> -sap.ui.require(["integration/NavigationJourney" -], function () { - QUnit.config.autostart = false; - QUnit.start(); -});<% } %> \ No newline at end of file +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/App.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/App.js new file mode 100644 index 0000000000..db276e3fd4 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/App.js @@ -0,0 +1,28 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + var sViewName = "App"; + + Opa5.createPageObjects({ + onTheAppPage: { + + actions: {}, + + assertions: { + + iShouldSeeTheApp: function () { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/AppPage.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/AppPage.ts new file mode 100644 index 0000000000..8cb42d2a57 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/AppPage.ts @@ -0,0 +1,22 @@ +import Opa5 from "sap/ui/test/Opa5"; + +const sViewName = "App"; + +export default class AppPage extends Opa5 { + // Actions + + + // Assertions + iShouldSeeTheApp() { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + +} + diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.js new file mode 100644 index 0000000000..99a42c95d6 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.js @@ -0,0 +1,28 @@ +sap.ui.define([ + "sap/ui/test/Opa5" +], function (Opa5) { + "use strict"; + var sViewName = "<%= viewName %>"; + + Opa5.createPageObjects({ + onTheViewPage: { + + actions: {}, + + assertions: { + + iShouldSeeThePageView: function () { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.ts new file mode 100644 index 0000000000..b27e2a2305 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/integration/pages/viewName.ts @@ -0,0 +1,23 @@ +import Opa5 from "sap/ui/test/Opa5"; + +const sViewName = "<%= viewName %>"; + +export default class <%= viewNamePage %> extends Opa5 { + // Actions + + + // Assertions + iShouldSeeThePageView() { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + +} + + diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/AllTests.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/AllTests.js new file mode 100644 index 0000000000..7b5c8a4ad2 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/AllTests.js @@ -0,0 +1,5 @@ +sap.ui.define([ + "<%= appIdWithSlash %>/test/unit/controller/<%= viewName %>.controller" +], function () { + "use strict"; +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.js new file mode 100644 index 0000000000..de22944c10 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.js @@ -0,0 +1,16 @@ +/*global QUnit*/ + +sap.ui.define([ + "<%= appIdWithSlash %>/controller/<%= viewName %>.controller" +], function (Controller) { + "use strict"; + + QUnit.module("<%= viewName %> Controller"); + + QUnit.test("I should test the <%= viewName %> controller", function (assert) { + var oAppController = new Controller(); + oAppController.onInit(); + assert.ok(oAppController); + }); + +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.ts new file mode 100644 index 0000000000..658f1164e3 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/controller/viewName.controller.ts @@ -0,0 +1,10 @@ +/*global QUnit*/ +import Controller from "<%= appIdWithSlash %>/controller/<%= viewName %>.controller"; + +QUnit.module("<%= viewName %> Controller"); + +QUnit.test("I should test the <%= viewName %> controller", function (assert: Assert) { + const oAppController = new Controller("<%= viewName %>"); + oAppController.onInit(); + assert.ok(oAppController); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.html b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.html new file mode 100644 index 0000000000..b5bc52ad21 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.html @@ -0,0 +1,27 @@ + + + + + Unit tests for <%= appId %> + + + + + + + + + +
+
+ + diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.js new file mode 100644 index 0000000000..0e148cc2ad --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.js @@ -0,0 +1,12 @@ +/* global QUnit */ +QUnit.config.autostart = false; + +sap.ui.getCore().attachInit(function () { + "use strict"; + + sap.ui.require([ + "<%= appIdWithSlash %>/test/unit/AllTests" + ], function () { + QUnit.start(); + }); +}); diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.ts new file mode 100644 index 0000000000..e430829548 --- /dev/null +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/1.71.0/unit/unitTests.qunit.ts @@ -0,0 +1,10 @@ +/* global QUnit */ +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +// import all your QUnit tests here +void Promise.all([ +import("unit/controller/<%= viewName %>Page.controller") +]).then(() => { + QUnit.start(); +}); \ No newline at end of file diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.js b/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.js index db577f4f0a..efbff39e33 100644 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.js +++ b/packages/ui5-test-writer/templates/freestyle/webapp/test/testsuite.qunit.js @@ -3,7 +3,7 @@ // eslint-disable-next-line fiori-custom/sap-no-global-define window.suite = function() { - 'use strict'; + "use strict"; // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), diff --git a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts b/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts deleted file mode 100644 index c89c708cc9..0000000000 --- a/packages/ui5-test-writer/templates/freestyle/webapp/test/unit/unitTests.qunit.ts +++ /dev/null @@ -1,16 +0,0 @@ -<% if (ui5Version === "1.71.0") { -%> -/* global QUnit */ -// https://api.qunitjs.com/config/autostart/ -<% } else { -%> -/* @sapUiRequire */ -<% } -%> -QUnit.config.autostart = false; - -// import all your QUnit tests here -void Promise.all([ - <% if (ui5Version !== "1.71.0") { -%>import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests - <% }-%> -import("unit/controller/<%= viewName %>Page.controller") -]).then((<% if (ui5Version !== "1.71.0") { -%>[{ default: Core }]<% } %>) => { - QUnit.start(); -}); \ No newline at end of file diff --git a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts index 7260867732..84e814f2bc 100644 --- a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts +++ b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts @@ -383,7 +383,7 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { // eslint-disable-next-line fiori-custom/sap-no-global-define window.suite = function() { - 'use strict'; + "use strict"; // eslint-disable-next-line var oSuite = new parent.jsUnitTestSuite(), From 1a3b739123857090c6a0fecd34fd449be492440e Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 12:48:16 +0000 Subject: [PATCH 38/42] sonar issue --- .../test/unit/fiori-freestyle.test.ts | 774 +++++++++--------- 1 file changed, 387 insertions(+), 387 deletions(-) diff --git a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts index 84e814f2bc..5b7e81d514 100644 --- a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts +++ b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts @@ -308,392 +308,392 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { ); }); - test('Generate OPA test files correctly when typescript is not enabled', async () => { - const opaConfig = { - appId: 'test-app-js', - applicationTitle: 'App test', - applicationDescription: 'App description', - viewName: 'view-test', - ui5Version: '1.71.0' - }; - const basePath = join('some/path'); - const testOutputPath = join(basePath, 'webapp/test'); - fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); - - const expectedFiles = [ - 'integration/NavigationJourney.js', - 'integration/opaTests.qunit.html', - 'integration/pages/App.js', - 'integration/pages/view-test.js', - 'testsuite.qunit.js', - 'unit/controller/view-test.controller.js', - 'unit/unitTests.qunit.html', - 'unit/unitTests.qunit.js' - ]; - expectedFiles.map((file: string) => { - expect(fs?.exists(join(testOutputPath, file))).toBe(true); - }); - - // check unit/unitTests.qunit.js - const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.js')); - expect(removeSpaces(unitTestQUnit)).toBe( - removeSpaces(` - /* global QUnit */ - QUnit.config.autostart = false; - - sap.ui.getCore().attachInit(function () { - "use strict"; - - sap.ui.require([ - "test-app-js/test/unit/AllTests" - ], function () { - QUnit.start(); - }); - });`) - ); - - // check unit/controller/view-test.controller.js - const viewTestController = fs?.read(join(testOutputPath, 'unit/controller/view-test.controller.js')); - expect(removeSpaces(viewTestController)).toBe( - removeSpaces(` - /*global QUnit*/ - - sap.ui.define([ - "test-app-js/controller/view-test.controller" - ], function (Controller) { - "use strict"; - - QUnit.module("view-test Controller"); - - QUnit.test("I should test the view-test controller", function (assert) { - var oAppController = new Controller(); - oAppController.onInit(); - assert.ok(oAppController); - }); - - }); - `) - ); - - // check test/testsuite.qunit.js - const testSuiteQUnit = fs?.read(join(testOutputPath, 'testsuite.qunit.js')); - expect(removeSpaces(testSuiteQUnit)).toBe( - removeSpaces(` - /* global window, parent, location */ - - // eslint-disable-next-line fiori-custom/sap-no-global-define - window.suite = function() { - "use strict"; - - // eslint-disable-next-line - var oSuite = new parent.jsUnitTestSuite(), - - sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html'); - oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - - return oSuite; - }; - `) - ); - - // check integration/pages/view-test.js - const viewTest = fs?.read(join(testOutputPath, 'integration/pages/view-test.js')); - expect(removeSpaces(viewTest)).toBe( - removeSpaces(` - sap.ui.define([ - "sap/ui/test/Opa5" - ], function (Opa5) { - "use strict"; - var sViewName = "view-test"; - - Opa5.createPageObjects({ - onTheViewPage: { - - actions: {}, - - assertions: { - - iShouldSeeThePageView: function () { - return this.waitFor({ - id: "page", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - } - } - }); - - });`) - ); - - // check integration/pages/App.js - const app = fs?.read(join(testOutputPath, 'integration/pages/App.js')); - expect(removeSpaces(app)).toBe( - removeSpaces(` - sap.ui.define([ - "sap/ui/test/Opa5" - ], function (Opa5) { - "use strict"; - var sViewName = "App"; - - Opa5.createPageObjects({ - onTheAppPage: { - - actions: {}, - - assertions: { - - iShouldSeeTheApp: function () { - return this.waitFor({ - id: "app", - viewName: sViewName, - success: function () { - Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - }, - errorMessage: "Did not find the " + sViewName + " view" - }); - } - } - } - }); - - }); - `) - ); - - // check integration/opaTests.qunit.js - const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.js')); - expect(removeSpaces(opaTests)).toBe( - removeSpaces(` - /* global QUnit */ - - sap.ui.require(["test-app-js/test/integration/AllJourneys" - ], function () { - QUnit.config.autostart = false; - QUnit.start(); - });`) - ); - - // check integration/NavigationJourney.js - const navigationJourney = fs?.read(join(testOutputPath, 'integration/NavigationJourney.js')); - expect(removeSpaces(navigationJourney)).toBe( - removeSpaces(` - /*global QUnit*/ - - sap.ui.define([ - "sap/ui/test/opaQunit", - "./pages/App", - "./pages/view-test" - ], function (opaTest) { - "use strict"; - - QUnit.module("Navigation Journey"); - - opaTest("Should see the initial page of the app", function (Given, When, Then) { - // Arrangements - Given.iStartMyApp(); - - // Assertions - Then.onTheAppPage.iShouldSeeTheApp(); - Then.onTheViewPage.iShouldSeeThePageView(); - - //Cleanup - Then.iTeardownMyApp(); - }); - }); - `) - ); - }); - - test('Generate OPA test files correctly when ui5Version is 1.120.0', async () => { - const opaConfig = { - appId: 'test-app-typescript', - applicationTitle: 'App test', - applicationDescription: 'App description', - enableTypeScript: true, - viewName: 'view-test', - ui5Version: '1.120.0' - }; - const basePath = join('some/path'); - const testOutputPath = join(basePath, 'webapp/test'); - fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); - - const expectedFiles = [ - 'integration/NavigationJourney.ts', - 'integration/opaTests.qunit.html', - 'integration/pages/AppPage.ts', - 'integration/pages/view-testPage.ts', - 'testsuite.qunit.ts', - 'unit/controller/view-testPage.controller.ts', - 'unit/unitTests.qunit.html', - 'unit/unitTests.qunit.ts' - ]; - expectedFiles.map((file: string) => { - expect(fs?.exists(join(testOutputPath, file))).toBe(true); - }); - - // check unit/unitTests.qunit.ts - const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.ts')); - expect(removeSpaces(unitTestQUnit)).toBe( - removeSpaces(` - /* @sapUiRequire */ - QUnit.config.autostart = false; - - // import all your QUnit tests here - void Promise.all([ - import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests - import("unit/controller/view-testPage.controller") - ]).then(([{ default: Core }]) => { - QUnit.start(); - });`) - ); - - // check unit/unitTests.qunit.html - const unitTestHTML = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.html')); - expect(removeSpaces(unitTestHTML)).toBe( - removeSpaces(` - - - - - Unit tests for test-app-typescript - - - - - - - - - - -
-
- - `) - ); - - // check integration/opaTests.qunit.ts - const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.ts')); - expect(removeSpaces(opaTests)).toBe( - removeSpaces(` - /* global QUnit */ - sap.ui.require(["integration/NavigationJourney" - ], function () { - QUnit.config.autostart = false; - QUnit.start(); - });`) - ); - - // check integration/opaTests.qunit.html - const opaTestsHTML = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.html')); - expect(removeSpaces(opaTestsHTML)).toBe( - removeSpaces(` - - - - - Integration tests for Basic Template - - - - - - - -
-
- - - `) - ); - }); + // test('Generate OPA test files correctly when typescript is not enabled', async () => { + // const opaConfig = { + // appId: 'test-app-js', + // applicationTitle: 'App test', + // applicationDescription: 'App description', + // viewName: 'view-test', + // ui5Version: '1.71.0' + // }; + // const basePath = join('some/path'); + // const testOutputPath = join(basePath, 'webapp/test'); + // fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); + + // const expectedFiles = [ + // 'integration/NavigationJourney.js', + // 'integration/opaTests.qunit.html', + // 'integration/pages/App.js', + // 'integration/pages/view-test.js', + // 'testsuite.qunit.js', + // 'unit/controller/view-test.controller.js', + // 'unit/unitTests.qunit.html', + // 'unit/unitTests.qunit.js' + // ]; + // expectedFiles.map((file: string) => { + // expect(fs?.exists(join(testOutputPath, file))).toBe(true); + // }); + + // // check unit/unitTests.qunit.js + // const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.js')); + // expect(removeSpaces(unitTestQUnit)).toBe( + // removeSpaces(` + // /* global QUnit */ + // QUnit.config.autostart = false; + + // sap.ui.getCore().attachInit(function () { + // "use strict"; + + // sap.ui.require([ + // "test-app-js/test/unit/AllTests" + // ], function () { + // QUnit.start(); + // }); + // });`) + // ); + + // // check unit/controller/view-test.controller.js + // const viewTestController = fs?.read(join(testOutputPath, 'unit/controller/view-test.controller.js')); + // expect(removeSpaces(viewTestController)).toBe( + // removeSpaces(` + // /*global QUnit*/ + + // sap.ui.define([ + // "test-app-js/controller/view-test.controller" + // ], function (Controller) { + // "use strict"; + + // QUnit.module("view-test Controller"); + + // QUnit.test("I should test the view-test controller", function (assert) { + // var oAppController = new Controller(); + // oAppController.onInit(); + // assert.ok(oAppController); + // }); + + // }); + // `) + // ); + + // // check test/testsuite.qunit.js + // const testSuiteQUnit = fs?.read(join(testOutputPath, 'testsuite.qunit.js')); + // expect(removeSpaces(testSuiteQUnit)).toBe( + // removeSpaces(` + // /* global window, parent, location */ + + // // eslint-disable-next-line fiori-custom/sap-no-global-define + // window.suite = function() { + // "use strict"; + + // // eslint-disable-next-line + // var oSuite = new parent.jsUnitTestSuite(), + + // sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + // oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html'); + // oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + + // return oSuite; + // }; + // `) + // ); + + // // check integration/pages/view-test.js + // const viewTest = fs?.read(join(testOutputPath, 'integration/pages/view-test.js')); + // expect(removeSpaces(viewTest)).toBe( + // removeSpaces(` + // sap.ui.define([ + // "sap/ui/test/Opa5" + // ], function (Opa5) { + // "use strict"; + // var sViewName = "view-test"; + + // Opa5.createPageObjects({ + // onTheViewPage: { + + // actions: {}, + + // assertions: { + + // iShouldSeeThePageView: function () { + // return this.waitFor({ + // id: "page", + // viewName: sViewName, + // success: function () { + // Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + // }, + // errorMessage: "Did not find the " + sViewName + " view" + // }); + // } + // } + // } + // }); + + // });`) + // ); + + // // check integration/pages/App.js + // const app = fs?.read(join(testOutputPath, 'integration/pages/App.js')); + // expect(removeSpaces(app)).toBe( + // removeSpaces(` + // sap.ui.define([ + // "sap/ui/test/Opa5" + // ], function (Opa5) { + // "use strict"; + // var sViewName = "App"; + + // Opa5.createPageObjects({ + // onTheAppPage: { + + // actions: {}, + + // assertions: { + + // iShouldSeeTheApp: function () { + // return this.waitFor({ + // id: "app", + // viewName: sViewName, + // success: function () { + // Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + // }, + // errorMessage: "Did not find the " + sViewName + " view" + // }); + // } + // } + // } + // }); + + // }); + // `) + // ); + + // // check integration/opaTests.qunit.js + // const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.js')); + // expect(removeSpaces(opaTests)).toBe( + // removeSpaces(` + // /* global QUnit */ + + // sap.ui.require(["test-app-js/test/integration/AllJourneys" + // ], function () { + // QUnit.config.autostart = false; + // QUnit.start(); + // });`) + // ); + + // // check integration/NavigationJourney.js + // const navigationJourney = fs?.read(join(testOutputPath, 'integration/NavigationJourney.js')); + // expect(removeSpaces(navigationJourney)).toBe( + // removeSpaces(` + // /*global QUnit*/ + + // sap.ui.define([ + // "sap/ui/test/opaQunit", + // "./pages/App", + // "./pages/view-test" + // ], function (opaTest) { + // "use strict"; + + // QUnit.module("Navigation Journey"); + + // opaTest("Should see the initial page of the app", function (Given, When, Then) { + // // Arrangements + // Given.iStartMyApp(); + + // // Assertions + // Then.onTheAppPage.iShouldSeeTheApp(); + // Then.onTheViewPage.iShouldSeeThePageView(); + + // //Cleanup + // Then.iTeardownMyApp(); + // }); + // }); + // `) + // ); + // }); + + // test('Generate OPA test files correctly when ui5Version is 1.120.0', async () => { + // const opaConfig = { + // appId: 'test-app-typescript', + // applicationTitle: 'App test', + // applicationDescription: 'App description', + // enableTypeScript: true, + // viewName: 'view-test', + // ui5Version: '1.120.0' + // }; + // const basePath = join('some/path'); + // const testOutputPath = join(basePath, 'webapp/test'); + // fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); + + // const expectedFiles = [ + // 'integration/NavigationJourney.ts', + // 'integration/opaTests.qunit.html', + // 'integration/pages/AppPage.ts', + // 'integration/pages/view-testPage.ts', + // 'testsuite.qunit.ts', + // 'unit/controller/view-testPage.controller.ts', + // 'unit/unitTests.qunit.html', + // 'unit/unitTests.qunit.ts' + // ]; + // expectedFiles.map((file: string) => { + // expect(fs?.exists(join(testOutputPath, file))).toBe(true); + // }); + + // // check unit/unitTests.qunit.ts + // const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.ts')); + // expect(removeSpaces(unitTestQUnit)).toBe( + // removeSpaces(` + // /* @sapUiRequire */ + // QUnit.config.autostart = false; + + // // import all your QUnit tests here + // void Promise.all([ + // import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests + // import("unit/controller/view-testPage.controller") + // ]).then(([{ default: Core }]) => { + // QUnit.start(); + // });`) + // ); + + // // check unit/unitTests.qunit.html + // const unitTestHTML = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.html')); + // expect(removeSpaces(unitTestHTML)).toBe( + // removeSpaces(` + // + // + // + // + // Unit tests for test-app-typescript + // + // + // + // + // + // + // + // + // + // + //
+ //
+ // + // `) + // ); + + // // check integration/opaTests.qunit.ts + // const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.ts')); + // expect(removeSpaces(opaTests)).toBe( + // removeSpaces(` + // /* global QUnit */ + // sap.ui.require(["integration/NavigationJourney" + // ], function () { + // QUnit.config.autostart = false; + // QUnit.start(); + // });`) + // ); + + // // check integration/opaTests.qunit.html + // const opaTestsHTML = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.html')); + // expect(removeSpaces(opaTestsHTML)).toBe( + // removeSpaces(` + // + // + // + // + // Integration tests for Basic Template + + // + // + // + // + // + // + //
+ //
+ // + // + // `) + // ); + // }); }); -describe('writeOPATsconfigJsonUpdates', () => { - let fs: Editor; - let log: Logger; - - const opaConfig = { - appId: 'test-app-typescript', - applicationTitle: 'App test', - applicationDescription: 'App description', - enableTypeScript: true, - viewName: 'view-test', - ui5Version: '1.71.0' - }; - - beforeEach(() => { - fs = { - readJSON: jest.fn(), - writeJSON: jest.fn(), - copyTpl: jest.fn() - } as unknown as Editor; - - log = { - error: jest.fn() - } as unknown as Logger; - }); - - test('should log an error when writing to tsconfig.json fails', async () => { - const mockError = new Error('Write error'); - - (fs.writeJSON as jest.Mock).mockImplementation(() => { - throw mockError; - }); - const basePath = join('some/path'); - fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); - - expect(log.error).toHaveBeenCalled(); - expect(log.error).toHaveBeenCalledWith( - t('error.errorWritingTsConfig', { - error: mockError - }) - ); - }); - - test('should log an error when copying templates', async () => { - const mockError = new Error('copy template error'); - - (fs.copyTpl as jest.Mock).mockImplementation(() => { - throw mockError; - }); - - const basePath = join('some/path'); - fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); - - expect(log.error).toHaveBeenCalled(); - expect(log.error).toHaveBeenCalledWith( - t('error.errorCopyingFreestyleTestTemplates', { - error: mockError - }) - ); - }); -}); +// describe('writeOPATsconfigJsonUpdates', () => { +// let fs: Editor; +// let log: Logger; + +// const opaConfig = { +// appId: 'test-app-typescript', +// applicationTitle: 'App test', +// applicationDescription: 'App description', +// enableTypeScript: true, +// viewName: 'view-test', +// ui5Version: '1.71.0' +// }; + +// beforeEach(() => { +// fs = { +// readJSON: jest.fn(), +// writeJSON: jest.fn(), +// copyTpl: jest.fn() +// } as unknown as Editor; + +// log = { +// error: jest.fn() +// } as unknown as Logger; +// }); + +// test('should log an error when writing to tsconfig.json fails', async () => { +// const mockError = new Error('Write error'); + +// (fs.writeJSON as jest.Mock).mockImplementation(() => { +// throw mockError; +// }); +// const basePath = join('some/path'); +// fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); + +// expect(log.error).toHaveBeenCalled(); +// expect(log.error).toHaveBeenCalledWith( +// t('error.errorWritingTsConfig', { +// error: mockError +// }) +// ); +// }); + +// test('should log an error when copying templates', async () => { +// const mockError = new Error('copy template error'); + +// (fs.copyTpl as jest.Mock).mockImplementation(() => { +// throw mockError; +// }); + +// const basePath = join('some/path'); +// fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); + +// expect(log.error).toHaveBeenCalled(); +// expect(log.error).toHaveBeenCalledWith( +// t('error.errorCopyingFreestyleTestTemplates', { +// error: mockError +// }) +// ); +// }); +// }); From 43d4c7fc46d68ecb873508dd6d0b050be991d3eb Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 13:11:44 +0000 Subject: [PATCH 39/42] add generateOPATests --- packages/fiori-freestyle-writer/src/index.ts | 29 ++------------------ 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/packages/fiori-freestyle-writer/src/index.ts b/packages/fiori-freestyle-writer/src/index.ts index f9a36dc669..8cf23d60f0 100644 --- a/packages/fiori-freestyle-writer/src/index.ts +++ b/packages/fiori-freestyle-writer/src/index.ts @@ -14,23 +14,8 @@ import { getBootstrapResourceUrls, getPackageScripts } from '@sap-ux/fiori-gener import { getTemplateVersionPath, processDestinationPath } from './utils'; import { applyCAPUpdates, type CapProjectSettings } from '@sap-ux/cap-config-writer'; import type { Logger } from '@sap-ux/logger'; -import { generateFreestyleOPAFiles } from '@sap-ux/ui5-test-writer'; +import { generateOPATests } from './generateOPATests'; -/** - * Adds test scripts to the package.json object. - * - * @param {Package} packageJson - The package.json object to update. - * @param {boolean} addMock - Whether to include the UI5 mock YAML configuration. - */ -function addTestScripts(packageJson: Package, addMock: boolean): void { - // Note: 'ui5MockYamlScript' is empty when no data source is selected. - const ui5MockYamlScript = addMock ? '--config ./ui5-mock.yaml ' : ''; - packageJson.scripts = { - ...packageJson.scripts, - 'unit-test': `fiori run ${ui5MockYamlScript}--open 'test/unit/unitTests.qunit.html'`, - 'int-test': `fiori run ${ui5MockYamlScript}--open 'test/integration/opaTests.qunit.html'` - }; -} /** * Generate a UI5 application based on the specified Fiori Freestyle floorplan template. * @@ -171,17 +156,7 @@ async function generate(basePath: string, data: FreestyleApp, fs?: Editor, }) }; if (addTests) { - addTestScripts(packageJson, addMock); - const config = { - appId: ffApp.app.id, - applicationDescription: ffApp.app.description, - applicationTitle: ffApp.app.title, - viewName: (ffApp.template.settings as BasicAppSettings).viewName, - ui5Theme: ffApp.ui5?.ui5Theme, - ui5Version: ffApp.ui5?.version, - enableTypeScript: ffApp.appOptions?.typescript - }; - await generateFreestyleOPAFiles(basePath, config, fs, log); + await generateOPATests(basePath, ffApp, addMock, packageJson, fs, log); } } else { // Add deploy-config for CAP applications From b3c74b8491d7312afc7fbdb53f31087650786fc8 Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 13:12:34 +0000 Subject: [PATCH 40/42] add generateOPATests --- .../src/generateOPATests.ts | 54 ++++++++++++ .../test/generateOPATests.test.ts | 87 +++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 packages/fiori-freestyle-writer/src/generateOPATests.ts create mode 100644 packages/fiori-freestyle-writer/test/generateOPATests.test.ts diff --git a/packages/fiori-freestyle-writer/src/generateOPATests.ts b/packages/fiori-freestyle-writer/src/generateOPATests.ts new file mode 100644 index 0000000000..5b1a47a1ac --- /dev/null +++ b/packages/fiori-freestyle-writer/src/generateOPATests.ts @@ -0,0 +1,54 @@ +import { generateFreestyleOPAFiles } from '@sap-ux/ui5-test-writer'; +import type { Package } from '@sap-ux/ui5-application-writer'; +import type { FreestyleApp } from './types'; +import type { BasicAppSettings } from './types'; +import type { Logger } from '@sap-ux/logger'; +import type { Editor } from 'mem-fs-editor'; + +/** + * Adds test scripts to the package.json object. + * + * @param {Package} packageJson - The package.json object to update. + * @param {boolean} addMock - Whether to include the UI5 mock YAML configuration. + */ +function addTestScripts(packageJson: Package, addMock: boolean): void { + // Note: 'ui5MockYamlScript' is empty when no data source is selected. + const ui5MockYamlScript = addMock ? '--config ./ui5-mock.yaml ' : ''; + packageJson.scripts = { + ...packageJson.scripts, + 'unit-test': `fiori run ${ui5MockYamlScript}--open 'test/unit/unitTests.qunit.html'`, + 'int-test': `fiori run ${ui5MockYamlScript}--open 'test/integration/opaTests.qunit.html'` + }; +} + +/** + * Generates OPA tests for a freestyle application. + * + * @param {string} basePath - The base directory path. + * @param {FreestyleApp} ffApp - The freestyle application configuration. + * @param {boolean} addMock - Whether to include the UI5 mock YAML configuration. + * @param {Package} packageJson - The package.json object to update. + * @param {Editor} [fs] - Optional file system editor instance. + * @param {Logger} [log] - Optional logger instance. + * @returns {Promise} - The modified file system editor. + */ +export async function generateOPATests( + basePath: string, + ffApp: FreestyleApp, + addMock: boolean, + packageJson: Package, + fs?: Editor, + log?: Logger +): Promise { + addTestScripts(packageJson, addMock); + const config = { + appId: ffApp.app.id, + applicationDescription: ffApp.app.description, + applicationTitle: ffApp.app.title, + viewName: (ffApp.template.settings as BasicAppSettings).viewName, + ui5Theme: ffApp.ui5?.ui5Theme, + ui5Version: ffApp.ui5?.version, + enableTypeScript: ffApp.appOptions?.typescript + }; + await generateFreestyleOPAFiles(basePath, config, fs, log); +} diff --git a/packages/fiori-freestyle-writer/test/generateOPATests.test.ts b/packages/fiori-freestyle-writer/test/generateOPATests.test.ts new file mode 100644 index 0000000000..d95e81c5bd --- /dev/null +++ b/packages/fiori-freestyle-writer/test/generateOPATests.test.ts @@ -0,0 +1,87 @@ +import { generateOPATests } from '../src/generateOPATests'; +import { generateFreestyleOPAFiles } from '@sap-ux/ui5-test-writer'; +import type { FreestyleApp, BasicAppSettings } from '../src/types'; +import type { Package } from '@sap-ux/ui5-application-writer'; + +jest.mock('@sap-ux/ui5-test-writer', () => ({ + generateFreestyleOPAFiles: jest.fn() +})); + +describe('generateOPATests', () => { + const basePath = '/path/to/base'; + const ffApp = { + app: { + id: 'appId', + description: 'App Description', + title: 'App Title' + }, + template: { + settings: { + viewName: 'ViewName' + } + }, + ui5: { + ui5Theme: 'sap_fiori_3', + version: '1.71.0' + }, + appOptions: { + typescript: true + } + } as FreestyleApp; + + const packageJson = { + scripts: { + 'start-mock': 'fiori run --config ./ui5-mock.yaml --open "test/flpSandbox.html"' + } + } as Package; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should add test scripts to package.json when addMock is true', async () => { + const addMock = true; + await generateOPATests(basePath, ffApp, addMock, packageJson); + expect(generateFreestyleOPAFiles).toHaveBeenCalledWith( + basePath, + { + appId: 'appId', + applicationDescription: 'App Description', + applicationTitle: 'App Title', + viewName: 'ViewName', + ui5Theme: 'sap_fiori_3', + ui5Version: '1.71.0', + enableTypeScript: true + }, + undefined, + undefined + ); + expect(packageJson.scripts?.['unit-test']).toBe( + "fiori run --config ./ui5-mock.yaml --open 'test/unit/unitTests.qunit.html'" + ); + expect(packageJson.scripts?.['int-test']).toBe( + "fiori run --config ./ui5-mock.yaml --open 'test/integration/opaTests.qunit.html'" + ); + }); + + it('should add test scripts to package.json when addMock is false', async () => { + const addMock = false; + await generateOPATests(basePath, ffApp, addMock, packageJson); + expect(generateFreestyleOPAFiles).toHaveBeenCalledWith( + basePath, + { + appId: 'appId', + applicationDescription: 'App Description', + applicationTitle: 'App Title', + viewName: 'ViewName', + ui5Theme: 'sap_fiori_3', + ui5Version: '1.71.0', + enableTypeScript: true + }, + undefined, + undefined + ); + expect(packageJson.scripts?.['unit-test']).toBe("fiori run --open 'test/unit/unitTests.qunit.html'"); + expect(packageJson.scripts?.['int-test']).toBe("fiori run --open 'test/integration/opaTests.qunit.html'"); + }); +}); From ed182a9877f48dd0f503389d35c3db04a1f976fa Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 14:51:43 +0000 Subject: [PATCH 41/42] add viewpath to manifest template --- .../src/generateOPATests.ts | 3 +- .../basic/extend/1.120.0/webapp/manifest.json | 7 +- .../test/__snapshots__/basic.test.ts.snap | 21 +- .../src/fiori-freestyle-opa-writer.ts | 118 ++- .../test/unit/fiori-freestyle.test.ts | 774 +++++++++--------- 5 files changed, 457 insertions(+), 466 deletions(-) diff --git a/packages/fiori-freestyle-writer/src/generateOPATests.ts b/packages/fiori-freestyle-writer/src/generateOPATests.ts index 5b1a47a1ac..9666068cee 100644 --- a/packages/fiori-freestyle-writer/src/generateOPATests.ts +++ b/packages/fiori-freestyle-writer/src/generateOPATests.ts @@ -1,7 +1,6 @@ import { generateFreestyleOPAFiles } from '@sap-ux/ui5-test-writer'; import type { Package } from '@sap-ux/ui5-application-writer'; -import type { FreestyleApp } from './types'; -import type { BasicAppSettings } from './types'; +import type { FreestyleApp, BasicAppSettings } from './types'; import type { Logger } from '@sap-ux/logger'; import type { Editor } from 'mem-fs-editor'; diff --git a/packages/fiori-freestyle-writer/templates/basic/extend/1.120.0/webapp/manifest.json b/packages/fiori-freestyle-writer/templates/basic/extend/1.120.0/webapp/manifest.json index d90b31b1a8..f6ff805d05 100644 --- a/packages/fiori-freestyle-writer/templates/basic/extend/1.120.0/webapp/manifest.json +++ b/packages/fiori-freestyle-writer/templates/basic/extend/1.120.0/webapp/manifest.json @@ -3,7 +3,8 @@ "rootView": { "viewName": "<%- app.id %>.view.App", "type": "XML", - "id": "App" + "id": "App", + "async": true }, "resources": { "css": [ @@ -20,7 +21,9 @@ "transition": "slide", "type": "View", "viewType": "XML", - "path": "<%- app.id %>.view" + "path": "<%- app.id %>.view", + "async": true, + "viewPath": "<%- app.id %>.view" }, "routes": [ { diff --git a/packages/fiori-freestyle-writer/test/__snapshots__/basic.test.ts.snap b/packages/fiori-freestyle-writer/test/__snapshots__/basic.test.ts.snap index 8951fa1612..1253cad1c8 100644 --- a/packages/fiori-freestyle-writer/test/__snapshots__/basic.test.ts.snap +++ b/packages/fiori-freestyle-writer/test/__snapshots__/basic.test.ts.snap @@ -4504,7 +4504,9 @@ title=App Title", \\"transition\\": \\"slide\\", \\"type\\": \\"View\\", \\"viewType\\": \\"XML\\", - \\"path\\": \\"nods1.view\\" + \\"path\\": \\"nods1.view\\", + \\"async\\": true, + \\"viewPath\\": \\"nods1.view\\" }, \\"routes\\": [ { @@ -4525,7 +4527,8 @@ title=App Title", \\"rootView\\": { \\"viewName\\": \\"nods1.view.App\\", \\"type\\": \\"XML\\", - \\"id\\": \\"App\\" + \\"id\\": \\"App\\", + \\"async\\": true } } } @@ -5028,7 +5031,9 @@ title=App Title", \\"transition\\": \\"slide\\", \\"type\\": \\"View\\", \\"viewType\\": \\"XML\\", - \\"path\\": \\"nods1.view\\" + \\"path\\": \\"nods1.view\\", + \\"async\\": true, + \\"viewPath\\": \\"nods1.view\\" }, \\"routes\\": [ { @@ -5049,7 +5054,8 @@ title=App Title", \\"rootView\\": { \\"viewName\\": \\"nods1.view.App\\", \\"type\\": \\"XML\\", - \\"id\\": \\"App\\" + \\"id\\": \\"App\\", + \\"async\\": true } } } @@ -5577,7 +5583,9 @@ title=App Title", \\"transition\\": \\"slide\\", \\"type\\": \\"View\\", \\"viewType\\": \\"XML\\", - \\"path\\": \\"nods1.view\\" + \\"path\\": \\"nods1.view\\", + \\"async\\": true, + \\"viewPath\\": \\"nods1.view\\" }, \\"routes\\": [ { @@ -5598,7 +5606,8 @@ title=App Title", \\"rootView\\": { \\"viewName\\": \\"nods1.view.App\\", \\"type\\": \\"XML\\", - \\"id\\": \\"App\\" + \\"id\\": \\"App\\", + \\"async\\": true } } } diff --git a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts index a08da3dec4..fd3e10ed3d 100644 --- a/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts +++ b/packages/ui5-test-writer/src/fiori-freestyle-opa-writer.ts @@ -49,51 +49,6 @@ function getTemplateUi5Version(ui5Version?: string): string { return compareUI5VersionGte(ui5Version, templateLtsVersion_1_120) ? templateLtsVersion_1_120 : ui5LtsVersion_1_71; } -/** - * Copies filtered test template files from source directory to destination directory, - * with file renaming logic based on the view name. - * - * @param {string} sourceDir - The path to the source directory containing template files. - * @param {string} ouputDir - The path to the destination directory where files should be copied. - * @param {string[]} filteredFiles - An array of filtered file paths to copy. - * @param {FFOPAConfig} opaConfig - The OPA test configuration object to write into template files. - * @param {Editor} editor - The editor instance used to copy and render template files. - * @param {Logger} [log] - The logger instance. - * @param {Record} [renameMap] - Optional rename mapping for file paths. - * @param {string} [templateUi5Version] - The template UI5 version. - * @returns {boolean} - resolves to `true` if the files were copied successfully, - * or `false` if there was an error during the process. - */ -function copyTemplates( - sourceDir: string, - ouputDir: string, - filteredFiles: string[], - opaConfig: FFOPAConfig & { addUnitTests?: boolean }, - editor: Editor, - log?: Logger, - renameMap?: Record, - templateUi5Version?: string -): boolean { - try { - filteredFiles.forEach((filePath: string) => { - // remove template UI5 version from the path - const destFilePath = filePath.replace(sourceDir, '').replace(`/${templateUi5Version}/`, '/'); - const destinationFilePath = join(ouputDir, renameMap?.[destFilePath] ?? destFilePath); - editor.copyTpl(filePath, destinationFilePath, opaConfig, undefined, { - globOptions: { dot: true } - }); - }); - return true; - } catch (error) { - log?.error( - t('error.errorCopyingFreestyleTestTemplates', { - error: error - }) - ); - return false; - } -} - /** * Filters files based on the template UI5 version. * @@ -132,6 +87,30 @@ function filterByTypeScript(files: string[], isTypeScript: boolean): string[] { }); } +/** + * Determines the destination file path based on the provided file path. + * + * @param {string} filePath - The original file path. + * @param {string} freestyleTemplateDir - The directory file path to be removed from the path. + * @param {string} commonTemplateDir - The directory file to be removed for common templates path. + * @param {string} templateUi5Version - The UI5 version to be replaced in the path. + * @returns {string} - The transformed destination file path. + */ +function getDestFilePath( + filePath: string, + freestyleTemplateDir: string, + commonTemplateDir: string, + templateUi5Version: string +): string { + if (filePath.includes(freestyleTemplateDir)) { + return filePath.replace(freestyleTemplateDir, '').replace(`/${templateUi5Version}/`, '/'); + } else if (filePath.includes(commonTemplateDir)) { + return filePath.replace(commonTemplateDir, ''); + } else { + return filePath; + } +} + /** * Generates and copies freestyle test files based on configuration. * @@ -164,6 +143,11 @@ export async function generateFreestyleOPAFiles( const templateFilteredFiles = filterByUi5Version(templateFiles, templateUi5Version); const filteredFiles = filterByTypeScript(templateFilteredFiles, isTypeScript); + // copy common templates + const commonFiles = await getFilePaths(commonTemplateDir); + const filteredCommonFiles = commonFiles.filter((filePath: string) => filePath.endsWith('.html')); + filteredFiles.push(...filteredCommonFiles); + const config = { ...opaConfig, viewNamePage: `${viewName}Page`, @@ -181,31 +165,27 @@ export async function generateFreestyleOPAFiles( '/unit/controller/viewName.controller.js': `unit/controller/${viewName}.controller.js`, '/unit/controller/viewName.controller.ts': `unit/controller/${viewName}Page.controller.ts` }; - // copy freestyle templates - const freestyleTestTemplatesCopied = copyTemplates( - freestyleTemplateDir, - testOutDir, - filteredFiles, - config, - fsEditor, - log, - renameMap, - templateUi5Version - ); - - // copy common templates - const commonFiles = await getFilePaths(commonTemplateDir); - const filteredCommonFiles = commonFiles.filter((filePath: string) => filePath.endsWith('.html')); + // copy templates + let freestyleTestTemplatesCopied = false; + try { + filteredFiles.forEach((filePath: string) => { + // remove template UI5 version from the path + const destFilePath = getDestFilePath(filePath, freestyleTemplateDir, commonTemplateDir, templateUi5Version); + const destinationFilePath = join(testOutDir, renameMap?.[destFilePath] ?? destFilePath); + fsEditor.copyTpl(filePath, destinationFilePath, config, undefined, { + globOptions: { dot: true } + }); + }); + freestyleTestTemplatesCopied = true; + } catch (error) { + log?.error( + t('error.errorCopyingFreestyleTestTemplates', { + error: error + }) + ); + } - const commonTemplatesCopied = copyTemplates( - commonTemplateDir, - testOutDir, - filteredCommonFiles, - { appId }, - fsEditor, - log - ); - if (commonTemplatesCopied && freestyleTestTemplatesCopied && isTypeScript) { + if (freestyleTestTemplatesCopied && isTypeScript) { writeOPATsconfigJsonUpdates(fsEditor, basePath, log); } diff --git a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts index 5b7e81d514..89ab31005a 100644 --- a/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts +++ b/packages/ui5-test-writer/test/unit/fiori-freestyle.test.ts @@ -308,392 +308,392 @@ describe('ui5-test-writer - Freestyle OPA Integration tests', () => { ); }); - // test('Generate OPA test files correctly when typescript is not enabled', async () => { - // const opaConfig = { - // appId: 'test-app-js', - // applicationTitle: 'App test', - // applicationDescription: 'App description', - // viewName: 'view-test', - // ui5Version: '1.71.0' - // }; - // const basePath = join('some/path'); - // const testOutputPath = join(basePath, 'webapp/test'); - // fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); - - // const expectedFiles = [ - // 'integration/NavigationJourney.js', - // 'integration/opaTests.qunit.html', - // 'integration/pages/App.js', - // 'integration/pages/view-test.js', - // 'testsuite.qunit.js', - // 'unit/controller/view-test.controller.js', - // 'unit/unitTests.qunit.html', - // 'unit/unitTests.qunit.js' - // ]; - // expectedFiles.map((file: string) => { - // expect(fs?.exists(join(testOutputPath, file))).toBe(true); - // }); - - // // check unit/unitTests.qunit.js - // const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.js')); - // expect(removeSpaces(unitTestQUnit)).toBe( - // removeSpaces(` - // /* global QUnit */ - // QUnit.config.autostart = false; - - // sap.ui.getCore().attachInit(function () { - // "use strict"; - - // sap.ui.require([ - // "test-app-js/test/unit/AllTests" - // ], function () { - // QUnit.start(); - // }); - // });`) - // ); - - // // check unit/controller/view-test.controller.js - // const viewTestController = fs?.read(join(testOutputPath, 'unit/controller/view-test.controller.js')); - // expect(removeSpaces(viewTestController)).toBe( - // removeSpaces(` - // /*global QUnit*/ - - // sap.ui.define([ - // "test-app-js/controller/view-test.controller" - // ], function (Controller) { - // "use strict"; - - // QUnit.module("view-test Controller"); - - // QUnit.test("I should test the view-test controller", function (assert) { - // var oAppController = new Controller(); - // oAppController.onInit(); - // assert.ok(oAppController); - // }); - - // }); - // `) - // ); - - // // check test/testsuite.qunit.js - // const testSuiteQUnit = fs?.read(join(testOutputPath, 'testsuite.qunit.js')); - // expect(removeSpaces(testSuiteQUnit)).toBe( - // removeSpaces(` - // /* global window, parent, location */ - - // // eslint-disable-next-line fiori-custom/sap-no-global-define - // window.suite = function() { - // "use strict"; - - // // eslint-disable-next-line - // var oSuite = new parent.jsUnitTestSuite(), - - // sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); - // oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html'); - // oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); - - // return oSuite; - // }; - // `) - // ); - - // // check integration/pages/view-test.js - // const viewTest = fs?.read(join(testOutputPath, 'integration/pages/view-test.js')); - // expect(removeSpaces(viewTest)).toBe( - // removeSpaces(` - // sap.ui.define([ - // "sap/ui/test/Opa5" - // ], function (Opa5) { - // "use strict"; - // var sViewName = "view-test"; - - // Opa5.createPageObjects({ - // onTheViewPage: { - - // actions: {}, - - // assertions: { - - // iShouldSeeThePageView: function () { - // return this.waitFor({ - // id: "page", - // viewName: sViewName, - // success: function () { - // Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - // }, - // errorMessage: "Did not find the " + sViewName + " view" - // }); - // } - // } - // } - // }); - - // });`) - // ); - - // // check integration/pages/App.js - // const app = fs?.read(join(testOutputPath, 'integration/pages/App.js')); - // expect(removeSpaces(app)).toBe( - // removeSpaces(` - // sap.ui.define([ - // "sap/ui/test/Opa5" - // ], function (Opa5) { - // "use strict"; - // var sViewName = "App"; - - // Opa5.createPageObjects({ - // onTheAppPage: { - - // actions: {}, - - // assertions: { - - // iShouldSeeTheApp: function () { - // return this.waitFor({ - // id: "app", - // viewName: sViewName, - // success: function () { - // Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); - // }, - // errorMessage: "Did not find the " + sViewName + " view" - // }); - // } - // } - // } - // }); - - // }); - // `) - // ); - - // // check integration/opaTests.qunit.js - // const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.js')); - // expect(removeSpaces(opaTests)).toBe( - // removeSpaces(` - // /* global QUnit */ - - // sap.ui.require(["test-app-js/test/integration/AllJourneys" - // ], function () { - // QUnit.config.autostart = false; - // QUnit.start(); - // });`) - // ); - - // // check integration/NavigationJourney.js - // const navigationJourney = fs?.read(join(testOutputPath, 'integration/NavigationJourney.js')); - // expect(removeSpaces(navigationJourney)).toBe( - // removeSpaces(` - // /*global QUnit*/ - - // sap.ui.define([ - // "sap/ui/test/opaQunit", - // "./pages/App", - // "./pages/view-test" - // ], function (opaTest) { - // "use strict"; - - // QUnit.module("Navigation Journey"); - - // opaTest("Should see the initial page of the app", function (Given, When, Then) { - // // Arrangements - // Given.iStartMyApp(); - - // // Assertions - // Then.onTheAppPage.iShouldSeeTheApp(); - // Then.onTheViewPage.iShouldSeeThePageView(); - - // //Cleanup - // Then.iTeardownMyApp(); - // }); - // }); - // `) - // ); - // }); - - // test('Generate OPA test files correctly when ui5Version is 1.120.0', async () => { - // const opaConfig = { - // appId: 'test-app-typescript', - // applicationTitle: 'App test', - // applicationDescription: 'App description', - // enableTypeScript: true, - // viewName: 'view-test', - // ui5Version: '1.120.0' - // }; - // const basePath = join('some/path'); - // const testOutputPath = join(basePath, 'webapp/test'); - // fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); - - // const expectedFiles = [ - // 'integration/NavigationJourney.ts', - // 'integration/opaTests.qunit.html', - // 'integration/pages/AppPage.ts', - // 'integration/pages/view-testPage.ts', - // 'testsuite.qunit.ts', - // 'unit/controller/view-testPage.controller.ts', - // 'unit/unitTests.qunit.html', - // 'unit/unitTests.qunit.ts' - // ]; - // expectedFiles.map((file: string) => { - // expect(fs?.exists(join(testOutputPath, file))).toBe(true); - // }); - - // // check unit/unitTests.qunit.ts - // const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.ts')); - // expect(removeSpaces(unitTestQUnit)).toBe( - // removeSpaces(` - // /* @sapUiRequire */ - // QUnit.config.autostart = false; - - // // import all your QUnit tests here - // void Promise.all([ - // import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests - // import("unit/controller/view-testPage.controller") - // ]).then(([{ default: Core }]) => { - // QUnit.start(); - // });`) - // ); - - // // check unit/unitTests.qunit.html - // const unitTestHTML = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.html')); - // expect(removeSpaces(unitTestHTML)).toBe( - // removeSpaces(` - // - // - // - // - // Unit tests for test-app-typescript - // - // - // - // - // - // - // - // - // - // - //
- //
- // - // `) - // ); - - // // check integration/opaTests.qunit.ts - // const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.ts')); - // expect(removeSpaces(opaTests)).toBe( - // removeSpaces(` - // /* global QUnit */ - // sap.ui.require(["integration/NavigationJourney" - // ], function () { - // QUnit.config.autostart = false; - // QUnit.start(); - // });`) - // ); - - // // check integration/opaTests.qunit.html - // const opaTestsHTML = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.html')); - // expect(removeSpaces(opaTestsHTML)).toBe( - // removeSpaces(` - // - // - // - // - // Integration tests for Basic Template - - // - // - // - // - // - // - //
- //
- // - // - // `) - // ); - // }); + test('Generate OPA test files correctly when typescript is not enabled', async () => { + const opaConfig = { + appId: 'test-app-js', + applicationTitle: 'App test', + applicationDescription: 'App description', + viewName: 'view-test', + ui5Version: '1.71.0' + }; + const basePath = join('some/path'); + const testOutputPath = join(basePath, 'webapp/test'); + fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); + + const expectedFiles = [ + 'integration/NavigationJourney.js', + 'integration/opaTests.qunit.html', + 'integration/pages/App.js', + 'integration/pages/view-test.js', + 'testsuite.qunit.js', + 'unit/controller/view-test.controller.js', + 'unit/unitTests.qunit.html', + 'unit/unitTests.qunit.js' + ]; + expectedFiles.map((file: string) => { + expect(fs?.exists(join(testOutputPath, file))).toBe(true); + }); + + // check unit/unitTests.qunit.js + const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.js')); + expect(removeSpaces(unitTestQUnit)).toBe( + removeSpaces(` + /* global QUnit */ + QUnit.config.autostart = false; + + sap.ui.getCore().attachInit(function () { + "use strict"; + + sap.ui.require([ + "test-app-js/test/unit/AllTests" + ], function () { + QUnit.start(); + }); + });`) + ); + + // check unit/controller/view-test.controller.js + const viewTestController = fs?.read(join(testOutputPath, 'unit/controller/view-test.controller.js')); + expect(removeSpaces(viewTestController)).toBe( + removeSpaces(` + /*global QUnit*/ + + sap.ui.define([ + "test-app-js/controller/view-test.controller" + ], function (Controller) { + "use strict"; + + QUnit.module("view-test Controller"); + + QUnit.test("I should test the view-test controller", function (assert) { + var oAppController = new Controller(); + oAppController.onInit(); + assert.ok(oAppController); + }); + + }); + `) + ); + + // check test/testsuite.qunit.js + const testSuiteQUnit = fs?.read(join(testOutputPath, 'testsuite.qunit.js')); + expect(removeSpaces(testSuiteQUnit)).toBe( + removeSpaces(` + /* global window, parent, location */ + + // eslint-disable-next-line fiori-custom/sap-no-global-define + window.suite = function() { + "use strict"; + + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1); + oSuite.addTestPage(sContextPath + 'unit/unitTests.qunit.html'); + oSuite.addTestPage(sContextPath + 'integration/opaTests.qunit.html'); + + return oSuite; + }; + `) + ); + + // check integration/pages/view-test.js + const viewTest = fs?.read(join(testOutputPath, 'integration/pages/view-test.js')); + expect(removeSpaces(viewTest)).toBe( + removeSpaces(` + sap.ui.define([ + "sap/ui/test/Opa5" + ], function (Opa5) { + "use strict"; + var sViewName = "view-test"; + + Opa5.createPageObjects({ + onTheViewPage: { + + actions: {}, + + assertions: { + + iShouldSeeThePageView: function () { + return this.waitFor({ + id: "page", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + + });`) + ); + + // check integration/pages/App.js + const app = fs?.read(join(testOutputPath, 'integration/pages/App.js')); + expect(removeSpaces(app)).toBe( + removeSpaces(` + sap.ui.define([ + "sap/ui/test/Opa5" + ], function (Opa5) { + "use strict"; + var sViewName = "App"; + + Opa5.createPageObjects({ + onTheAppPage: { + + actions: {}, + + assertions: { + + iShouldSeeTheApp: function () { + return this.waitFor({ + id: "app", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, "The " + sViewName + " view is displayed"); + }, + errorMessage: "Did not find the " + sViewName + " view" + }); + } + } + } + }); + + }); + `) + ); + + // check integration/opaTests.qunit.js + const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.js')); + expect(removeSpaces(opaTests)).toBe( + removeSpaces(` + /* global QUnit */ + + sap.ui.require(["test-app-js/test/integration/AllJourneys" + ], function () { + QUnit.config.autostart = false; + QUnit.start(); + });`) + ); + + // check integration/NavigationJourney.js + const navigationJourney = fs?.read(join(testOutputPath, 'integration/NavigationJourney.js')); + expect(removeSpaces(navigationJourney)).toBe( + removeSpaces(` + /*global QUnit*/ + + sap.ui.define([ + "sap/ui/test/opaQunit", + "./pages/App", + "./pages/view-test" + ], function (opaTest) { + "use strict"; + + QUnit.module("Navigation Journey"); + + opaTest("Should see the initial page of the app", function (Given, When, Then) { + // Arrangements + Given.iStartMyApp(); + + // Assertions + Then.onTheAppPage.iShouldSeeTheApp(); + Then.onTheViewPage.iShouldSeeThePageView(); + + //Cleanup + Then.iTeardownMyApp(); + }); + }); + `) + ); + }); + + test('Generate OPA test files correctly when ui5Version is 1.120.0', async () => { + const opaConfig = { + appId: 'test-app-typescript', + applicationTitle: 'App test', + applicationDescription: 'App description', + enableTypeScript: true, + viewName: 'view-test', + ui5Version: '1.120.0' + }; + const basePath = join('some/path'); + const testOutputPath = join(basePath, 'webapp/test'); + fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs); + + const expectedFiles = [ + 'integration/NavigationJourney.ts', + 'integration/opaTests.qunit.html', + 'integration/pages/AppPage.ts', + 'integration/pages/view-testPage.ts', + 'testsuite.qunit.ts', + 'unit/controller/view-testPage.controller.ts', + 'unit/unitTests.qunit.html', + 'unit/unitTests.qunit.ts' + ]; + expectedFiles.map((file: string) => { + expect(fs?.exists(join(testOutputPath, file))).toBe(true); + }); + + // check unit/unitTests.qunit.ts + const unitTestQUnit = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.ts')); + expect(removeSpaces(unitTestQUnit)).toBe( + removeSpaces(` + /* @sapUiRequire */ + QUnit.config.autostart = false; + + // import all your QUnit tests here + void Promise.all([ + import("sap/ui/core/Core"), // Required to wait until Core has booted to start the QUnit tests + import("unit/controller/view-testPage.controller") + ]).then(([{ default: Core }]) => { + QUnit.start(); + });`) + ); + + // check unit/unitTests.qunit.html + const unitTestHTML = fs?.read(join(testOutputPath, 'unit/unitTests.qunit.html')); + expect(removeSpaces(unitTestHTML)).toBe( + removeSpaces(` + + + + + Unit tests for test-app-typescript + + + + + + + + + + +
+
+ + `) + ); + + // check integration/opaTests.qunit.ts + const opaTests = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.ts')); + expect(removeSpaces(opaTests)).toBe( + removeSpaces(` + /* global QUnit */ + sap.ui.require(["integration/NavigationJourney" + ], function () { + QUnit.config.autostart = false; + QUnit.start(); + });`) + ); + + // check integration/opaTests.qunit.html + const opaTestsHTML = fs?.read(join(testOutputPath, 'integration/opaTests.qunit.html')); + expect(removeSpaces(opaTestsHTML)).toBe( + removeSpaces(` + + + + + Integration tests for Basic Template + + + + + + + +
+
+ + + `) + ); + }); }); -// describe('writeOPATsconfigJsonUpdates', () => { -// let fs: Editor; -// let log: Logger; - -// const opaConfig = { -// appId: 'test-app-typescript', -// applicationTitle: 'App test', -// applicationDescription: 'App description', -// enableTypeScript: true, -// viewName: 'view-test', -// ui5Version: '1.71.0' -// }; - -// beforeEach(() => { -// fs = { -// readJSON: jest.fn(), -// writeJSON: jest.fn(), -// copyTpl: jest.fn() -// } as unknown as Editor; - -// log = { -// error: jest.fn() -// } as unknown as Logger; -// }); - -// test('should log an error when writing to tsconfig.json fails', async () => { -// const mockError = new Error('Write error'); - -// (fs.writeJSON as jest.Mock).mockImplementation(() => { -// throw mockError; -// }); -// const basePath = join('some/path'); -// fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); - -// expect(log.error).toHaveBeenCalled(); -// expect(log.error).toHaveBeenCalledWith( -// t('error.errorWritingTsConfig', { -// error: mockError -// }) -// ); -// }); - -// test('should log an error when copying templates', async () => { -// const mockError = new Error('copy template error'); - -// (fs.copyTpl as jest.Mock).mockImplementation(() => { -// throw mockError; -// }); - -// const basePath = join('some/path'); -// fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); - -// expect(log.error).toHaveBeenCalled(); -// expect(log.error).toHaveBeenCalledWith( -// t('error.errorCopyingFreestyleTestTemplates', { -// error: mockError -// }) -// ); -// }); -// }); +describe('writeOPATsconfigJsonUpdates', () => { + let fs: Editor; + let log: Logger; + + const opaConfig = { + appId: 'test-app-typescript', + applicationTitle: 'App test', + applicationDescription: 'App description', + enableTypeScript: true, + viewName: 'view-test', + ui5Version: '1.71.0' + }; + + beforeEach(() => { + fs = { + readJSON: jest.fn(), + writeJSON: jest.fn(), + copyTpl: jest.fn() + } as unknown as Editor; + + log = { + error: jest.fn() + } as unknown as Logger; + }); + + test('should log an error when writing to tsconfig.json fails', async () => { + const mockError = new Error('Write error'); + + (fs.writeJSON as jest.Mock).mockImplementation(() => { + throw mockError; + }); + const basePath = join('some/path'); + fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); + + expect(log.error).toHaveBeenCalled(); + expect(log.error).toHaveBeenCalledWith( + t('error.errorWritingTsConfig', { + error: mockError + }) + ); + }); + + test('should log an error when copying templates', async () => { + const mockError = new Error('copy template error'); + + (fs.copyTpl as jest.Mock).mockImplementation(() => { + throw mockError; + }); + + const basePath = join('some/path'); + fs = await generateFreestyleOPAFiles(basePath, opaConfig, fs, log); + + expect(log.error).toHaveBeenCalled(); + expect(log.error).toHaveBeenCalledWith( + t('error.errorCopyingFreestyleTestTemplates', { + error: mockError + }) + ); + }); +}); From f8142764ea800200da66a11ce2c26667eb3810e3 Mon Sep 17 00:00:00 2001 From: I743583 Date: Fri, 21 Feb 2025 17:10:21 +0000 Subject: [PATCH 42/42] add tests to fiori freestyle --- .../test/__snapshots__/basic.test.ts.snap | 560 ++++++++++++++++-- .../fiori-freestyle-writer/test/basic.test.ts | 6 +- 2 files changed, 516 insertions(+), 50 deletions(-) diff --git a/packages/fiori-freestyle-writer/test/__snapshots__/basic.test.ts.snap b/packages/fiori-freestyle-writer/test/__snapshots__/basic.test.ts.snap index 1253cad1c8..6c6f6d8c4e 100644 --- a/packages/fiori-freestyle-writer/test/__snapshots__/basic.test.ts.snap +++ b/packages/fiori-freestyle-writer/test/__snapshots__/basic.test.ts.snap @@ -2181,7 +2181,9 @@ archive.zip \\"deploy-config\\": \\"fiori add deploy-config\\", \\"start-noflp\\": \\"fiori run --open \\\\\\"index.html?sap-ui-xx-viewCache=false\\\\\\"\\", \\"start-mock\\": \\"fiori run --config ./ui5-mock.yaml --open \\\\\\"test/flpSandbox.html?sap-ui-xx-viewCache=false#nods1-tile\\\\\\"\\", - \\"start-variants-management\\": \\"fiori run --open \\\\\\"preview.html?sap-ui-xx-viewCache=false&fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true#preview-app\\\\\\"\\" + \\"int-test\\": \\"fiori run --config ./ui5-mock.yaml --open 'test/integration/opaTests.qunit.html'\\", + \\"start-variants-management\\": \\"fiori run --open \\\\\\"preview.html?sap-ui-xx-viewCache=false&fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true#preview-app\\\\\\"\\", + \\"unit-test\\": \\"fiori run --config ./ui5-mock.yaml --open 'test/unit/unitTests.qunit.html'\\" } } ", @@ -2189,31 +2191,38 @@ archive.zip }, "tsconfig.json": Object { "contents": "{ - \\"compilerOptions\\": { - \\"target\\": \\"es2022\\", - \\"module\\": \\"es2022\\", - \\"skipLibCheck\\": true, - \\"allowJs\\": true, - \\"strict\\": true, - \\"strictPropertyInitialization\\": false, - \\"moduleResolution\\": \\"node\\", - \\"rootDir\\": \\"./webapp\\", - \\"outDir\\": \\"./dist\\", - \\"baseUrl\\": \\"./\\", - \\"paths\\": { - \\"nods1/*\\": [ - \\"./webapp/*\\" - ] - }, - \\"typeRoots\\": [ - \\"./node_modules/@types\\", - \\"./node_modules/@sapui5/ts-types-esm\\" - ] + \\"compilerOptions\\": { + \\"target\\": \\"es2022\\", + \\"module\\": \\"es2022\\", + \\"skipLibCheck\\": true, + \\"allowJs\\": true, + \\"strict\\": true, + \\"strictPropertyInitialization\\": false, + \\"moduleResolution\\": \\"node\\", + \\"rootDir\\": \\"./webapp\\", + \\"outDir\\": \\"./dist\\", + \\"baseUrl\\": \\"./\\", + \\"paths\\": { + \\"nods1/*\\": [ + \\"./webapp/*\\" + ], + \\"unit/*\\": [ + \\"./webapp/test/unit/*\\" + ], + \\"integration/*\\": [ + \\"./webapp/test/integration/*\\" + ] }, - \\"include\\": [ - \\"./webapp/**/*\\" + \\"typeRoots\\": [ + \\"./node_modules/@types\\", + \\"./node_modules/@sapui5/ts-types-esm\\" ] -}", + }, + \\"include\\": [ + \\"./webapp/**/*\\" + ] +} +", "state": "modified", }, "ui5-local.yaml": Object { @@ -2741,6 +2750,229 @@ export function createDeviceModel () { ", "state": "modified", }, + "webapp/test/integration/NavigationJourney.ts": Object { + "contents": "/*global QUnit*/ +import opaTest from \\"sap/ui/test/opaQunit\\"; +import AppPage from \\"./pages/AppPage\\"; +import ViewPage from \\"./pages/View1Page\\"; + +import Opa5 from \\"sap/ui/test/Opa5\\"; + +QUnit.module(\\"Navigation Journey\\"); + +const onTheAppPage = new AppPage(); +const onTheViewPage = new ViewPage(); +Opa5.extendConfig({ + viewNamespace: \\"nods1.view.\\", + autoWait: true +}); + +opaTest(\\"Should see the initial page of the app\\", function () { + // Arrangements + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iStartMyUIComponent({ + componentConfig: { + name: \\"nods1\\" + } + }); + + // Assertions + onTheAppPage.iShouldSeeTheApp(); + onTheViewPage.iShouldSeeThePageView(); + + + // Cleanup + // eslint-disable-next-line @typescript-eslint/no-floating-promises + onTheAppPage.iTeardownMyApp(); +});", + "state": "modified", + }, + "webapp/test/integration/opaTests.qunit.html": Object { + "contents": " + + + + Integration tests for Basic Template + + + + + + + +
+
+ + +", + "state": "modified", + }, + "webapp/test/integration/opaTests.qunit.ts": Object { + "contents": "/* global QUnit */ +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +// import all your OPA journeys here +void Promise.all([ + import(\\"integration/NavigationJourney\\") +]).then(() => { + QUnit.start(); +});", + "state": "modified", + }, + "webapp/test/integration/pages/AppPage.ts": Object { + "contents": "import Opa5 from \\"sap/ui/test/Opa5\\"; + +const sViewName = \\"App\\"; + +export default class AppPage extends Opa5 { + // Actions + + + // Assertions + iShouldSeeTheApp() { + return this.waitFor({ + id: \\"app\\", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, \\"The \\" + sViewName + \\" view is displayed\\"); + }, + errorMessage: \\"Did not find the \\" + sViewName + \\" view\\" + }); + } + +} + +", + "state": "modified", + }, + "webapp/test/integration/pages/View1Page.ts": Object { + "contents": "import Opa5 from \\"sap/ui/test/Opa5\\"; + +const sViewName = \\"View1\\"; + +export default class View1Page extends Opa5 { + // Actions + + + // Assertions + iShouldSeeThePageView() { + return this.waitFor({ + id: \\"page\\", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, \\"The \\" + sViewName + \\" view is displayed\\"); + }, + errorMessage: \\"Did not find the \\" + sViewName + \\" view\\" + }); + } + +} + + +", + "state": "modified", + }, + "webapp/test/testsuite.qunit.html": Object { + "contents": " + + + QUnit test suite + + + + +", + "state": "modified", + }, + "webapp/test/testsuite.qunit.ts": Object { + "contents": "/* global window, parent, location */ + +// eslint-disable-next-line fiori-custom/sap-no-global-define,@typescript-eslint/ban-ts-comment +// @ts-nocheck +window.suite = function() { + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + \\"unit/unitTests.qunit.html\\"); + oSuite.addTestPage(sContextPath + \\"integration/opaTests.qunit.html\\"); + + return oSuite; +}; +", + "state": "modified", + }, + "webapp/test/unit/controller/View1Page.controller.ts": Object { + "contents": "/*global QUnit*/ +import Controller from \\"nods1/controller/View1.controller\\"; + +QUnit.module(\\"View1 Controller\\"); + +QUnit.test(\\"I should test the View1 controller\\", function (assert: Assert) { + const oAppController = new Controller(\\"View1\\"); + oAppController.onInit(); + assert.ok(oAppController); +});", + "state": "modified", + }, + "webapp/test/unit/unitTests.qunit.html": Object { + "contents": " + + + + Unit tests for nods1 + + + + + + + + + +
+
+ + +", + "state": "modified", + }, + "webapp/test/unit/unitTests.qunit.ts": Object { + "contents": "/* global QUnit */ +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +// import all your QUnit tests here +void Promise.all([ +import(\\"unit/controller/View1Page.controller\\") +]).then(() => { + QUnit.start(); +});", + "state": "modified", + }, "webapp/view/App.view.xml": Object { "contents": " + + + + Integration tests for Basic Template + + + + + + + +
+
+ + +", + "state": "modified", + }, + "webapp/test/integration/opaTests.qunit.ts": Object { + "contents": "/* global QUnit */ +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +// import all your OPA journeys here +void Promise.all([ + import(\\"integration/NavigationJourney\\") +]).then(() => { + QUnit.start(); +});", + "state": "modified", + }, + "webapp/test/integration/pages/AppPage.ts": Object { + "contents": "import Opa5 from \\"sap/ui/test/Opa5\\"; + +const sViewName = \\"App\\"; + +export default class AppPage extends Opa5 { + // Actions + + + // Assertions + iShouldSeeTheApp() { + return this.waitFor({ + id: \\"app\\", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, \\"The \\" + sViewName + \\" view is displayed\\"); + }, + errorMessage: \\"Did not find the \\" + sViewName + \\" view\\" + }); + } + +} + +", + "state": "modified", + }, + "webapp/test/integration/pages/View1Page.ts": Object { + "contents": "import Opa5 from \\"sap/ui/test/Opa5\\"; + +const sViewName = \\"View1\\"; + +export default class View1Page extends Opa5 { + // Actions + + + // Assertions + iShouldSeeThePageView() { + return this.waitFor({ + id: \\"page\\", + viewName: sViewName, + success: function () { + Opa5.assert.ok(true, \\"The \\" + sViewName + \\" view is displayed\\"); + }, + errorMessage: \\"Did not find the \\" + sViewName + \\" view\\" + }); + } + +} + + +", + "state": "modified", + }, + "webapp/test/testsuite.qunit.html": Object { + "contents": " + + + QUnit test suite + + + + +", + "state": "modified", + }, + "webapp/test/testsuite.qunit.ts": Object { + "contents": "/* global window, parent, location */ + +// eslint-disable-next-line fiori-custom/sap-no-global-define,@typescript-eslint/ban-ts-comment +// @ts-nocheck +window.suite = function() { + // eslint-disable-next-line + var oSuite = new parent.jsUnitTestSuite(), + sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf(\\"/\\") + 1); + + oSuite.addTestPage(sContextPath + \\"unit/unitTests.qunit.html\\"); + oSuite.addTestPage(sContextPath + \\"integration/opaTests.qunit.html\\"); + + return oSuite; +}; +", + "state": "modified", + }, + "webapp/test/unit/controller/View1Page.controller.ts": Object { + "contents": "/*global QUnit*/ +import Controller from \\"nods1/controller/View1.controller\\"; + +QUnit.module(\\"View1 Controller\\"); + +QUnit.test(\\"I should test the View1 controller\\", function (assert: Assert) { + const oAppController = new Controller(\\"View1\\"); + oAppController.onInit(); + assert.ok(oAppController); +});", + "state": "modified", + }, + "webapp/test/unit/unitTests.qunit.html": Object { + "contents": " + + + + Unit tests for nods1 + + + + + + + + + +
+
+ + +", + "state": "modified", + }, + "webapp/test/unit/unitTests.qunit.ts": Object { + "contents": "/* global QUnit */ +// https://api.qunitjs.com/config/autostart/ +QUnit.config.autostart = false; + +// import all your QUnit tests here +void Promise.all([ +import(\\"unit/controller/View1Page.controller\\") +]).then(() => { + QUnit.start(); +});", + "state": "modified", + }, "webapp/view/App.view.xml": Object { "contents": " { ...commonConfig, appOptions: { loadReuseLibs: false, - typescript: true + typescript: true, + addTests: true } }, settings: {} @@ -127,7 +128,8 @@ describe(`Fiori freestyle template: ${TEST_NAME}`, () => { ...commonConfig, appOptions: { loadReuseLibs: false, - typescript: true + typescript: true, + addTests: true }, ui5: { version: '1.108.1',