diff --git a/gpii/configs/all.development.dr.production.json b/gpii/configs/all.development.dr.production.json new file mode 100644 index 000000000..7e1b6dc2f --- /dev/null +++ b/gpii/configs/all.development.dr.production.json @@ -0,0 +1,23 @@ +{ + "typeName": "all.development.dr.production", + "options": { + "gradeNames": ["autoInit", "fluid.littleComponent"], + "components": { + "server": { + "type": "kettle.server", + "options": { + "logging": true, + "port": 8081 + } + } + } + }, + "includes": [ + "../node_modules/deviceReporter/configs/production.json", + "../node_modules/flowManager/configs/development.json", + "../node_modules/preferencesServer/configs/development.json", + "../node_modules/solutionsRegistry/configs/development.json", + "../node_modules/flatMatchMaker/configs/development.all.local.json", + "../node_modules/rawPreferencesServer/configs/development.json" + ] +} diff --git a/gpii/configs/all.development.dr.production.txt b/gpii/configs/all.development.dr.production.txt new file mode 100644 index 000000000..a3c60c871 --- /dev/null +++ b/gpii/configs/all.development.dr.production.txt @@ -0,0 +1,22 @@ +all.development.dr.production.json +================================== + +This configuration runs the entire system locally and in development mode with the exception of the deviceReporter, +which runs in production mode. + +This mean that: +* All storage is on the local filesystem (as opposed to couchDB servers/remote URLs) +* The following components are running on the local machine: +** flowManager +** preferencesServer +** OntologyHandler +** rawPreferencesServer (reading preferences from file) +** solutionsRegistry (reading registry from file) +** deviceReporter (using a dynamic device reporter) +** matchMakerFramework +** flatMatchMaker +** lifecycleManager + +Notes on testing: +This setup is used as a basis for the platform specific acceptance tests that make use of a dynamic device reporter. +Since the acceptance tests might use slightly different paths for the tests (ie. a special folder for reading prefs and solutionsRegistry), what is actually being used for testing is a slight variation of this config. For more details, see the txt files describing the configs in the acceptance tests folder of both universal and the platform specific repositories. diff --git a/gpii/node_modules/deviceReporter/configs/development.json b/gpii/node_modules/deviceReporter/configs/development.json index 46144eea0..60ee26bbc 100644 --- a/gpii/node_modules/deviceReporter/configs/development.json +++ b/gpii/node_modules/deviceReporter/configs/development.json @@ -9,7 +9,7 @@ "logging": true, "components": { "deviceReporter": { - "type": "gpii.deviceReporter", + "type": "gpii.deviceReporter.static", "options": { "gradeNames": ["gpii.deviceReporter.dev"], "installedSolutionsUrl": "file://%root/../../../testData/deviceReporter/installedSolutions.json" diff --git a/gpii/node_modules/deviceReporter/configs/kettleModuleLoader.js b/gpii/node_modules/deviceReporter/configs/kettleModuleLoader.js index 5b35545a7..3c9b28d48 100644 --- a/gpii/node_modules/deviceReporter/configs/kettleModuleLoader.js +++ b/gpii/node_modules/deviceReporter/configs/kettleModuleLoader.js @@ -17,4 +17,4 @@ // The purpose of this file is to be copied to a location for which the // require function is needed. It allows to find node modules relative // to that location that are otherwise non-resolvable. -module.exports = require; \ No newline at end of file +module.exports = require; diff --git a/gpii/node_modules/deviceReporter/configs/production.json b/gpii/node_modules/deviceReporter/configs/production.json index ffc3ac22c..479e77f77 100644 --- a/gpii/node_modules/deviceReporter/configs/production.json +++ b/gpii/node_modules/deviceReporter/configs/production.json @@ -9,10 +9,9 @@ "logging": false, "components": { "deviceReporter": { - "type": "gpii.deviceReporter", + "type": "gpii.deviceReporter.live", "options": { - "gradeNames": ["gpii.deviceReporter.dev"], - "installedSolutionsUrl": "file://%root/../../../testData/deviceReporter/installedSolutions.json" + "gradeNames": ["gpii.deviceReporter.dev"] } } } diff --git a/gpii/node_modules/deviceReporter/index.js b/gpii/node_modules/deviceReporter/index.js index b2daafab2..80cb181e2 100644 --- a/gpii/node_modules/deviceReporter/index.js +++ b/gpii/node_modules/deviceReporter/index.js @@ -2,4 +2,4 @@ var fluid = require("infusion"); var loader = fluid.getLoader(__dirname); -loader.require("./src/DeviceReporter.js"); \ No newline at end of file +loader.require("./src/DeviceReporter.js"); diff --git a/gpii/node_modules/deviceReporter/src/DeviceGet.js b/gpii/node_modules/deviceReporter/src/DeviceGet.js index af59f6278..bbe7f1a5c 100644 --- a/gpii/node_modules/deviceReporter/src/DeviceGet.js +++ b/gpii/node_modules/deviceReporter/src/DeviceGet.js @@ -18,26 +18,18 @@ "use strict"; - var fluid = require("infusion"), - gpii = fluid.registerNamespace("gpii"); + var fluid = require("infusion"); fluid.defaults("kettle.requests.request.handler.deviceGet", { gradeNames: ["fluid.littleComponent", "autoInit"], invokers: { handle: { - funcName: "gpii.handleDeviceGet", - args: ["{requestProxy}", "{deviceReporter}.installedSolutionsDataSource", "{deviceReporter}.platformReporter"] + func: "{deviceReporter}.get", + args: [ + "{requestProxy}" + ] } } }); - gpii.handleDeviceGet = function (requestProxy, installedSolutionsDataSource, platformReporter) { - installedSolutionsDataSource.get(null, function onSuccess(solutions) { - requestProxy.events.onSuccess.fire({ - solutions: solutions, - OS: platformReporter.reportPlatform() - }); - }); - }; - })(); diff --git a/gpii/node_modules/deviceReporter/src/DeviceReporter.js b/gpii/node_modules/deviceReporter/src/DeviceReporter.js index 77101be55..e73fc6b4e 100644 --- a/gpii/node_modules/deviceReporter/src/DeviceReporter.js +++ b/gpii/node_modules/deviceReporter/src/DeviceReporter.js @@ -24,7 +24,7 @@ var fluid = require("infusion"), fluid.require("kettle", require); fluid.require("./DeviceGet.js", require); -fluid.defaults("gpii.deviceReporter", { +fluid.defaults("gpii.deviceReporter.base", { gradeNames: ["kettle.app", "autoInit"], handlers: { deviceGet: { @@ -32,21 +32,94 @@ fluid.defaults("gpii.deviceReporter", { type: "get" } }, + components: { + platformReporter: { + type: "gpii.platformReporter.native" + }, + nameResolver: { + type: "gpii.deviceReporter.nameResolver" + } + }, + invokers: { + fireResponse: { + funcName: "gpii.deviceReporter.fireResponse", + args: ["{arguments}.0", "{arguments}.1", "{platformReporter}"] + } + } +}); + +fluid.defaults("gpii.deviceReporter.nameResolver", { + gradeNames: ["fluid.littleComponent", "autoInit"], + invokers: { + resolveName: { + funcName: "fluid.identity" + } + } +}); + +gpii.deviceReporter.fireResponse = function (requestProxy, installedSolutions, platformReporter) { + requestProxy.events.onSuccess.fire({ + solutions: installedSolutions, + OS: platformReporter.reportPlatform() + }); +}; + +fluid.defaults("gpii.deviceReporter.static", { + gradeNames: ["autoInit", "gpii.deviceReporter.base"], installedSolutionsUrl: "", root: path.join(__dirname, ".."), components: { installedSolutionsDataSource: { type: "kettle.dataSource.URL", options: { - url: "{gpii.deviceReporter}.options.installedSolutionsUrl" + url: "{gpii.deviceReporter.static}.options.installedSolutionsUrl" } - }, - platformReporter: { - type: "gpii.platformReporter.native" + } + }, + invokers: { + get: { + funcName: "gpii.deviceReporter.static.get", + args: ["{arguments}.0", "{deviceReporter}"] } } }); +gpii.deviceReporter["static"].get = function (requestProxy, deviceReporter) { + deviceReporter.installedSolutionsDataSource.get(null, function onSuccess(solutions) { + deviceReporter.fireResponse(requestProxy, solutions); + }); +}; + +fluid.defaults("gpii.deviceReporter.live", { + gradeNames: ["autoInit", "gpii.deviceReporter.base"], + invokers: { + get: { + funcName: "gpii.deviceReporter.live.get", + args: ["{arguments}.0", "{deviceReporter}", "{flowManager}.solutionsRegistryDataSource"] + } + } +}); + +gpii.deviceReporter.live.get = function (requestProxy, deviceReporter, solutionsRegistryDataSource) { + var installedSolutions = []; + solutionsRegistryDataSource.get({os: deviceReporter.platformReporter.reportPlatform().id}, function onSuccess(entries) { + fluid.each(entries, function (entry, entryId) { + if (!installedSolutions.some(function (s) { return s.id === entryId; })) { + var foundEntryId = fluid.find(entry.contexts.isInstalled, function (installedSolutionsReporter) { + var resolvedName = deviceReporter.nameResolver.resolveName(installedSolutionsReporter.type, "deviceReporter"); + if (fluid.invokeGradedFunction(resolvedName, installedSolutionsReporter)) { + return entryId; + } + }, null); + if (foundEntryId !== null) { + installedSolutions.push({ "id": foundEntryId }); + } + } + }); + deviceReporter.fireResponse(requestProxy, installedSolutions); + }); +}; + fluid.defaults("gpii.platformReporter.native", { gradeNames: ["fluid.littleComponent", "autoInit"], invokers: { diff --git a/gpii/node_modules/testing/src/Integration.js b/gpii/node_modules/testing/src/Integration.js index 61b08cdae..fa06db2f2 100644 --- a/gpii/node_modules/testing/src/Integration.js +++ b/gpii/node_modules/testing/src/Integration.js @@ -47,6 +47,12 @@ fluid.defaults("gpii.test.integration.testCaseHolder", { func: "{gpii.test.integration.testCaseHolder}.nameResolver.resolveName" }, target: "{that lifecycleManager > nameResolver}.options.invokers.resolveName" + }, { + record: { + funcName: null, + func: "{gpii.test.integration.deviceReporterAware}.nameResolver.resolveName" + }, + target: "{that deviceReporter > nameResolver}.options.invokers.resolveName" }, { record: { funcName: null, @@ -61,13 +67,16 @@ fluid.defaults("gpii.test.integration.testCaseHolder", { mockSettingsHandlers: { type: "gpii.test.integration.mockSettingsHandlerRegistry.universal" }, + mockDeviceReporters: { + type: "gpii.test.integration.deviceReporterAware" + }, nameResolver: { type: "fluid.littleComponent", options: { invokers: { resolveName: { funcName: "gpii.test.integration.resolveName", - args: ["{mockSettingsHandlers}", "{arguments}.0", "{arguments}.1"] + args: ["{mockSettingsHandlers}", "{mockDeviceReporters}", "{arguments}.0", "{arguments}.1"] } } } @@ -154,9 +163,11 @@ fluid.defaults("gpii.test.integration.mockExecHandler", { } }); -gpii.test.integration.resolveName = function (settingsHandlerRegistry, name, category) { +gpii.test.integration.resolveName = function (settingsHandlerRegistry, deviceReporterAware, name, category) { if (category === "settingsHandler") { return settingsHandlerRegistry.resolveName(name); + } else if (category === "deviceReporter") { + return deviceReporterAware.resolveName(name); } else { return "gpii.test.integration.mockExecHandler"; } @@ -371,3 +382,68 @@ fluid.defaults("gpii.test.integration.mockSettingsHandlerRegistry.android", { } } }); + +fluid.defaults("gpii.test.integration.deviceReporterAware", { + gradeNames: ["fluid.eventedComponent", "autoInit"], + rootPath: "gpii.test.integration.deviceReporterAware.mockDeviceReporters", + members: { + mockDeviceReporters: {}, + deviceReporters: {} + }, + invokers: { + resolveName: { + funcName: "gpii.test.integration.deviceReporterAware.resolveName", + args: ["{that}", "{arguments}.0"] + } + }, + listeners: { + onCreate: "gpii.test.integration.deviceReporterAware.populate" + } +}); + +gpii.test.integration.deviceReporterAware.mockDeviceReporters = {}; + +gpii.test.integration.deviceReporterAware.mockDeviceReporters.findNameInList = function (expectInstalled, name) { + return expectInstalled.some(function (el) { return el === name; }); +}; + +gpii.test.integration.deviceReporterAware.populate = function (that) { + fluid.each(that.options.deviceReporters, function (options, key) { + var mock = that.options.mockDeviceReporters[key]; + + if (!mock) { + var registered = fluid.keys(that.options.mockDeviceReporters).join(", "); + fluid.fail("Error in dynamic device reporter mock configuration - handler " + key + + " is not registered - registered handlers are " + registered); + } + + var expectInstalled = []; + fluid.each(that.options.deviceReporters[key].expectInstalled, function (item) { + expectInstalled.push(item); + }); + + fluid.defaults(that.options.rootPath + "." + key, mock.defaults); + + var mockedFunction = gpii.test.integration.deviceReporterAware.mockDeviceReporters[mock.mockFunc].bind(undefined, expectInstalled); + fluid.setGlobalValue(that.options.rootPath + "." + key, mockedFunction); + }); +}; + +gpii.test.integration.deviceReporterAware.resolveName = function (that, name) { + return that.options.rootPath + "." + name; +}; + +fluid.defaults("gpii.test.integration.deviceReporterAware.linux", { + gradeNames: ["gpii.test.integration.deviceReporterAware", "autoInit"], + mockDeviceReporters: { + "gpii.packageKit.find": { + mockFunc: "findNameInList", + defaults: { + gradeNames: "fluid.function", + argumentMap: { + name: 0 + } + } + } + } +}); diff --git a/testData/solutions/linux.json b/testData/solutions/linux.json index f456ff5ea..8d49d0bad 100644 --- a/testData/solutions/linux.json +++ b/testData/solutions/linux.json @@ -7,6 +7,12 @@ "id": "linux", "version": ">=2.6.26" } + ], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "gnome-shell" + } ] }, "settingsHandlers": [ @@ -92,6 +98,12 @@ "id": "linux", "version": ">=2.6.26" } + ], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "gsettings-desktop-schemas" + } ] }, "settingsHandlers": [ @@ -171,7 +183,13 @@ "OS": [{ "id": "linux", "version": ">=2.6.26" - }] + }], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "nautilus" + } + ] }, "settingsHandlers": [ @@ -202,7 +220,13 @@ "OS": [{ "id": "linux", "version": ">=2.6.26" - }] + }], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "gnome-shell" + } + ] }, "settingsHandlers": [ { @@ -236,7 +260,13 @@ "OS": [{ "id": "linux", "version": ">=2.6.26" - }] + }], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "gsettings-desktop-schemas" + } + ] }, "settingsHandlers": [ { "type": "gpii.gsettings", @@ -303,7 +333,13 @@ "OS": [{ "id": "linux", "version": ">=2.6.26" - }] + }], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "gnome-shell" + } + ] }, "settingsHandlers": [ @@ -331,7 +367,13 @@ "OS": [{ "id": "linux", "version": ">=2.6.26" - }] + }], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "gnome-shell" + } + ] }, "settingsHandlers": [ @@ -359,7 +401,13 @@ "OS": [{ "id": "linux", "version": ">=2.6.26" - }] + }], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "orca" + } + ] }, "settingsHandlers": [ { @@ -1173,6 +1221,16 @@ "id": "linux", "version": ">=2.6.26" } + ], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "alsa" + }, + { + "type": "gpii.packageKit.find", + "name": "alsa-lib" + } ] }, "settingsHandlers": [ @@ -1206,6 +1264,20 @@ "id": "linux", "version": ">=2.6.26" } + ], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "google-chrome-beta" + }, + { + "type": "gpii.packageKit.find", + "name": "google-chrome-stable" + }, + { + "type": "gpii.packageKit.find", + "name": "google-chrome-unstable" + } ] }, "settingsHandlers": [ @@ -1242,6 +1314,20 @@ "id": "linux", "version": ">=2.6.26" } + ], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "google-chrome-beta" + }, + { + "type": "gpii.packageKit.find", + "name": "google-chrome-stable" + }, + { + "type": "gpii.packageKit.find", + "name": "google-chrome-unstable" + } ] }, "settingsHandlers": [ @@ -1278,6 +1364,20 @@ "id": "linux", "version": ">=2.6.26" } + ], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "google-chrome-beta" + }, + { + "type": "gpii.packageKit.find", + "name": "google-chrome-stable" + }, + { + "type": "gpii.packageKit.find", + "name": "google-chrome-unstable" + } ] }, "settingsHandlers": [ @@ -1311,7 +1411,13 @@ "OS": [{ "id": "linux", "version": ">=2.6.26" - }] + }], + "isInstalled": [ + { + "type": "gpii.packageKit.find", + "name": "libXrandr" + } + ] }, "settingsHandlers": [ { diff --git a/tests/configs/localInstallWithDynamicDeviceReporter.json b/tests/configs/localInstallWithDynamicDeviceReporter.json new file mode 100644 index 000000000..8986980c6 --- /dev/null +++ b/tests/configs/localInstallWithDynamicDeviceReporter.json @@ -0,0 +1,21 @@ +{ + "typeName": "acceptanceTests.all.development.dr.production.config", + "options": { + "components": { + "server": { + "options": { + "components": { + "rawPreferencesServer": { + "options": { + "rawPreferencesSourceUrl": "file://%root/../../../testData/preferences/acceptanceTests/%userToken.json" + } + } + } + } + } + } + }, + "includes": [ + "${universal}/gpii/configs/all.development.dr.production.json" + ] +} diff --git a/tests/platform/index-linux.js b/tests/platform/index-linux.js index 69e453c19..cf9b791c5 100644 --- a/tests/platform/index-linux.js +++ b/tests/platform/index-linux.js @@ -22,5 +22,6 @@ https://github.com/GPII/universal/blob/master/LICENSE.txt module.exports = [ "linux/linux-builtIn-testSpec.js", - "linux/linux-orca-testSpec.js" -]; \ No newline at end of file + "linux/linux-orca-testSpec.js", + "linux/linux-dynamicDeviceReporter-testSpec.js" +]; diff --git a/tests/platform/linux/configs/linux-dynamicDeviceReporter-config.json b/tests/platform/linux/configs/linux-dynamicDeviceReporter-config.json new file mode 100644 index 000000000..045c6a602 --- /dev/null +++ b/tests/platform/linux/configs/linux-dynamicDeviceReporter-config.json @@ -0,0 +1,6 @@ +{ + "typeName": "acceptanceTests.linux.dynamicDeviceReporter", + "includes": [ + "${universal}/tests/configs/localInstallWithDynamicDeviceReporter.json" + ] +} diff --git a/tests/platform/linux/configs/linux-dynamicDeviceReporter-config.txt b/tests/platform/linux/configs/linux-dynamicDeviceReporter-config.txt new file mode 100644 index 000000000..8d1c551c1 --- /dev/null +++ b/tests/platform/linux/configs/linux-dynamicDeviceReporter-config.txt @@ -0,0 +1,4 @@ +This configuration file is used by the acceptance test: linux-dynamicDeviceReporter-config.js. + +This config makes use of dynamic device reporting, so it uses localInstallWithDynamicDeviceReporter +as its base config, which uses the all.development.dr.production gpii's config. diff --git a/tests/platform/linux/linux-dynamicDeviceReporter-testSpec.js b/tests/platform/linux/linux-dynamicDeviceReporter-testSpec.js new file mode 100644 index 000000000..a38274fc1 --- /dev/null +++ b/tests/platform/linux/linux-dynamicDeviceReporter-testSpec.js @@ -0,0 +1,155 @@ +/* +GPII Integration and Acceptance Testing + +Copyright 2014 Emergya + +Licensed under the New BSD license. You may not use this file except in +compliance with this License. + +You may obtain a copy of the License at +https://github.com/gpii/universal/LICENSE.txt +*/ + +"use strict"; +var fluid = require("universal"), + gpii = fluid.registerNamespace("gpii"); + +gpii.loadTestingSupport(); + +fluid.registerNamespace("gpii.tests.deviceReporterAware.linux.orca"); + +gpii.tests.deviceReporterAware.linux.orca = [ + { + name: "Testing screenreader_common using Flat matchmaker", + gradeNames: "gpii.test.integration.deviceReporterAware.linux", + userToken: "screenreader_common", + settingsHandlers: { + "gpii.orca": { + "data": [ + { + "settings": { + "sayAllStyle": 1, + "enableSpeech": true, + "enableEchoByWord": true, + "enableEchoByCharacter": false, + "voices.default.rate": 102.27272727272727, + "voices.default.gain": 7.5, + "enableTutorialMessages": false, + "voices.default.family": { + "locale": "en", + "name": "en-westindies" + }, + "verbalizePunctuationStyle": 0, + "voices.default.average-pitch": 1.5 + }, + "options": { + "user": "screenreader_common" + } + } + ] + } + }, + processes: [ + { + "command": "gsettings get org.gnome.desktop.a11y.applications screen-reader-enabled", + "expectConfigured": "true", + "expectRestored": "false" + } + ], + deviceReporters: { + "gpii.packageKit.find": { + "expectInstalled": ["orca"] + } + } + }, + { + name: "Testing screenreader_orca using Flat matchmaker", + gradeNames: "gpii.test.integration.deviceReporterAware.linux", + userToken: "screenreader_orca", + settingsHandlers: { + "gpii.orca": { + "some.app.id": [ + { + "settings": { + "sayAllStyle": 1, + "enableEchoByWord": true, + "enableEchoByCharacter": false, + "voices.default.rate": 102.27272727272727, + "voices.default.gain": 7.5, + "enableTutorialMessages": false, + "voices.default.family": { + "locale": "en", + "name": "en-westindies" + }, + "verbalizePunctuationStyle": 0, + "voices.default.average-pitch": 1.5 + }, + "options": { + "user": "screenreader_orca" + } + } + ] + } + }, + processes: [ + { + "command": "gsettings get org.gnome.desktop.a11y.applications screen-reader-enabled", + "expectConfigured": "true", + "expectRestored": "false" + } + ], + deviceReporters: { + "gpii.packageKit.find": { + "expectInstalled": ["orca"] + } + } + }, + { + name: "Testing screenreader_nvda using Flat matchmaker", + gradeNames: "gpii.test.integration.deviceReporterAware.linux", + userToken: "screenreader_nvda", + settingsHandlers: { + "gpii.orca": { + "some.app.id": [ + { + "settings": { + "sayAllStyle": 1, + "enableSpeech": true, + "enableEchoByWord": true, + "enableEchoByCharacter": false, + "voices.default.rate": 101.84090909090908, + "enableTutorialMessages": false, + "voices.default.family": { + "locale": "en", + "name": "en-westindies" + }, + "verbalizePunctuationStyle": 0 + }, + "options": { + "user": "screenreader_nvda" + } + } + ] + } + }, + processes: [ + { + "command": "gsettings get org.gnome.desktop.a11y.applications screen-reader-enabled", + "expectConfigured": "true", + "expectRestored": "false" + } + ], + deviceReporters: { + "gpii.packageKit.find": { + "expectInstalled": ["orca"] + } + } + } +]; + +module.exports = gpii.test.bootstrap({ + testDefs: "gpii.tests.deviceReporterAware.linux.orca", + configName: "linux-dynamicDeviceReporter-config", + configPath: "configs" +}, ["gpii.test.integration.testCaseHolder.linux", "gpii.test.integration.deviceReporterAware.linux"], + module, require, __dirname); diff --git a/tests/platform/linux/linux-dynamicDeviceReporter-testSpec.txt b/tests/platform/linux/linux-dynamicDeviceReporter-testSpec.txt new file mode 100644 index 000000000..979e68516 --- /dev/null +++ b/tests/platform/linux/linux-dynamicDeviceReporter-testSpec.txt @@ -0,0 +1,6 @@ +linux-dynamicDeviceReporter-testSpec.js + +Descriptions: + +This will run the acceptance tests with dynamic device reporting. +It uses 1 NP set: screenreader_common (but more will be added)