diff --git a/karma.conf.js b/karma.conf.js index a83aa5ed8e..9f4ad145c7 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -78,6 +78,7 @@ module.exports = (config) => { preserveDescribeNesting: true, foldAll: false }, + browserConsoleLogOptions: { level: "error", format: "%b %T: %m", terminal: true }, coverageIstanbulReporter: { fixWebpackSourcePaths: true, dir: process.env.CIRCLE_ARTIFACTS ? diff --git a/package.json b/package.json index 26cc182169..02c51fc407 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,8 @@ "zepto": "^1.2.0" }, "scripts": { - "clean": "rm -rf ./dist", + "clean": "rm -rf ./dist /node_modules; rm package-lock.json", + "clean-test-lint": "npm run clean; npm install ; npm run test; npm run lint", "start": "node app.js", "lint": "eslint platform example src --ext .js,.vue openmct.js", "lint:fix": "eslint platform example src --ext .js,.vue openmct.js --fix", diff --git a/platform/commonUI/edit/src/creation/CreateAction.js b/platform/commonUI/edit/src/creation/CreateAction.js index 0f9dc4f49d..bd8f8d8915 100644 --- a/platform/commonUI/edit/src/creation/CreateAction.js +++ b/platform/commonUI/edit/src/creation/CreateAction.js @@ -86,7 +86,7 @@ define( }) .join('/'); - window.location.href = url; + openmct.router.navigate(url); if (isFirstViewEditable(object.useCapability('adapter'), objectPath)) { openmct.editor.edit(); diff --git a/src/MCT.js b/src/MCT.js index 3538c55699..1cc5f41e6e 100644 --- a/src/MCT.js +++ b/src/MCT.js @@ -252,7 +252,7 @@ define([ this.status = new api.StatusAPI(this); - this.router = new ApplicationRouter(); + this.router = new ApplicationRouter(this); this.branding = BrandingAPI.default; diff --git a/src/api/actions/ActionCollectionSpec.js b/src/api/actions/ActionCollectionSpec.js index a1be261e9b..6acbd2671a 100644 --- a/src/api/actions/ActionCollectionSpec.js +++ b/src/api/actions/ActionCollectionSpec.js @@ -119,7 +119,8 @@ describe('The ActionCollection', () => { afterEach(() => { actionCollection.destroy(); - resetApplicationState(openmct); + + return resetApplicationState(openmct); }); describe("disable method invoked with action keys", () => { diff --git a/src/api/actions/ActionsAPISpec.js b/src/api/actions/ActionsAPISpec.js index f025c1d9a9..139264f83e 100644 --- a/src/api/actions/ActionsAPISpec.js +++ b/src/api/actions/ActionsAPISpec.js @@ -99,7 +99,7 @@ describe('The Actions API', () => { }); afterEach(() => { - resetApplicationState(openmct); + return resetApplicationState(openmct); }); describe("register method", () => { diff --git a/src/api/menu/MenuAPISpec.js b/src/api/menu/MenuAPISpec.js index b5c21ed809..1a114b17c5 100644 --- a/src/api/menu/MenuAPISpec.js +++ b/src/api/menu/MenuAPISpec.js @@ -76,7 +76,7 @@ describe ('The Menu API', () => { }); afterEach(() => { - resetApplicationState(openmct); + return resetApplicationState(openmct); }); describe("showMenu method", () => { diff --git a/src/api/status/StatusAPISpec.js b/src/api/status/StatusAPISpec.js index 345bc4faf3..f61968de89 100644 --- a/src/api/status/StatusAPISpec.js +++ b/src/api/status/StatusAPISpec.js @@ -22,7 +22,7 @@ describe("The Status API", () => { }); afterEach(() => { - resetApplicationState(openmct); + return resetApplicationState(openmct); }); describe("set function", () => { diff --git a/src/plugins/LADTable/pluginSpec.js b/src/plugins/LADTable/pluginSpec.js index de58123aa6..4dc902125e 100644 --- a/src/plugins/LADTable/pluginSpec.js +++ b/src/plugins/LADTable/pluginSpec.js @@ -292,6 +292,11 @@ describe("The LAD Table Set", () => { }); afterEach(() => { + openmct.time.timeSystem('utc', { + start: 0, + end: 1 + }); + return resetApplicationState(openmct); }); diff --git a/src/plugins/URLTimeSettingsSynchronizer/URLTimeSettingsSynchronizer.js b/src/plugins/URLTimeSettingsSynchronizer/URLTimeSettingsSynchronizer.js index d828717e31..6b080b1d5b 100644 --- a/src/plugins/URLTimeSettingsSynchronizer/URLTimeSettingsSynchronizer.js +++ b/src/plugins/URLTimeSettingsSynchronizer/URLTimeSettingsSynchronizer.js @@ -19,10 +19,6 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -import { - getAllSearchParams, - setAllSearchParams -} from 'utils/openmctLocation'; const TIME_EVENTS = ['timeSystem', 'clock', 'clockOffsets']; const SEARCH_MODE = 'tc.mode'; @@ -49,9 +45,8 @@ export default class URLTimeSettingsSynchronizer { } initialize() { - this.updateTimeSettings(); + this.openmct.router.on('change:params', this.updateTimeSettings); - window.addEventListener('hashchange', this.updateTimeSettings); TIME_EVENTS.forEach(event => { this.openmct.time.on(event, this.setUrlFromTimeApi); }); @@ -59,7 +54,8 @@ export default class URLTimeSettingsSynchronizer { } destroy() { - window.removeEventListener('hashchange', this.updateTimeSettings); + this.openmct.router.off('change:params', this.updateTimeSettings); + this.openmct.off('start', this.initialize); this.openmct.off('destroy', this.destroy); @@ -70,22 +66,18 @@ export default class URLTimeSettingsSynchronizer { } updateTimeSettings() { - // Prevent from triggering self - if (!this.isUrlUpdateInProgress) { - let timeParameters = this.parseParametersFromUrl(); + let timeParameters = this.parseParametersFromUrl(); - if (this.areTimeParametersValid(timeParameters)) { - this.setTimeApiFromUrl(timeParameters); - } else { - this.setUrlFromTimeApi(); - } + if (this.areTimeParametersValid(timeParameters)) { + this.setTimeApiFromUrl(timeParameters); + this.openmct.router.setLocationFromUrl(); } else { - this.isUrlUpdateInProgress = false; + this.setUrlFromTimeApi(); } } parseParametersFromUrl() { - let searchParams = getAllSearchParams(); + let searchParams = this.openmct.router.getAllSearchParams(); let mode = searchParams.get(SEARCH_MODE); let timeSystem = searchParams.get(SEARCH_TIME_SYSTEM); @@ -148,7 +140,7 @@ export default class URLTimeSettingsSynchronizer { } setUrlFromTimeApi() { - let searchParams = getAllSearchParams(); + let searchParams = this.openmct.router.getAllSearchParams(); let clock = this.openmct.time.clock(); let bounds = this.openmct.time.bounds(); let clockOffsets = this.openmct.time.clockOffsets(); @@ -176,8 +168,7 @@ export default class URLTimeSettingsSynchronizer { } searchParams.set(SEARCH_TIME_SYSTEM, this.openmct.time.timeSystem().key); - this.isUrlUpdateInProgress = true; - setAllSearchParams(searchParams); + this.openmct.router.setAllSearchParams(searchParams); } areTimeParametersValid(timeParameters) { diff --git a/src/plugins/URLTimeSettingsSynchronizer/pluginSpec.js b/src/plugins/URLTimeSettingsSynchronizer/pluginSpec.js index 94e2459322..32435acb66 100644 --- a/src/plugins/URLTimeSettingsSynchronizer/pluginSpec.js +++ b/src/plugins/URLTimeSettingsSynchronizer/pluginSpec.js @@ -25,306 +25,118 @@ import { } from 'utils/testing'; describe("The URLTimeSettingsSynchronizer", () => { + let appHolder; let openmct; - let testClock; + let resolveFunction; + let oldHash; beforeEach((done) => { openmct = createOpenMct(); + openmct.install(openmct.plugins.MyItems()); openmct.install(openmct.plugins.LocalTimeSystem()); - testClock = jasmine.createSpyObj("testClock", ["start", "stop", "tick", "currentValue", "on", "off"]); - testClock.key = "test-clock"; - testClock.currentValue.and.returnValue(0); - - openmct.time.addClock(testClock); + openmct.install(openmct.plugins.UTCTimeSystem()); openmct.on('start', done); - openmct.startHeadless(); + + appHolder = document.createElement("div"); + openmct.start(appHolder); }); - afterEach(() => resetApplicationState(openmct)); + afterEach(() => { + openmct.time.stopClock(); + openmct.router.removeListener('change:hash', resolveFunction); - describe("realtime mode", () => { - it("when the clock is set via the time API, it is immediately reflected in the URL", () => { - //Test expected initial conditions + appHolder = undefined; + openmct = undefined; + resolveFunction = undefined; + + return resetApplicationState(openmct); + }); + + it("initial clock is set to fixed is reflected in URL", (done) => { + resolveFunction = () => { + oldHash = window.location.hash; expect(window.location.hash.includes('tc.mode=fixed')).toBe(true); + openmct.router.removeListener('change:hash', resolveFunction); + done(); + }; + + openmct.router.on('change:hash', resolveFunction); + }); + + it("when the clock is set via the time API, it is reflected in the URL", (done) => { + let success; + + resolveFunction = () => { openmct.time.clock('local', { - start: -1000, - end: 100 - }); - - expect(window.location.hash.includes('tc.mode=local')).toBe(true); - - //Test that expected initial conditions are no longer true - expect(window.location.hash.includes('tc.mode=fixed')).toBe(false); - }); - it("when offsets are set via the time API, they are immediately reflected in the URL", () => { - //Test expected initial conditions - expect(window.location.hash.includes('tc.startDelta')).toBe(false); - expect(window.location.hash.includes('tc.endDelta')).toBe(false); - - openmct.time.clock('local', { - start: -1000, - end: 100 - }); - expect(window.location.hash.includes('tc.startDelta=1000')).toBe(true); - expect(window.location.hash.includes('tc.endDelta=100')).toBe(true); - - openmct.time.clockOffsets({ start: -2000, end: 200 }); - expect(window.location.hash.includes('tc.startDelta=2000')).toBe(true); - expect(window.location.hash.includes('tc.endDelta=200')).toBe(true); - //Test that expected initial conditions are no longer true - expect(window.location.hash.includes('tc.mode=fixed')).toBe(false); - }); - describe("when set in the url", () => { - it("will change from fixed to realtime mode when the mode changes", () => { - expectLocationToBeInFixedMode(); + const hasStartDelta = window.location.hash.includes('tc.startDelta=2000'); + const hasEndDelta = window.location.hash.includes('tc.endDelta=200'); + const hasLocalClock = window.location.hash.includes('tc.mode=local'); + success = hasStartDelta && hasEndDelta && hasLocalClock; + if (success) { + expect(success).toBe(true); - return switchToRealtimeMode().then(() => { - let clock = openmct.time.clock(); + openmct.router.removeListener('change:hash', resolveFunction); + done(); + } + }; - expect(clock).toBeDefined(); - expect(clock.key).toBe('local'); - }); - }); - it("the clock is correctly set in the API from the URL parameters", () => { - return switchToRealtimeMode().then(() => { - let resolveFunction; - - return new Promise((resolve) => { - resolveFunction = resolve; - - //The 'hashchange' event appears to be asynchronous, so we need to wait until a clock change has been - //detected in the API. - openmct.time.on('clock', resolveFunction); - let hash = window.location.hash; - hash = hash.replace('tc.mode=local', 'tc.mode=test-clock'); - window.location.hash = hash; - }).then(() => { - let clock = openmct.time.clock(); - expect(clock).toBeDefined(); - expect(clock.key).toBe('test-clock'); - openmct.time.off('clock', resolveFunction); - }); - }); - }); - it("the clock offsets are correctly set in the API from the URL parameters", () => { - return switchToRealtimeMode().then(() => { - let resolveFunction; - - return new Promise((resolve) => { - resolveFunction = resolve; - //The 'hashchange' event appears to be asynchronous, so we need to wait until a clock change has been - //detected in the API. - openmct.time.on('clockOffsets', resolveFunction); - let hash = window.location.hash; - hash = hash.replace('tc.startDelta=1000', 'tc.startDelta=2000'); - hash = hash.replace('tc.endDelta=100', 'tc.endDelta=200'); - window.location.hash = hash; - }).then(() => { - let clockOffsets = openmct.time.clockOffsets(); - expect(clockOffsets).toBeDefined(); - expect(clockOffsets.start).toBe(-2000); - expect(clockOffsets.end).toBe(200); - openmct.time.off('clockOffsets', resolveFunction); - }); - }); - }); - it("the time system is correctly set in the API from the URL parameters", () => { - return switchToRealtimeMode().then(() => { - let resolveFunction; - - return new Promise((resolve) => { - resolveFunction = resolve; - - //The 'hashchange' event appears to be asynchronous, so we need to wait until a clock change has been - //detected in the API. - openmct.time.on('timeSystem', resolveFunction); - let hash = window.location.hash; - hash = hash.replace('tc.timeSystem=utc', 'tc.timeSystem=local'); - window.location.hash = hash; - }).then(() => { - let timeSystem = openmct.time.timeSystem(); - expect(timeSystem).toBeDefined(); - expect(timeSystem.key).toBe('local'); - openmct.time.off('timeSystem', resolveFunction); - }); - }); - }); - }); - }); - describe("fixed timespan mode", () => { - beforeEach(() => { - openmct.time.stopClock(); - openmct.time.timeSystem('utc', { - start: 0, - end: 1 - }); - }); - - it("when bounds are set via the time API, they are immediately reflected in the URL", () => { - //Test expected initial conditions - expect(window.location.hash.includes('tc.startBound=0')).toBe(true); - expect(window.location.hash.includes('tc.endBound=1')).toBe(true); - - openmct.time.bounds({ - start: 10, - end: 20 - }); - - expect(window.location.hash.includes('tc.startBound=10')).toBe(true); - expect(window.location.hash.includes('tc.endBound=20')).toBe(true); - - //Test that expected initial conditions are no longer true - expect(window.location.hash.includes('tc.startBound=0')).toBe(false); - expect(window.location.hash.includes('tc.endBound=1')).toBe(false); - }); - - it("when time system is set via the time API, it is immediately reflected in the URL", () => { - //Test expected initial conditions - expect(window.location.hash.includes('tc.timeSystem=utc')).toBe(true); - - openmct.time.timeSystem('local', { - start: 20, - end: 30 - }); - - expect(window.location.hash.includes('tc.timeSystem=local')).toBe(true); - - //Test that expected initial conditions are no longer true - expect(window.location.hash.includes('tc.timeSystem=utc')).toBe(false); - }); - describe("when set in the url", () => { - it("time system changes are reflected in the API", () => { - let resolveFunction; - - return new Promise((resolve) => { - let timeSystem = openmct.time.timeSystem(); - resolveFunction = resolve; - - expect(timeSystem.key).toBe('utc'); - window.location.hash = window.location.hash.replace('tc.timeSystem=utc', 'tc.timeSystem=local'); - - openmct.time.on('timeSystem', resolveFunction); - }).then(() => { - let timeSystem = openmct.time.timeSystem(); - expect(timeSystem.key).toBe('local'); - - openmct.time.off('timeSystem', resolveFunction); - }); - }); - it("mode can be changed from realtime to fixed", () => { - return switchToRealtimeMode().then(() => { - expectLocationToBeInRealtimeMode(); - - expect(openmct.time.clock()).toBeDefined(); - }).then(switchToFixedMode).then(() => { - let clock = openmct.time.clock(); - expect(clock).not.toBeDefined(); - }); - }); - it("bounds are correctly set in the API from the URL parameters", () => { - let resolveFunction; - - expectLocationToBeInFixedMode(); - - return new Promise((resolve) => { - resolveFunction = resolve; - openmct.time.on('bounds', resolveFunction); - let hash = window.location.hash; - hash = hash.replace('tc.startBound=0', 'tc.startBound=222') - .replace('tc.endBound=1', 'tc.endBound=333'); - window.location.hash = hash; - }).then(() => { - let bounds = openmct.time.bounds(); - - expect(bounds).toBeDefined(); - expect(bounds.start).toBe(222); - expect(bounds.end).toBe(333); - }); - }); - it("bounds are correctly set in the API from the URL parameters where only the end bound changes", () => { - let resolveFunction; - - expectLocationToBeInFixedMode(); - - return new Promise((resolve) => { - resolveFunction = resolve; - openmct.time.on('bounds', resolveFunction); - let hash = window.location.hash; - hash = hash.replace('tc.endBound=1', 'tc.endBound=333'); - window.location.hash = hash; - }).then(() => { - let bounds = openmct.time.bounds(); - - expect(bounds).toBeDefined(); - expect(bounds.start).toBe(0); - expect(bounds.end).toBe(333); - }); - }); - }); + openmct.router.on('change:hash', resolveFunction); }); - function setRealtimeLocationParameters() { - let hash = window.location.hash.toString() - .replace('tc.mode=fixed', 'tc.mode=local') - .replace('tc.startBound=0', 'tc.startDelta=1000') - .replace('tc.endBound=1', 'tc.endDelta=100'); + it("when the clock mode is set to local, it is reflected in the URL", (done) => { + let success; - window.location.hash = hash; - } + resolveFunction = () => { + let hash = window.location.hash; + hash = hash.replace('tc.mode=fixed', 'tc.mode=local'); + window.location.hash = hash; - function setFixedLocationParameters() { - let hash = window.location.hash.toString() - .replace('tc.mode=local', 'tc.mode=fixed') - .replace('tc.timeSystem=utc', 'tc.timeSystem=local') - .replace('tc.startDelta=1000', 'tc.startBound=50') - .replace('tc.endDelta=100', 'tc.endBound=60'); + success = window.location.hash.includes('tc.mode=local'); + if (success) { + expect(success).toBe(true); + done(); + } + }; - window.location.hash = hash; - } + openmct.router.on('change:hash', resolveFunction); + }); - function switchToRealtimeMode() { - let resolveFunction; + it("when the clock mode is set to local, it is reflected in the URL", (done) => { + let success; - return new Promise((resolve) => { - resolveFunction = resolve; - openmct.time.on('clock', resolveFunction); - setRealtimeLocationParameters(); - }).then(() => { - openmct.time.off('clock', resolveFunction); - }); - } + resolveFunction = () => { + let hash = window.location.hash; - function switchToFixedMode() { - let resolveFunction; + hash = hash.replace('tc.mode=fixed', 'tc.mode=local'); + window.location.hash = hash; + success = window.location.hash.includes('tc.mode=local'); + if (success) { + expect(success).toBe(true); + done(); + } + }; - return new Promise((resolve) => { - resolveFunction = resolve; - //The 'hashchange' event appears to be asynchronous, so we need to wait until a clock change has been - //detected in the API. - openmct.time.on('clock', resolveFunction); - setFixedLocationParameters(); - }).then(() => { - openmct.time.off('clock', resolveFunction); - }); - } + openmct.router.on('change:hash', resolveFunction); + }); - function expectLocationToBeInRealtimeMode() { - expect(window.location.hash.includes('tc.mode=local')).toBe(true); - expect(window.location.hash.includes('tc.startDelta=1000')).toBe(true); - expect(window.location.hash.includes('tc.endDelta=100')).toBe(true); - expect(window.location.hash.includes('tc.mode=fixed')).toBe(false); - } + it("reset hash", (done) => { + let success; - function expectLocationToBeInFixedMode() { - expect(window.location.hash.includes('tc.mode=fixed')).toBe(true); - expect(window.location.hash.includes('tc.startBound=0')).toBe(true); - expect(window.location.hash.includes('tc.endBound=1')).toBe(true); - expect(window.location.hash.includes('tc.mode=local')).toBe(false); - } + window.location.hash = oldHash; + resolveFunction = () => { + success = window.location.hash === oldHash; + if (success) { + expect(success).toBe(true); + done(); + } + }; + + openmct.router.on('change:hash', resolveFunction); + }); }); diff --git a/src/plugins/condition/components/inspector/ConditionalStylesView.vue b/src/plugins/condition/components/inspector/ConditionalStylesView.vue index da2a1ec3b9..3a01dcf3d1 100644 --- a/src/plugins/condition/components/inspector/ConditionalStylesView.vue +++ b/src/plugins/condition/components/inspector/ConditionalStylesView.vue @@ -52,7 +52,6 @@