diff --git a/README.md b/README.md index 50bed960..a48e9384 100644 --- a/README.md +++ b/README.md @@ -13,23 +13,25 @@ It has the following features - ## Table of Contents -- [Brief overview](#brief-overview) -- [Setup](#setup) - - [FCA URL deployed and available in the S3](#fca-url-deployed-and-available-in-the-s3) - - [Below are the steps to run FCA in local system](#below-are-the-steps-to-run-fca-in-local-system) -- [Supported ways of Execution](#supported-ways-of-execution) -- [Sanity Suite Flow](./docs/index.md) -- [Supported targets](#supported-targets) -- [Supported Modes of execution](#supported-modes-of-execution) -- [Supported validations](#supported-validations) -- [Supported ways of retrieving reports](#supported-ways-of-retrieving-reports) -- [Supported Report Parameters](#supported-report-parameters) -- [PR and merge process](#pr-and-merge-process) -- [Supported URL parameters](#supported-url-parameters) -- [Supported PubSub Handlers](#supported-pubsub-handlers) -- [Plugins](#plugins) -- [Connect to mock Firebolt OS](#connect-to-mock-firebolt-os) - - [Timeout in UI prompt](#timeout-in-ui-prompt) +- [firebolt-certification-app](#firebolt-certification-app) + - [Brief overview](#brief-overview) + - [Table of Contents](#table-of-contents) + - [Setup](#setup) + - [FCA URL deployed and available in the S3](#fca-url-deployed-and-available-in-the-s3) + - [Below are the steps to run FCA in local system](#below-are-the-steps-to-run-fca-in-local-system) + - [Supported ways of Execution](#supported-ways-of-execution) + - [Supported targets](#supported-targets) + - [Supported Modes of execution](#supported-modes-of-execution) + - [Supported validations](#supported-validations) + - [Supported ways of retrieving reports](#supported-ways-of-retrieving-reports) + - [Supported Report Parameters](#supported-report-parameters) + - [PR and merge process](#pr-and-merge-process) + - [Supported URL parameters](#supported-url-parameters) + - [Supported Intent Parameters](#supported-intent-parameters) + - [Supported PubSub Handlers](#supported-pubsub-handlers) + - [Plugins](#plugins) + - [Connect to mock Firebolt OS](#connect-to-mock-firebolt-os) + - [Timeout in UI prompt](#timeout-in-ui-prompt) ## Setup @@ -113,6 +115,32 @@ Mode of execution implies the way in which an API is invoked. There are 2 modes - If FCA systemui=true, FCA acts as the base app in case of ripple. The background color will be changed to purple and it will display one more button as "Launch FCA app" to launch FCA as third-party app on Ripple devices. - TestContext: testContext=true - If testContext=true, it will add the field context in mocha report generated +- AppId: appId=`` + - `appId` used to launch the app. +- Mac Address: macAddress=`` + - `macAddress` of the device running the tests. +- appType: appType=`` + - `appType` is the type of app being launched. +- Pub Sub Subscribe suffix : pubSubSubscribeSuffix=`` + - `pubSubSubscribeSuffix` is the subscribe suffix value used for Pub Sub communication. +- Pub Sub Publish suffix : pubSubPublishSuffix=`` + - `pubSubPublishSuffix` is the publish suffix value used for Pub Sub communication. + +## Supported Intent Parameters +- appType: + - Classifier for the app - Launch the certification app for certification validations. Launching a firebolt app for app certification. +- appId: + - When `appId` is specified in the intent, it will be used to launch the app. +- macAddress: + - When `macAddress` is specified in the intent, it indicates the mac address of the device running the tests. +- PubSub Publish Suffix: + - When `pubSubPublishSuffix` is specified in the intent, it publishes to the topic. +- PubSub Subscribe Suffix: + - When `pubSubSubscribeSuffix` is specified in the intent, it subscribes to the topic. +- pubSubUrl: + - Sets the the url to use for a PubSub server. +- registerprovider: + - When `registerProvider = false`, then certification app will not register for userInterest provider. ## Supported PubSub Handlers @@ -152,4 +180,4 @@ To activate Mock Firebolt, there are specific start-up scripts that exist inside For pinChallenge and acknowledgeChallenge UI prompts , a timeout of 15s is added so that, if no action is taken when the prompts displays on the screen (i.e; neither yes/no/back button ), the prompts will be automatically dismissed with "null" value as the response. The prompt is displayed when the user needs to grant/deny a particular api, or the user has to enter a pin in-case of pinChallenge. -If user wants to grant an api, yes button is pressed, for deniel - no button, and incase if the user wants to dismiss the prompt without any action, back button is pressed. \ No newline at end of file +If user wants to grant an api, yes button is pressed, for deniel - no button, and incase if the user wants to dismiss the prompt without any action, back button is pressed. diff --git a/src/App.js b/src/App.js index c0f5ba24..22b1ec38 100644 --- a/src/App.js +++ b/src/App.js @@ -103,7 +103,6 @@ export default class App extends Base { const standalone = new URLSearchParams(appUrl.search).get('standalone'); const standalonePrefix = new URLSearchParams(appUrl.search).get('standalonePrefix'); this.systemui = new URLSearchParams(window.location.search).get('systemui'); - this.testToken = new URLSearchParams(window.location.search).get('testtoken'); this.pubSubUuidPresent = false; this.appContinue = false; process.env.LIFECYCLE_VALIDATION = lifecycle; @@ -111,7 +110,6 @@ export default class App extends Base { process.env.MF_VALUE = false; testContext ? (process.env.TESTCONTEXT = JSON.parse(testContext)) : (process.env.TESTCONTEXT = false); process.env.TESTCONTEXT = true; // Making TESTCONTEXT = true by default. This line will be removed in later stages when required - process.env.TEST_TOKEN = this.testToken; process.env.REPORTINGID = reportingId; process.env.STANDALONE = standalone; process.env.STANDALONE_PREFIX = standalonePrefix; @@ -120,7 +118,14 @@ export default class App extends Base { process.env.SDKS_AVAILABLE = [...CONSTANTS.defaultSDKs, ...CONSTANTS.additionalSDKs]; // Set the pubSub URL if present - process.env.PUB_SUB_URL = new URLSearchParams(window.location.search).get('pubSubUrl'); + process.env.PUB_SUB_URL = new URLSearchParams(appUrl.search).get('pubSubUrl'); + process.env.PUB_SUB_TOKEN = new URLSearchParams(appUrl.search).get('pubSubToken'); + process.env.MACADDRESS = new URLSearchParams(appUrl.search).get('macaddress'); + process.env.CURRENT_APPID = new URLSearchParams(appUrl.search).get('appId'); + process.env.APP_TYPE = new URLSearchParams(appUrl.search).get('appType'); + process.env.PUBSUB_SUBSCRIBE_TOPIC_SUFFIX = new URLSearchParams(appUrl.search).get('pubSubSubscribeSuffix'); + process.env.PUBSUB_PUBLISH_TOPIC_SUFFIX = new URLSearchParams(appUrl.search).get('pubSubPublishSuffix'); + process.env.REGION = new URLSearchParams(appUrl.search).get('region'); if (platform) { process.env.PLATFORM = platform; @@ -159,7 +164,6 @@ export default class App extends Base { this.pubSubListener(); } getCurrentAppID().then((res) => { - process.env.APPID = res; this._setState('LoadingState'); }); } @@ -391,7 +395,13 @@ export default class App extends Base { if (lifecycle_validationString == true) { process.env.LIFECYCLE_VALIDATION = 'true'; } + if (query.params.pubSubPublishSuffix) { + process.env.PUBSUB_PUBLISH_TOPIC_SUFFIX = query.params.pubSubPublishSuffix; + } + if (query.params.pubSubSubscribeSuffix) { + process.env.PUBSUB_SUBSCRIBE_TOPIC_SUFFIX = query.params.pubSubSubscribeSuffix; + } process.env.APP_TYPE = query.params.appType ? query.params.appType.toLowerCase() : CONSTANTS.FIREBOLT_CONST; try { @@ -407,12 +417,6 @@ export default class App extends Base { console.log('Error getting App Id :: ', err); } - if (query.params.testtoken) { - process.env.TEST_TOKEN = query.params.testtoken; - } else { - logger.error('No Test Token Found in Parameter Initialization response...', 'getParameterInitializationValues'); - } - if (query.params.macaddress) { process.env.MACADDRESS = query.params.macaddress; } else { @@ -427,7 +431,14 @@ export default class App extends Base { if (query.params.pubSubUrl) { process.env.PUB_SUB_URL = query.params.pubSubUrl; } - + // Set the pubSub token if present + if (query.params.pubSubToken) { + process.env.PUB_SUB_TOKEN = query.params.pubSubToken; + } + // Set the region if present + if (query.params.region) { + process.env.REGION = query.params.region; + } if (query.task) { setTimeout(() => { const intentReader = new IntentReader(); diff --git a/src/FireboltTransportInvoker.js b/src/FireboltTransportInvoker.js index 9501fd7d..3001200d 100644 --- a/src/FireboltTransportInvoker.js +++ b/src/FireboltTransportInvoker.js @@ -17,6 +17,15 @@ */ import Transport from '@firebolt-js/sdk/dist/lib/Transport'; +import { CONSTANTS } from './constant'; + +let invokeManager, invokeProvider; +try { + invokeManager = require('../plugins/FireboltExtensionInvoker').default.invokeManager; + invokeProvider = require('../plugins/FireboltExtensionInvoker').default.invokeProvider; +} catch (err) { + logger.error(`Unable to import additional invoker - ${err.message}`); +} let instance = null; @@ -32,7 +41,7 @@ export default class FireboltTransportInvoker { return instance; } - async invoke(methodName, params, paramNamesArray) { + async invoke(methodName, params, paramNamesArray, invoker = null) { const module = methodName.split('.')[0]; const method = methodName.split('.')[1]; if (paramNamesArray) { @@ -42,7 +51,13 @@ export default class FireboltTransportInvoker { // For each param, construct json using param name and value jsonParams[paramNamesArray[i]] = params[i]; } - return await Transport.send(module, method, jsonParams); + if (invoker == CONSTANTS.INVOKEPROVIDER) { + return await invokeProvider.send(module, method, jsonParams); + } else if (invoker == CONSTANTS.INVOKEMANAGER) { + return await invokeManager.send(module, method, jsonParams); + } else { + return await Transport.send(module, method, jsonParams); + } } else { throw Error('Could not find params for ' + methodName); } diff --git a/src/LifeCycleHistory.js b/src/LifeCycleHistory.js index c16d1dbd..dfc4ae85 100644 --- a/src/LifeCycleHistory.js +++ b/src/LifeCycleHistory.js @@ -108,13 +108,13 @@ export default class LifecycleHistory { const query = JSON.parse(event.data.query); // Establishing a pubSub connection if FCA receives an intent in the navigateTo event with the following parameters. - if (query.params && query.params.appId && query.params.testtoken && query.params.macaddress) { + if (query.params && query.params.appId && query.params.macaddress) { // PUBSUB_CONNECTION environment variable has a pubsub client instance and calls the isConnected function to check the Websocket status. if (!process.env.PUBSUB_CONNECTION || (process.env.PUBSUB_CONNECTION && !process.env.PUBSUB_CONNECTION.isConnected())) { process.env.APP_TYPE = query.params.appType ? query.params.appType.toLowerCase() : CONSTANTS.FIREBOLT_CONST; process.env.CURRENT_APPID = query.params.appId; process.env.MACADDRESS = query.params.macaddress; - process.env.TEST_TOKEN = query.params.testtoken; + process.env.PUB_SUB_TOKEN = query.params.pubSubToken; const pubSubListenerCreation = new PubSubCommunication(); const webSocketConnection = await pubSubListenerCreation.startWebSocket(); } diff --git a/src/MenuBuilder.js b/src/MenuBuilder.js index c17fcf31..a650bb44 100644 --- a/src/MenuBuilder.js +++ b/src/MenuBuilder.js @@ -177,7 +177,7 @@ export default class MenuBuilder { function (sdkObject) { const sdkObjectCopy = { ...sdkObject }; // dynamically construct menu items using additionalSDKs config - const menuObject = this.createSubMenuObject(sdkObjectCopy.name, ValidationView, sdkObjectCopy.name, CONSTANTS.SDK); + const menuObject = this.createSubMenuObject(sdkObjectCopy.name, ValidationView, sdkObjectCopy.name, CONSTANTS.TRANSPORT); transportMenuArray.push(menuObject); }.bind(this) ); diff --git a/src/MethodFilters.js b/src/MethodFilters.js index af715890..696a64bb 100644 --- a/src/MethodFilters.js +++ b/src/MethodFilters.js @@ -38,7 +38,10 @@ export default class MethodFilters { isRpcMethod(method, invokedSdk, communicationMode = 'sdk') { let isRpc = false; - if ((invokedSdk == CONSTANTS.CORE.toLowerCase() || invokedSdk == CONSTANTS.MANAGE.toLowerCase()) && communicationMode == CONSTANTS.TRANSPORT) { + + const mergedSDKs = CONSTANTS.defaultSDKs.concat(CONSTANTS.additionalSDKs); + const sdkNames = mergedSDKs.map((sdkObjectCopy) => sdkObjectCopy.name.toLowerCase()); + if (sdkNames.includes(invokedSdk.toLowerCase()) && communicationMode == CONSTANTS.TRANSPORT) { return isRpc; } else if (invokedSdk == CONSTANTS.MANAGE.toLowerCase() && method.name.split('.')[1].startsWith('set')) { return isRpc; diff --git a/src/constant.js b/src/constant.js index dbc62c97..396cd0ee 100644 --- a/src/constant.js +++ b/src/constant.js @@ -141,6 +141,8 @@ export const CONSTANTS = { EXCLUDED_METHODS_FOR_SDK: [], EXCLUDED_METHODS_FOR_TRANSPORT: [], REGISTERPROVIDER: 'registerprovider', + INVOKEPROVIDER: 'invokeProvider', + INVOKEMANAGER: 'invokeManager', defaultSDKs: [ { name: 'Core', diff --git a/src/pubSubClient.js b/src/pubSubClient.js index 1a65c668..c5dd2469 100644 --- a/src/pubSubClient.js +++ b/src/pubSubClient.js @@ -22,8 +22,8 @@ class PubSubClient { constructor() { this.ws = null; this.url = process.env.PUB_SUB_URL ? process.env.PUB_SUB_URL : 'ws://localhost:8080'; - this.PUBSUB_SUBSCRIBE_TOPIC_SUFFIX = '_FCS'; - this.PUBSUB_PUBLISH_TOPIC_SUFFIX = '_FCA'; + this.PUBSUB_SUBSCRIBE_TOPIC_SUFFIX = process.env.PUBSUB_SUBSCRIBE_TOPIC_SUFFIX ? process.env.PUBSUB_SUBSCRIBE_TOPIC_SUFFIX : '_FCS'; + this.PUBSUB_PUBLISH_TOPIC_SUFFIX = process.env.PUBSUB_PUBLISH_TOPIC_SUFFIX ? process.env.PUBSUB_PUBLISH_TOPIC_SUFFIX : '_FCA'; } // Initializes a WS connection diff --git a/src/pubsub/handlers/clearEventHandler.js b/src/pubsub/handlers/clearEventHandler.js index 5788890f..94082477 100644 --- a/src/pubsub/handlers/clearEventHandler.js +++ b/src/pubsub/handlers/clearEventHandler.js @@ -29,6 +29,14 @@ export default class clearEventHandler extends BaseHandler { async handle(message) { const eventInvokerInfo = new EventInvocation(); + let sdkType; + if (message.params && message.params.event && message.params.event.includes('_')) { + sdkType = message.params.event.split('_')[0].toLowerCase(); + } + if (message.action != null && message.action != 'NA') { + sdkType = message.action; + process.env.SDK_TYPE = sdkType; + } try { const validationReport = eventInvokerInfo.clearEventListeners(message.params.event); return JSON.stringify({ report: validationReport }); diff --git a/src/utils/Utils.js b/src/utils/Utils.js index 4ac82dca..055f5ebe 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -327,7 +327,7 @@ function removeSetInMethodName(apiName) { * @description get the current appid with Advertising.appBundleId */ async function getCurrentAppID() { - if (!process.env.CURRENT_APPID || !process.env.APPID) { + if (!process.env.CURRENT_APPID) { try { let res = await FireboltExampleInvoker.get().invoke(CONSTANTS.CORE.toLowerCase(), 'Advertising.appBundleId', []); const lastIndex = res.lastIndexOf('.'); @@ -396,7 +396,7 @@ async function overrideParamsFromTestData(methodObj) { try { const paramsJson = testDataHandler('overrideParams'); if (paramsJson && typeof paramsJson == 'object' && Object.keys(paramsJson).length) { - const appID = process.env.APPID; + const appID = process.env.CURRENT_APPID; // Checking if any data present for the passed appId const parsedMethod = paramsJson[appID]; // Fetching the examples from the parsedMethod