chore: remove vue/compat and complete Vue 3 migration (#7133)

* chore: remove custom `compatConfig` settings

* chore: remove `vue-compat` and adjust webpack config

* chore: explicitly define Vue feature flags

* fix: `_data` property moved to `_.data`

* fix(e2e): revert to original test procedures

* refactor: replace final instances of `$set`

* refactor: remove `Vue` imports from tests

* refactor: `Vue.ref()` -> `ref()`

* refactor: actually push the changes...

* test: replace unit test with e2e test

* test: remove test as it's already covered by e2e

* fix(test): use `$ref`s instead of `$children`

* test(fix): more `$refs`

* fix(test): more `$refs`

* fix(test): use `$refs` in InspectorStyles tests

* fix(SearchComponent): use `$attrs` correctly

---------

Co-authored-by: Scott Bell <scott@traclabs.com>
This commit is contained in:
Jesse Mazzella 2023-10-19 09:08:39 -07:00 committed by GitHub
parent 1414f54c17
commit 43338f3980
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 436 additions and 471 deletions

View File

@ -77,8 +77,7 @@ const config = {
MCT: path.join(projectRootDir, 'src/MCT'), MCT: path.join(projectRootDir, 'src/MCT'),
testUtils: path.join(projectRootDir, 'src/utils/testUtils.js'), testUtils: path.join(projectRootDir, 'src/utils/testUtils.js'),
objectUtils: path.join(projectRootDir, 'src/api/objects/object-utils.js'), objectUtils: path.join(projectRootDir, 'src/api/objects/object-utils.js'),
utils: path.join(projectRootDir, 'src/utils'), utils: path.join(projectRootDir, 'src/utils')
vue: path.join(projectRootDir, 'node_modules/@vue/compat/dist/vue.esm-bundler.js'),
} }
}, },
plugins: [ plugins: [
@ -86,7 +85,9 @@ const config = {
__OPENMCT_VERSION__: `'${packageDefinition.version}'`, __OPENMCT_VERSION__: `'${packageDefinition.version}'`,
__OPENMCT_BUILD_DATE__: `'${new Date()}'`, __OPENMCT_BUILD_DATE__: `'${new Date()}'`,
__OPENMCT_REVISION__: `'${gitRevision}'`, __OPENMCT_REVISION__: `'${gitRevision}'`,
__OPENMCT_BUILD_BRANCH__: `'${gitBranch}'` __OPENMCT_BUILD_BRANCH__: `'${gitBranch}'`,
__VUE_OPTIONS_API__: true, // enable/disable Options API support, default: true
__VUE_PROD_DEVTOOLS__: false // enable/disable devtools support in production, default: false
}), }),
new VueLoaderPlugin(), new VueLoaderPlugin(),
new CopyWebpackPlugin({ new CopyWebpackPlugin({
@ -115,7 +116,7 @@ const config = {
new webpack.BannerPlugin({ new webpack.BannerPlugin({
test: /.*Theme\.css$/, test: /.*Theme\.css$/,
raw: true, raw: true,
banner: '@charset "UTF-8";', banner: '@charset "UTF-8";'
}) })
], ],
module: { module: {
@ -142,10 +143,7 @@ const config = {
options: { options: {
compilerOptions: { compilerOptions: {
hoistStatic: false, hoistStatic: false,
whitespace: 'preserve', whitespace: 'preserve'
compatConfig: {
MODE: 2
}
} }
} }
}, },

View File

@ -0,0 +1,59 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2023, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*
Verify that the "Clear Data" menu action performs as expected for various object types.
*/
const { test, expect } = require('../../pluginFixtures.js');
const { createDomainObjectWithDefaults } = require('../../appActions.js');
const backgroundImageSelector = '.c-imagery__main-image__background-image';
test.describe('Clear Data Action', () => {
test.beforeEach(async ({ page }) => {
// Go to baseURL
await page.goto('./', { waitUntil: 'domcontentloaded' });
// Create a default 'Example Imagery' object
const exampleImagery = await createDomainObjectWithDefaults(page, { type: 'Example Imagery' });
// Verify that the created object is focused
await expect(page.locator('.l-browse-bar__object-name')).toContainText(exampleImagery.name);
await page.locator('.c-imagery__main-image__bg').hover({ trial: true });
await expect(page.locator(backgroundImageSelector)).toBeVisible();
});
test('works as expected with Example Imagery', async ({ page }) => {
await expect(await page.locator('.c-thumb__image').count()).toBeGreaterThan(0);
// Click the "Clear Data" menu action
await page.getByTitle('More options').click();
const clearDataMenuItem = page.getByRole('menuitem', {
name: 'Clear Data'
});
await expect(clearDataMenuItem).toBeEnabled();
await clearDataMenuItem.click();
// Verify that the background image is no longer visible
await expect(page.locator(backgroundImageSelector)).toBeHidden();
await expect(await page.locator('.c-thumb__image').count()).toBe(0);
});
});

View File

@ -77,11 +77,11 @@ test.describe('Grand Search', () => {
// Click [aria-label="OpenMCT Search"] a >> nth=0 // Click [aria-label="OpenMCT Search"] a >> nth=0
await page.locator('[aria-label="Search Result"] >> nth=0').click(); await page.locator('[aria-label="Search Result"] >> nth=0').click();
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeInViewport(); await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
// Fill [aria-label="OpenMCT Search"] input[type="search"] // Fill [aria-label="OpenMCT Search"] input[type="search"]
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('foo'); await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('foo');
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).not.toBeInViewport(); await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
// Click text=Snapshot Save and Finish Editing Save and Continue Editing >> button >> nth=1 // Click text=Snapshot Save and Finish Editing Save and Continue Editing >> button >> nth=1
await page await page

View File

@ -12,7 +12,6 @@
"@types/eventemitter3": "1.2.0", "@types/eventemitter3": "1.2.0",
"@types/jasmine": "4.3.4", "@types/jasmine": "4.3.4",
"@types/lodash": "4.14.192", "@types/lodash": "4.14.192",
"@vue/compat": "3.3.4",
"@vue/compiler-sfc": "3.3.4", "@vue/compiler-sfc": "3.3.4",
"babel-loader": "9.1.0", "babel-loader": "9.1.0",
"babel-plugin-istanbul": "6.1.1", "babel-plugin-istanbul": "6.1.1",

View File

@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
import Vue from 'vue'; import { nextTick } from 'vue';
import { createMouseEvent, createOpenMct, resetApplicationState } from '../../utils/testing'; import { createMouseEvent, createOpenMct, resetApplicationState } from '../../utils/testing';
import Menu from './menu'; import Menu from './menu';
@ -186,7 +186,7 @@ describe('The Menu API', () => {
superMenuItem.dispatchEvent(mouseOverEvent); superMenuItem.dispatchEvent(mouseOverEvent);
const itemDescription = document.querySelector('.l-item-description__description'); const itemDescription = document.querySelector('.l-item-description__description');
Vue.nextTick(() => { nextTick(() => {
expect(menuElement).not.toBeNull(); expect(menuElement).not.toBeNull();
expect(itemDescription.innerText).toEqual(actionsArray[0].description); expect(itemDescription.innerText).toEqual(actionsArray[0].description);

View File

@ -71,11 +71,6 @@ class Menu extends EventEmitter {
}, },
provide: { provide: {
options: this.options options: this.options
},
// TODO: Remove this exception upon full migration to Vue 3
// https://v3-migration.vuejs.org/breaking-changes/render-function-api.html#render-function-argument
compatConfig: {
RENDER_FUNCTION: false
} }
}); });
@ -98,11 +93,6 @@ class Menu extends EventEmitter {
}, },
provide: { provide: {
options: this.options options: this.options
},
// TODO: Remove this exception upon full migration to Vue 3
// https://v3-migration.vuejs.org/breaking-changes/render-function-api.html#render-function-argument
compatConfig: {
RENDER_FUNCTION: false
} }
}); });

View File

@ -192,11 +192,7 @@ export default {
reorderLadTables(reorderPlan) { reorderLadTables(reorderPlan) {
let oldComposition = this.ladTableObjects.slice(); let oldComposition = this.ladTableObjects.slice();
reorderPlan.forEach((reorderEvent) => { reorderPlan.forEach((reorderEvent) => {
this.$set( this.ladTableObjects[reorderEvent.newIndex] = oldComposition[reorderEvent.oldIndex];
this.ladTableObjects,
reorderEvent.newIndex,
oldComposition[reorderEvent.oldIndex]
);
}); });
}, },
addTelemetryObject(ladTable) { addTelemetryObject(ladTable) {

View File

@ -27,7 +27,7 @@ import {
resetApplicationState, resetApplicationState,
spyOnBuiltins spyOnBuiltins
} from 'utils/testing'; } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import LadPlugin from './plugin.js'; import LadPlugin from './plugin.js';
@ -233,7 +233,7 @@ describe('The LAD Table', () => {
anotherTelemetryObjectPromise, anotherTelemetryObjectPromise,
aggregateTelemetryObjectResolve aggregateTelemetryObjectResolve
]); ]);
await Vue.nextTick(); await nextTick();
}); });
it('should show one row per object in the composition', () => { it('should show one row per object in the composition', () => {
@ -244,7 +244,7 @@ describe('The LAD Table', () => {
it('should show the most recent datum from the telemetry producing object', async () => { it('should show the most recent datum from the telemetry producing object', async () => {
const latestDatum = getLatestTelemetry(mockTelemetry, { timeFormat }); const latestDatum = getLatestTelemetry(mockTelemetry, { timeFormat });
const expectedDate = utcTimeFormat(latestDatum[timeFormat]); const expectedDate = utcTimeFormat(latestDatum[timeFormat]);
await Vue.nextTick(); await nextTick();
const latestDate = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText; const latestDate = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText;
expect(latestDate).toBe(expectedDate); expect(latestDate).toBe(expectedDate);
const dataType = parent const dataType = parent
@ -254,7 +254,7 @@ describe('The LAD Table', () => {
}); });
it('should show aggregate telemetry type with blank data', async () => { it('should show aggregate telemetry type with blank data', async () => {
await Vue.nextTick(); await nextTick();
const latestData = parent const latestData = parent
.querySelectorAll(TABLE_BODY_ROWS)[1] .querySelectorAll(TABLE_BODY_ROWS)[1]
.querySelectorAll('td')[2].innerText; .querySelectorAll('td')[2].innerText;
@ -282,7 +282,7 @@ describe('The LAD Table', () => {
const mostRecentTelemetry = getLatestTelemetry(mockTelemetry, { timeFormat }); const mostRecentTelemetry = getLatestTelemetry(mockTelemetry, { timeFormat });
const rangeValue = mostRecentTelemetry[range]; const rangeValue = mostRecentTelemetry[range];
const domainValue = utcTimeFormat(mostRecentTelemetry[domain]); const domainValue = utcTimeFormat(mostRecentTelemetry[domain]);
await Vue.nextTick(); await nextTick();
const actualDomainValue = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText; const actualDomainValue = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText;
const actualRangeValue = parent.querySelector(TABLE_BODY_FIRST_ROW_THIRD_DATA).innerText; const actualRangeValue = parent.querySelector(TABLE_BODY_FIRST_ROW_THIRD_DATA).innerText;
expect(actualRangeValue).toBe(rangeValue); expect(actualRangeValue).toBe(rangeValue);
@ -424,7 +424,7 @@ describe('The LAD Table Set', () => {
ladTableSetView = ladTableSetViewProvider.view(mockObj.ladTableSet, [mockObj.ladTableSet]); ladTableSetView = ladTableSetViewProvider.view(mockObj.ladTableSet, [mockObj.ladTableSet]);
ladTableSetView.show(child); ladTableSetView.show(child);
return Vue.nextTick(); return nextTick();
}); });
it('should show one row per lad table object in the composition', () => { it('should show one row per lad table object in the composition', () => {

View File

@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
import { createOpenMct, resetApplicationState, spyOnBuiltins } from 'utils/testing'; import { createOpenMct, resetApplicationState, spyOnBuiltins } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import AutoflowTabularConstants from './AutoflowTabularConstants'; import AutoflowTabularConstants from './AutoflowTabularConstants';
import AutoflowTabularPlugin from './AutoflowTabularPlugin'; import AutoflowTabularPlugin from './AutoflowTabularPlugin';
@ -175,7 +175,7 @@ xdescribe('AutoflowTabularPlugin', () => {
view = provider.view(testObject, [testObject]); view = provider.view(testObject, [testObject]);
view.show(testContainer); view.show(testContainer);
return Vue.nextTick(); return nextTick();
}); });
afterEach(() => { afterEach(() => {

View File

@ -23,7 +23,7 @@
// import BarGraph from './BarGraphPlot.vue'; // import BarGraph from './BarGraphPlot.vue';
import EventEmitter from 'EventEmitter'; import EventEmitter from 'EventEmitter';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import { BAR_GRAPH_INSPECTOR_KEY, BAR_GRAPH_KEY, BAR_GRAPH_VIEW } from './BarGraphConstants'; import { BAR_GRAPH_INSPECTOR_KEY, BAR_GRAPH_KEY, BAR_GRAPH_VIEW } from './BarGraphConstants';
import BarGraphPlugin from './plugin'; import BarGraphPlugin from './plugin';
@ -153,7 +153,7 @@ describe('the plugin', function () {
spyOn(openmct.composition, 'get').and.returnValue(mockComposition); spyOn(openmct.composition, 'get').and.returnValue(mockComposition);
await Vue.nextTick(); await nextTick();
}); });
it('provides a bar graph view', () => { it('provides a bar graph view', () => {
@ -254,7 +254,7 @@ describe('the plugin', function () {
spyOn(openmct.composition, 'get').and.returnValue(mockComposition); spyOn(openmct.composition, 'get').and.returnValue(mockComposition);
await Vue.nextTick(); await nextTick();
}); });
it('Renders spectral plots', async () => { it('Renders spectral plots', async () => {
@ -305,8 +305,8 @@ describe('the plugin', function () {
barGraphView.show(child, true); barGraphView.show(child, true);
mockComposition.emit('add', dotFullTelemetryObject); mockComposition.emit('add', dotFullTelemetryObject);
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const plotElement = element.querySelector('.cartesianlayer .scatterlayer .trace .lines'); const plotElement = element.querySelector('.cartesianlayer .scatterlayer .trace .lines');
expect(plotElement).not.toBeNull(); expect(plotElement).not.toBeNull();
@ -581,7 +581,7 @@ describe('the plugin', function () {
plotInspectorView = applicableViews.filter((view) => view.key === BAR_GRAPH_INSPECTOR_KEY)[0]; plotInspectorView = applicableViews.filter((view) => view.key === BAR_GRAPH_INSPECTOR_KEY)[0];
plotInspectorView.show(viewContainer); plotInspectorView.show(viewContainer);
await Vue.nextTick(); await nextTick();
optionsElement = element.querySelector('.c-bar-graph-options'); optionsElement = element.querySelector('.c-bar-graph-options');
}); });

View File

@ -22,7 +22,7 @@
import EventEmitter from 'EventEmitter'; import EventEmitter from 'EventEmitter';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import ScatterPlotPlugin from './plugin'; import ScatterPlotPlugin from './plugin';
import { SCATTER_PLOT_KEY, SCATTER_PLOT_VIEW } from './scatterPlotConstants'; import { SCATTER_PLOT_KEY, SCATTER_PLOT_VIEW } from './scatterPlotConstants';
@ -178,7 +178,7 @@ describe('the plugin', function () {
spyOn(openmct.composition, 'get').and.returnValue(mockComposition); spyOn(openmct.composition, 'get').and.returnValue(mockComposition);
await Vue.nextTick(); await nextTick();
}); });
it('provides a scatter plot view', () => { it('provides a scatter plot view', () => {
@ -406,7 +406,7 @@ describe('the plugin', function () {
plotInspectorView = applicableViews[0]; plotInspectorView = applicableViews[0];
plotInspectorView.show(viewContainer); plotInspectorView.show(viewContainer);
await Vue.nextTick(); await nextTick();
optionsElement = element.querySelector('.c-scatter-plot-options'); optionsElement = element.querySelector('.c-scatter-plot-options');
}); });

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing'; import { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import ClearDataPlugin from './plugin.js'; import ClearDataPlugin from './plugin.js';
@ -213,7 +213,7 @@ describe('The Clear Data Plugin:', () => {
}); });
it('renders its major elements', async () => { it('renders its major elements', async () => {
await Vue.nextTick(); await nextTick();
const indicatorClass = appHolder.querySelector('.c-indicator'); const indicatorClass = appHolder.querySelector('.c-indicator');
const iconClass = appHolder.querySelector('.icon-clear-data'); const iconClass = appHolder.querySelector('.icon-clear-data');
const indicatorLabel = appHolder.querySelector('.c-indicator__label'); const indicatorLabel = appHolder.querySelector('.c-indicator__label');

View File

@ -22,7 +22,7 @@
import EventEmitter from 'EventEmitter'; import EventEmitter from 'EventEmitter';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import clockPlugin from './plugin'; import clockPlugin from './plugin';
@ -106,7 +106,7 @@ describe('Clock plugin:', () => {
clockView = clockViewProvider.view(mutableClockObject); clockView = clockViewProvider.view(mutableClockObject);
clockView.show(child); clockView.show(child);
await Vue.nextTick(); await nextTick();
await new Promise((resolve) => requestAnimationFrame(resolve)); await new Promise((resolve) => requestAnimationFrame(resolve));
}); });
@ -232,7 +232,7 @@ describe('Clock plugin:', () => {
it('contains text', async () => { it('contains text', async () => {
await setupClock(true); await setupClock(true);
await Vue.nextTick(); await nextTick();
await new Promise((resolve) => requestAnimationFrame(resolve)); await new Promise((resolve) => requestAnimationFrame(resolve));
clockIndicator = openmct.indicators.indicatorObjects.find( clockIndicator = openmct.indicators.indicatorObjects.find(

View File

@ -78,6 +78,7 @@
<!-- Save Styles --> <!-- Save Styles -->
<toolbar-button <toolbar-button
v-if="canSaveStyle" v-if="canSaveStyle"
ref="saveStyleButton"
class="c-style__toolbar-button--save c-local-controls--show-on-hover c-icon-button c-icon-button--major" class="c-style__toolbar-button--save c-local-controls--show-on-hover c-icon-button c-icon-button--major"
:options="saveOptions" :options="saveOptions"
@click="saveItemStyle()" @click="saveItemStyle()"

View File

@ -38,6 +38,7 @@
<div class="c-inspect-styles__content"> <div class="c-inspect-styles__content">
<div v-if="staticStyle" class="c-inspect-styles__style"> <div v-if="staticStyle" class="c-inspect-styles__style">
<StyleEditor <StyleEditor
ref="styleEditor"
class="c-inspect-styles__editor" class="c-inspect-styles__editor"
:style-item="staticStyle" :style-item="staticStyle"
:is-editing="allowEditing" :is-editing="allowEditing"

View File

@ -20,8 +20,9 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
import mount from 'utils/mount';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import ConditionManager from '@/plugins/condition/ConditionManager'; import ConditionManager from '@/plugins/condition/ConditionManager';
@ -142,6 +143,7 @@ describe('the plugin', function () {
let conditionWidgetItem; let conditionWidgetItem;
let selection; let selection;
let component; let component;
let _destroy;
let styleViewComponentObject; let styleViewComponentObject;
const conditionSetDomainObject = { const conditionSetDomainObject = {
configuration: { configuration: {
@ -238,8 +240,7 @@ describe('the plugin', function () {
]; ];
let viewContainer = document.createElement('div'); let viewContainer = document.createElement('div');
child.append(viewContainer); child.append(viewContainer);
component = new Vue({ const { vNode, destroy } = mount({
el: viewContainer,
components: { components: {
StylesView StylesView
}, },
@ -248,17 +249,20 @@ describe('the plugin', function () {
selection: selection, selection: selection,
stylesManager stylesManager
}, },
template: '<styles-view/>' template: '<styles-view ref="root"/>'
}); });
return Vue.nextTick().then(() => { component = vNode.componentInstance;
styleViewComponentObject = component.$root.$children[0]; _destroy = destroy;
return nextTick().then(() => {
styleViewComponentObject = component.$refs.root;
styleViewComponentObject.setEditState(true); styleViewComponentObject.setEditState(true);
}); });
}); });
afterEach(() => { afterEach(() => {
component.$destroy(); _destroy();
}); });
it('does not include the output label when the flag is disabled', () => { it('does not include the output label when the flag is disabled', () => {
@ -267,7 +271,7 @@ describe('the plugin', function () {
styleViewComponentObject.initializeConditionalStyles(); styleViewComponentObject.initializeConditionalStyles();
expect(styleViewComponentObject.conditionalStyles.length).toBe(2); expect(styleViewComponentObject.conditionalStyles.length).toBe(2);
return Vue.nextTick().then(() => { return nextTick().then(() => {
const hasNoOutput = const hasNoOutput =
styleViewComponentObject.domainObject.configuration.objectStyles.styles.every((style) => { styleViewComponentObject.domainObject.configuration.objectStyles.styles.every((style) => {
return style.style.output === '' || style.style.output === undefined; return style.style.output === '' || style.style.output === undefined;
@ -286,7 +290,7 @@ describe('the plugin', function () {
styleViewComponentObject.useConditionSetOutputAsLabel = true; styleViewComponentObject.useConditionSetOutputAsLabel = true;
styleViewComponentObject.persistLabelConfiguration(); styleViewComponentObject.persistLabelConfiguration();
return Vue.nextTick().then(() => { return nextTick().then(() => {
const outputs = styleViewComponentObject.domainObject.configuration.objectStyles.styles.map( const outputs = styleViewComponentObject.domainObject.configuration.objectStyles.styles.map(
(style) => { (style) => {
return style.style.output; return style.style.output;
@ -306,6 +310,7 @@ describe('the plugin', function () {
let selection; let selection;
let component; let component;
let styleViewComponentObject; let styleViewComponentObject;
let _destroy;
const conditionSetDomainObject = { const conditionSetDomainObject = {
configuration: { configuration: {
conditionTestData: [ conditionTestData: [
@ -560,8 +565,7 @@ describe('the plugin', function () {
]; ];
let viewContainer = document.createElement('div'); let viewContainer = document.createElement('div');
child.append(viewContainer); child.append(viewContainer);
component = new Vue({ const { vNode, destroy } = mount({
el: viewContainer,
components: { components: {
StylesView StylesView
}, },
@ -570,15 +574,22 @@ describe('the plugin', function () {
selection: selection, selection: selection,
stylesManager stylesManager
}, },
template: '<styles-view/>' template: '<styles-view ref="root"/>'
}); });
return Vue.nextTick().then(() => { component = vNode.componentInstance;
styleViewComponentObject = component.$root.$children[0]; _destroy = destroy;
return nextTick().then(() => {
styleViewComponentObject = component.$refs.root;
styleViewComponentObject.setEditState(true); styleViewComponentObject.setEditState(true);
}); });
}); });
afterEach(() => {
_destroy();
});
it('initializes the items in the view', () => { it('initializes the items in the view', () => {
expect(styleViewComponentObject.items.length).toBe(3); expect(styleViewComponentObject.items.length).toBe(3);
}); });
@ -597,7 +608,7 @@ describe('the plugin', function () {
expect(styleViewComponentObject.conditionalStyles.length).toBe(2); expect(styleViewComponentObject.conditionalStyles.length).toBe(2);
styleViewComponentObject.updateConditionalStyle(conditionalStyle, 'border'); styleViewComponentObject.updateConditionalStyle(conditionalStyle, 'border');
return Vue.nextTick().then(() => { return nextTick().then(() => {
expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined(); expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined();
[boxLayoutItem, lineLayoutItem, notCreatableObjectItem].forEach((item) => { [boxLayoutItem, lineLayoutItem, notCreatableObjectItem].forEach((item) => {
const itemStyles = const itemStyles =
@ -627,7 +638,7 @@ describe('the plugin', function () {
it('updates applicable static styles', () => { it('updates applicable static styles', () => {
styleViewComponentObject.updateStaticStyle(staticStyle, 'border'); styleViewComponentObject.updateStaticStyle(staticStyle, 'border');
return Vue.nextTick().then(() => { return nextTick().then(() => {
expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined(); expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined();
[boxLayoutItem, lineLayoutItem, notCreatableObjectItem].forEach((item) => { [boxLayoutItem, lineLayoutItem, notCreatableObjectItem].forEach((item) => {
const itemStyle = const itemStyle =

View File

@ -1,5 +1,5 @@
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import ConditionWidgetPlugin from './plugin'; import ConditionWidgetPlugin from './plugin';
@ -148,7 +148,7 @@ describe('the plugin', function () {
let view = conditionWidgetView.view(testViewObject, element); let view = conditionWidgetView.view(testViewObject, element);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
it('provides a view', () => { it('provides a view', () => {
@ -184,7 +184,7 @@ describe('the plugin', function () {
); );
conditionWidgetView.show(urlChild); conditionWidgetView.show(urlChild);
await Vue.nextTick(); await nextTick();
const domainUrl = mockConditionObject[CONDITION_WIDGET_KEY].url; const domainUrl = mockConditionObject[CONDITION_WIDGET_KEY].url;
expect(urlParent.innerHTML).toContain( expect(urlParent.innerHTML).toContain(

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import DisplayLayoutPlugin from './plugin'; import DisplayLayoutPlugin from './plugin';
@ -163,7 +163,7 @@ describe('the plugin', function () {
const view = displayLayoutViewProvider.view(displayLayoutItem, displayLayoutItem); const view = displayLayoutViewProvider.view(displayLayoutItem, displayLayoutItem);
view.show(child, false); view.show(child, false);
Vue.nextTick(done); nextTick(done);
}); });
it('will sync composition and layout items', () => { it('will sync composition and layout items', () => {

View File

@ -155,11 +155,7 @@ export default {
mutateFilters = true; mutateFilters = true;
} }
this.$set( this.persistedFilters[keyString][metadatum.key] = this.globalFilters[metadatum.key];
this.persistedFilters[keyString],
metadatum.key,
this.globalFilters[metadatum.key]
);
} }
}); });
} }

View File

@ -22,7 +22,7 @@
import EventEmitter from 'EventEmitter'; import EventEmitter from 'EventEmitter';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import FlexibleLayout from './plugin'; import FlexibleLayout from './plugin';
@ -105,7 +105,7 @@ describe('the plugin', function () {
const flexibleView = flexibleLayoutViewProvider.view(testViewObject, [testViewObject]); const flexibleView = flexibleLayoutViewProvider.view(testViewObject, [testViewObject]);
flexibleView.show(child, false); flexibleView.show(child, false);
await Vue.nextTick(); await nextTick();
console.log(child); console.log(child);
const flexTitle = child.querySelector('.c-fl'); const flexTitle = child.querySelector('.c-fl');

View File

@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import FolderPlugin from './plugin.js'; import FolderPlugin from './plugin.js';
@ -132,7 +132,7 @@ describe('The folder plugin', () => {
let folderView = gridViewProvider.view(folderObject, [folderObject]); let folderView = gridViewProvider.view(folderObject, [folderObject]);
folderView.show(childDiv, true); folderView.show(childDiv, true);
await Vue.nextTick(); await nextTick();
let children = parentDiv.getElementsByClassName('js-folder-child'); let children = parentDiv.getElementsByClassName('js-folder-child');
expect(children.length).toBe(folderObject.composition.length); expect(children.length).toBe(folderObject.composition.length);
@ -147,7 +147,7 @@ describe('The folder plugin', () => {
let folderView = listViewProvider.view(folderObject, [folderObject]); let folderView = listViewProvider.view(folderObject, [folderObject]);
folderView.show(childDiv, true); folderView.show(childDiv, true);
await Vue.nextTick(); await nextTick();
let children = parentDiv.getElementsByClassName('js-folder-child'); let children = parentDiv.getElementsByClassName('js-folder-child');
expect(children.length).toBe(folderObject.composition.length); expect(children.length).toBe(folderObject.composition.length);

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing'; import { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
describe('EditPropertiesAction plugin', () => { describe('EditPropertiesAction plugin', () => {
let editPropertiesAction; let editPropertiesAction;
@ -106,7 +106,7 @@ describe('EditPropertiesAction plugin', () => {
done(); done();
}); });
Vue.nextTick(() => { nextTick(() => {
const form = document.querySelector('.js-form'); const form = document.querySelector('.js-form');
const title = form.querySelector('input'); const title = form.querySelector('input');
expect(title.value).toEqual(domainObject.name); expect(title.value).toEqual(domainObject.name);
@ -153,7 +153,7 @@ describe('EditPropertiesAction plugin', () => {
editPropertiesAction.invoke([domainObject]); editPropertiesAction.invoke([domainObject]);
Vue.nextTick(() => { nextTick(() => {
const form = document.querySelector('.js-form'); const form = document.querySelector('.js-form');
const title = form.querySelector('input'); const title = form.querySelector('input');
const notes = form.querySelector('textArea'); const notes = form.querySelector('textArea');

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
let gaugeDomainObject = { let gaugeDomainObject = {
identifier: { identifier: {
@ -174,7 +174,7 @@ describe('Gauge plugin', () => {
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]); gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
gaugeView.show(child); gaugeView.show(child);
return Vue.nextTick(); return nextTick();
}); });
}); });
@ -221,7 +221,7 @@ describe('Gauge plugin', () => {
} }
const debouncedWatchUpdate = debounce(WatchUpdateValue, 200); const debouncedWatchUpdate = debounce(WatchUpdateValue, 200);
Vue.nextTick(debouncedWatchUpdate); nextTick(debouncedWatchUpdate);
}); });
}); });
@ -316,7 +316,7 @@ describe('Gauge plugin', () => {
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]); gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
gaugeView.show(child); gaugeView.show(child);
return Vue.nextTick(); return nextTick();
}); });
}); });
@ -363,7 +363,7 @@ describe('Gauge plugin', () => {
} }
const debouncedWatchUpdate = debounce(WatchUpdateValue, 200); const debouncedWatchUpdate = debounce(WatchUpdateValue, 200);
Vue.nextTick(debouncedWatchUpdate); nextTick(debouncedWatchUpdate);
}); });
}); });
@ -458,7 +458,7 @@ describe('Gauge plugin', () => {
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]); gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
gaugeView.show(child); gaugeView.show(child);
return Vue.nextTick(); return nextTick();
}); });
}); });
@ -505,7 +505,7 @@ describe('Gauge plugin', () => {
} }
const debouncedWatchUpdate = debounce(WatchUpdateValue, 200); const debouncedWatchUpdate = debounce(WatchUpdateValue, 200);
Vue.nextTick(debouncedWatchUpdate); nextTick(debouncedWatchUpdate);
}); });
}); });
@ -562,7 +562,7 @@ describe('Gauge plugin', () => {
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]); gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
gaugeView.show(child); gaugeView.show(child);
return Vue.nextTick(); return nextTick();
}); });
}); });
@ -645,7 +645,7 @@ describe('Gauge plugin', () => {
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]); gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
gaugeView.show(child); gaugeView.show(child);
return Vue.nextTick(); return nextTick();
}); });
}); });
@ -773,7 +773,7 @@ describe('Gauge plugin', () => {
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]); gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
gaugeView.show(child); gaugeView.show(child);
return Vue.nextTick(); return nextTick();
}); });
}); });
@ -821,7 +821,7 @@ describe('Gauge plugin', () => {
} }
const debouncedWatchUpdate = debounce(WatchUpdateValue, 200); const debouncedWatchUpdate = debounce(WatchUpdateValue, 200);
Vue.nextTick(debouncedWatchUpdate); nextTick(debouncedWatchUpdate);
}); });
}); });
}); });

View File

@ -65,7 +65,7 @@ export default function ImageryTimestripViewProvider(openmct) {
domainObject: domainObject, domainObject: domainObject,
objectPath: objectPath objectPath: objectPath
}, },
template: '<imagery-time-view></imagery-time-view>' template: '<imagery-time-view ref="root"></imagery-time-view>'
}, },
{ {
app: openmct.app, app: openmct.app,

View File

@ -19,7 +19,7 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
import Vue from 'vue'; import mount from 'utils/mount';
import Compass from './CompassComponent.vue'; import Compass from './CompassComponent.vue';
@ -27,7 +27,7 @@ const COMPASS_ROSE_CLASS = '.c-direction-rose';
const COMPASS_HUD_CLASS = '.c-compass__hud'; const COMPASS_HUD_CLASS = '.c-compass__hud';
describe('The Compass component', () => { describe('The Compass component', () => {
let app; let _destroy;
let instance; let instance;
beforeEach(() => { beforeEach(() => {
@ -55,7 +55,7 @@ describe('The Compass component', () => {
} }
}; };
app = new Vue({ const { vNode, destroy } = mount({
components: { Compass }, components: { Compass },
data() { data() {
return propsData; return propsData;
@ -66,11 +66,12 @@ describe('The Compass component', () => {
:sized-image-dimensions="sizedImageDimensions" :sized-image-dimensions="sizedImageDimensions"
/>` />`
}); });
instance = app.$mount(); _destroy = destroy;
instance = vNode.componentInstance;
}); });
afterAll(() => { afterAll(() => {
app.$destroy(); _destroy();
}); });
describe('when a heading value and cameraAngleOfView exists on the image', () => { describe('when a heading value and cameraAngleOfView exists on the image', () => {

View File

@ -26,9 +26,7 @@ import {
resetApplicationState, resetApplicationState,
simulateKeyEvent simulateKeyEvent
} from 'utils/testing'; } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import ClearDataPlugin from '../clearData/plugin';
const ONE_MINUTE = 1000 * 60; const ONE_MINUTE = 1000 * 60;
const TEN_MINUTES = ONE_MINUTE * 10; const TEN_MINUTES = ONE_MINUTE * 10;
@ -319,63 +317,6 @@ describe('The Imagery View Layouts', () => {
expect(imageryView).toBeDefined(); expect(imageryView).toBeDefined();
}); });
describe('Clear data action for imagery', () => {
let applicableViews;
let imageryViewProvider;
let imageryView;
let componentView;
let clearDataPlugin;
let clearDataAction;
beforeEach(() => {
openmct.time.timeSystem('utc', {
start: START - 5 * ONE_MINUTE,
end: START + 5 * ONE_MINUTE
});
applicableViews = openmct.objectViews.get(imageryObject, [imageryObject]);
imageryViewProvider = applicableViews.find((viewProvider) => viewProvider.key === imageryKey);
imageryView = imageryViewProvider.view(imageryObject, [imageryObject]);
imageryView.show(child);
componentView = imageryView._getInstance().$children[0];
clearDataPlugin = new ClearDataPlugin(['example.imagery'], { indicator: true });
openmct.install(clearDataPlugin);
clearDataAction = openmct.actions.getAction('clear-data-action');
return Vue.nextTick();
});
it('clear data action is installed', () => {
expect(clearDataAction).toBeDefined();
});
it('on clearData action should clear data for object is selected', (done) => {
// force show the thumbnails
componentView.forceShowThumbnails = true;
Vue.nextTick(() => {
let clearDataResolve;
let telemetryRequestPromise = new Promise((resolve) => {
clearDataResolve = resolve;
});
expect(parent.querySelectorAll('.c-imagery__thumb').length).not.toBe(0);
openmct.objectViews.on('clearData', (_domainObject) => {
return Vue.nextTick(() => {
expect(parent.querySelectorAll('.c-imagery__thumb').length).toBe(0);
clearDataResolve();
});
});
clearDataAction.invoke(imageryObject);
telemetryRequestPromise.then(() => {
done();
});
});
});
});
describe('imagery view', () => { describe('imagery view', () => {
let applicableViews; let applicableViews;
let imageryViewProvider; let imageryViewProvider;
@ -392,54 +333,35 @@ describe('The Imagery View Layouts', () => {
imageryView = imageryViewProvider.view(imageryObject, [imageryObject]); imageryView = imageryViewProvider.view(imageryObject, [imageryObject]);
imageryView.show(child); imageryView.show(child);
imageryView._getInstance().$children[0].forceShowThumbnails = true; imageryView._getInstance().$refs.ImageryContainer.forceShowThumbnails = true;
return Vue.nextTick(); return nextTick();
}); });
it('on mount should show the the most recent image', async () => { it('on mount should show the the most recent image', async () => {
//Looks like we need Vue.nextTick here so that computed properties settle down //Looks like we need nextTick here so that computed properties settle down
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const imageInfo = getImageInfo(parent); const imageInfo = getImageInfo(parent);
expect(imageInfo.url.indexOf(imageTelemetry[COUNT - 1].timeId)).not.toEqual(-1); expect(imageInfo.url.indexOf(imageTelemetry[COUNT - 1].timeId)).not.toEqual(-1);
}); });
it('on mount should show any image layers', async () => { it('on mount should show any image layers', async () => {
//Looks like we need Vue.nextTick here so that computed properties settle down //Looks like we need nextTick here so that computed properties settle down
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const layerEls = parent.querySelectorAll('.js-layer-image'); const layerEls = parent.querySelectorAll('.js-layer-image');
expect(layerEls.length).toEqual(1); expect(layerEls.length).toEqual(1);
}); });
it('should use the image thumbnailUrl for thumbnails', async () => {
await Vue.nextTick();
await Vue.nextTick();
const fullSizeImageUrl = imageTelemetry[5].url;
const thumbnailUrl = formatThumbnail(imageTelemetry[5].url);
// Ensure thumbnails are shown w/ thumbnail Urls
const thumbnails = parent.querySelectorAll(`img[src='${thumbnailUrl}']`);
expect(thumbnails.length).toBeGreaterThan(0);
// Click a thumbnail
parent.querySelectorAll(`img[src='${thumbnailUrl}']`)[0].click();
await Vue.nextTick();
// Ensure full size image is shown w/ full size url
const fullSizeImages = parent.querySelectorAll(`img[src='${fullSizeImageUrl}']`);
expect(fullSizeImages.length).toBeGreaterThan(0);
});
it('should show the clicked thumbnail as the main image', async () => { it('should show the clicked thumbnail as the main image', async () => {
//Looks like we need Vue.nextTick here so that computed properties settle down //Looks like we need nextTick here so that computed properties settle down
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const thumbnailUrl = formatThumbnail(imageTelemetry[5].url); const thumbnailUrl = formatThumbnail(imageTelemetry[5].url);
parent.querySelectorAll(`img[src='${thumbnailUrl}']`)[0].click(); parent.querySelectorAll(`img[src='${thumbnailUrl}']`)[0].click();
await Vue.nextTick(); await nextTick();
const imageInfo = getImageInfo(parent); const imageInfo = getImageInfo(parent);
expect(imageInfo.url.indexOf(imageTelemetry[5].timeId)).not.toEqual(-1); expect(imageInfo.url.indexOf(imageTelemetry[5].timeId)).not.toEqual(-1);
@ -451,7 +373,7 @@ describe('The Imagery View Layouts', () => {
end: 1000 end: 1000
}); });
Vue.nextTick(() => { nextTick(() => {
// used in code, need to wait to the 500ms here too // used in code, need to wait to the 500ms here too
setTimeout(() => { setTimeout(() => {
const imageIsNew = isNew(parent); const imageIsNew = isNew(parent);
@ -462,20 +384,20 @@ describe('The Imagery View Layouts', () => {
}); });
it('should show that an image is not new', async () => { it('should show that an image is not new', async () => {
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const target = formatThumbnail(imageTelemetry[4].url); const target = formatThumbnail(imageTelemetry[4].url);
parent.querySelectorAll(`img[src='${target}']`)[0].click(); parent.querySelectorAll(`img[src='${target}']`)[0].click();
await Vue.nextTick(); await nextTick();
const imageIsNew = isNew(parent); const imageIsNew = isNew(parent);
expect(imageIsNew).toBeFalse(); expect(imageIsNew).toBeFalse();
}); });
it('should navigate via arrow keys', async () => { it('should navigate via arrow keys', async () => {
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const keyOpts = { const keyOpts = {
element: parent.querySelector('.c-imagery'), element: parent.querySelector('.c-imagery'),
key: 'ArrowLeft', key: 'ArrowLeft',
@ -485,14 +407,14 @@ describe('The Imagery View Layouts', () => {
simulateKeyEvent(keyOpts); simulateKeyEvent(keyOpts);
await Vue.nextTick(); await nextTick();
const imageInfo = getImageInfo(parent); const imageInfo = getImageInfo(parent);
expect(imageInfo.url.indexOf(imageTelemetry[COUNT - 2].timeId)).not.toEqual(-1); expect(imageInfo.url.indexOf(imageTelemetry[COUNT - 2].timeId)).not.toEqual(-1);
}); });
it('should navigate via numerous arrow keys', async () => { it('should navigate via numerous arrow keys', async () => {
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const element = parent.querySelector('.c-imagery'); const element = parent.querySelector('.c-imagery');
const type = 'keyup'; const type = 'keyup';
const leftKeyOpts = { const leftKeyOpts = {
@ -515,15 +437,15 @@ describe('The Imagery View Layouts', () => {
// right once // right once
simulateKeyEvent(rightKeyOpts); simulateKeyEvent(rightKeyOpts);
await Vue.nextTick(); await nextTick();
const imageInfo = getImageInfo(parent); const imageInfo = getImageInfo(parent);
expect(imageInfo.url.indexOf(imageTelemetry[COUNT - 3].timeId)).not.toEqual(-1); expect(imageInfo.url.indexOf(imageTelemetry[COUNT - 3].timeId)).not.toEqual(-1);
}); });
it('shows an auto scroll button when scroll to left', (done) => { it('shows an auto scroll button when scroll to left', (done) => {
Vue.nextTick(() => { nextTick(() => {
// to mock what a scroll would do // to mock what a scroll would do
imageryView._getInstance().$refs.ImageryContainer.autoScroll = false; imageryView._getInstance().$refs.ImageryContainer.autoScroll = false;
Vue.nextTick(() => { nextTick(() => {
let autoScrollButton = parent.querySelector('.c-imagery__auto-scroll-resume-button'); let autoScrollButton = parent.querySelector('.c-imagery__auto-scroll-resume-button');
expect(autoScrollButton).toBeTruthy(); expect(autoScrollButton).toBeTruthy();
done(); done();
@ -531,16 +453,16 @@ describe('The Imagery View Layouts', () => {
}); });
}); });
it('scrollToRight is called when clicking on auto scroll button', async () => { it('scrollToRight is called when clicking on auto scroll button', async () => {
await Vue.nextTick(); await nextTick();
// use spyon to spy the scroll function // use spyon to spy the scroll function
spyOn(imageryView._getInstance().$refs.ImageryContainer, 'scrollHandler'); spyOn(imageryView._getInstance().$refs.ImageryContainer, 'scrollHandler');
imageryView._getInstance().$refs.ImageryContainer.autoScroll = false; imageryView._getInstance().$refs.ImageryContainer.autoScroll = false;
await Vue.nextTick(); await nextTick();
parent.querySelector('.c-imagery__auto-scroll-resume-button').click(); parent.querySelector('.c-imagery__auto-scroll-resume-button').click();
expect(imageryView._getInstance().$refs.ImageryContainer.scrollHandler); expect(imageryView._getInstance().$refs.ImageryContainer.scrollHandler);
}); });
xit('should change the image zoom factor when using the zoom buttons', async () => { xit('should change the image zoom factor when using the zoom buttons', async () => {
await Vue.nextTick(); await nextTick();
let imageSizeBefore; let imageSizeBefore;
let imageSizeAfter; let imageSizeAfter;
@ -549,7 +471,7 @@ describe('The Imagery View Layouts', () => {
.querySelector('.c-imagery_main-image_background-image') .querySelector('.c-imagery_main-image_background-image')
.getBoundingClientRect(); .getBoundingClientRect();
parent.querySelector('.t-btn-zoom-in').click(); parent.querySelector('.t-btn-zoom-in').click();
await Vue.nextTick(); await nextTick();
imageSizeAfter = parent imageSizeAfter = parent
.querySelector('.c-imagery_main-image_background-image') .querySelector('.c-imagery_main-image_background-image')
.getBoundingClientRect(); .getBoundingClientRect();
@ -560,7 +482,7 @@ describe('The Imagery View Layouts', () => {
.querySelector('.c-imagery_main-image_background-image') .querySelector('.c-imagery_main-image_background-image')
.getBoundingClientRect(); .getBoundingClientRect();
parent.querySelector('.t-btn-zoom-out').click(); parent.querySelector('.t-btn-zoom-out').click();
await Vue.nextTick(); await nextTick();
imageSizeAfter = parent imageSizeAfter = parent
.querySelector('.c-imagery_main-image_background-image') .querySelector('.c-imagery_main-image_background-image')
.getBoundingClientRect(); .getBoundingClientRect();
@ -568,15 +490,15 @@ describe('The Imagery View Layouts', () => {
expect(imageSizeAfter.width).toBeLessThan(imageSizeBefore.width); expect(imageSizeAfter.width).toBeLessThan(imageSizeBefore.width);
}); });
xit('should reset the zoom factor on the image when clicking the zoom button', async (done) => { xit('should reset the zoom factor on the image when clicking the zoom button', async (done) => {
await Vue.nextTick(); await nextTick();
// test clicking the zoom reset button // test clicking the zoom reset button
// zoom in to scale up the image dimensions // zoom in to scale up the image dimensions
parent.querySelector('.t-btn-zoom-in').click(); parent.querySelector('.t-btn-zoom-in').click();
await Vue.nextTick(); await nextTick();
let imageSizeBefore = parent let imageSizeBefore = parent
.querySelector('.c-imagery_main-image_background-image') .querySelector('.c-imagery_main-image_background-image')
.getBoundingClientRect(); .getBoundingClientRect();
await Vue.nextTick(); await nextTick();
parent.querySelector('.t-btn-zoom-reset').click(); parent.querySelector('.t-btn-zoom-reset').click();
let imageSizeAfter = parent let imageSizeAfter = parent
.querySelector('.c-imagery_main-image_background-image') .querySelector('.c-imagery_main-image_background-image')
@ -587,22 +509,22 @@ describe('The Imagery View Layouts', () => {
}); });
it('should display the viewable area when zoom factor is greater than 1', async () => { it('should display the viewable area when zoom factor is greater than 1', async () => {
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
expect(parent.querySelectorAll('.c-thumb__viewable-area').length).toBe(0); expect(parent.querySelectorAll('.c-thumb__viewable-area').length).toBe(0);
parent.querySelector('.t-btn-zoom-in').click(); parent.querySelector('.t-btn-zoom-in').click();
await Vue.nextTick(); await nextTick();
expect(parent.querySelectorAll('.c-thumb__viewable-area').length).toBe(1); expect(parent.querySelectorAll('.c-thumb__viewable-area').length).toBe(1);
parent.querySelector('.t-btn-zoom-reset').click(); parent.querySelector('.t-btn-zoom-reset').click();
await Vue.nextTick(); await nextTick();
expect(parent.querySelectorAll('.c-thumb__viewable-area').length).toBe(0); expect(parent.querySelectorAll('.c-thumb__viewable-area').length).toBe(0);
}); });
it('should reset the brightness and contrast when clicking the reset button', async () => { it('should reset the brightness and contrast when clicking the reset button', async () => {
const viewInstance = imageryView._getInstance(); const viewInstance = imageryView._getInstance();
await Vue.nextTick(); await nextTick();
// Save the original brightness and contrast values // Save the original brightness and contrast values
const origBrightness = viewInstance.$refs.ImageryContainer.filters.brightness; const origBrightness = viewInstance.$refs.ImageryContainer.filters.brightness;
@ -613,7 +535,7 @@ describe('The Imagery View Layouts', () => {
brightness: 200, brightness: 200,
contrast: 200 contrast: 200
}); });
await Vue.nextTick(); await nextTick();
// Verify that the values actually changed // Verify that the values actually changed
expect(viewInstance.$refs.ImageryContainer.filters.brightness).toBe(200); expect(viewInstance.$refs.ImageryContainer.filters.brightness).toBe(200);
@ -621,7 +543,7 @@ describe('The Imagery View Layouts', () => {
// Click the reset button // Click the reset button
parent.querySelector('.t-btn-reset').click(); parent.querySelector('.t-btn-reset').click();
await Vue.nextTick(); await nextTick();
// Verify that the values were reset // Verify that the values were reset
expect(viewInstance.$refs.ImageryContainer.filters.brightness).toBe(origBrightness); expect(viewInstance.$refs.ImageryContainer.filters.brightness).toBe(origBrightness);
@ -631,8 +553,8 @@ describe('The Imagery View Layouts', () => {
describe('imagery time strip view', () => { describe('imagery time strip view', () => {
let applicableViews; let applicableViews;
let imageryViewProvider; let imageryTimestripViewProvider;
let imageryView; let imageryTimeView;
let componentView; let componentView;
beforeEach(() => { beforeEach(() => {
@ -671,10 +593,10 @@ describe('The Imagery View Layouts', () => {
type: 'time-strip' type: 'time-strip'
} }
]); ]);
imageryViewProvider = applicableViews.find( imageryTimestripViewProvider = applicableViews.find(
(viewProvider) => viewProvider.key === imageryForTimeStripKey (viewProvider) => viewProvider.key === imageryForTimeStripKey
); );
imageryView = imageryViewProvider.view(imageryObject, [ imageryTimeView = imageryTimestripViewProvider.view(imageryObject, [
imageryObject, imageryObject,
{ {
identifier: { identifier: {
@ -684,12 +606,12 @@ describe('The Imagery View Layouts', () => {
type: 'time-strip' type: 'time-strip'
} }
]); ]);
imageryView.show(child); imageryTimeView.show(child);
componentView = imageryView.getComponent().$children[0]; componentView = imageryTimeView.getComponent().$refs.root;
spyOn(componentView.previewAction, 'invoke').and.callThrough(); spyOn(componentView.previewAction, 'invoke').and.callThrough();
return Vue.nextTick(); return nextTick();
}); });
afterEach(() => { afterEach(() => {
@ -697,19 +619,19 @@ describe('The Imagery View Layouts', () => {
}); });
it('on mount should show imagery within the given bounds', async () => { it('on mount should show imagery within the given bounds', async () => {
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper'); const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
expect(imageElements.length).toEqual(5); expect(imageElements.length).toEqual(5);
}); });
it('should show the clicked thumbnail as the preview image', async () => { it('should show the clicked thumbnail as the preview image', async () => {
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const mouseDownEvent = createMouseEvent('mousedown'); const mouseDownEvent = createMouseEvent('mousedown');
let imageWrapper = parent.querySelectorAll(`.c-imagery-tsv__image-wrapper`); let imageWrapper = parent.querySelectorAll(`.c-imagery-tsv__image-wrapper`);
imageWrapper[2].dispatchEvent(mouseDownEvent); imageWrapper[2].dispatchEvent(mouseDownEvent);
await Vue.nextTick(); await nextTick();
const timestamp = imageWrapper[2].id.replace('wrapper-', ''); const timestamp = imageWrapper[2].id.replace('wrapper-', '');
expect(componentView.previewAction.invoke).toHaveBeenCalledWith( expect(componentView.previewAction.invoke).toHaveBeenCalledWith(
[componentView.objectPath[0]], [componentView.objectPath[0]],
@ -722,8 +644,8 @@ describe('The Imagery View Layouts', () => {
it('should remove images when clock advances', async () => { it('should remove images when clock advances', async () => {
openmct.time.tick(ONE_MINUTE * 2); openmct.time.tick(ONE_MINUTE * 2);
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper'); const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
expect(imageElements.length).toEqual(4); expect(imageElements.length).toEqual(4);
}); });
@ -733,8 +655,8 @@ describe('The Imagery View Layouts', () => {
start: START, start: START,
end: START + 5 * ONE_MINUTE end: START + 5 * ONE_MINUTE
}); });
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper'); const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
expect(imageElements.length).toEqual(1); expect(imageElements.length).toEqual(1);
}); });
@ -744,8 +666,8 @@ describe('The Imagery View Layouts', () => {
start: START - 5 * ONE_MINUTE, start: START - 5 * ONE_MINUTE,
end: START - 2 * ONE_MINUTE end: START - 2 * ONE_MINUTE
}); });
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper'); const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
expect(imageElements.length).toEqual(4); expect(imageElements.length).toEqual(4);
}); });
@ -755,8 +677,8 @@ describe('The Imagery View Layouts', () => {
start: START - 2 * ONE_MINUTE, start: START - 2 * ONE_MINUTE,
end: START + 2 * ONE_MINUTE end: START + 2 * ONE_MINUTE
}); });
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper'); const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
expect(imageElements.length).toEqual(3); expect(imageElements.length).toEqual(3);
}); });

View File

@ -410,7 +410,7 @@ export default {
this.manageEmbedLayout(); this.manageEmbedLayout();
this.timestampAndUpdate(); this.timestampAndUpdate();
}, },
convertMarkDownToHtml(text) { convertMarkDownToHtml(text = '') {
let markDownHtml = this.marked.parse(text, { let markDownHtml = this.marked.parse(text, {
breaks: true, breaks: true,
renderer: this.renderer renderer: this.renderer

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing'; import { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import { NotebookPlugin } from './plugin'; import { NotebookPlugin } from './plugin';
@ -189,7 +189,7 @@ describe('Notebook plugin:', () => {
notebookView = notebookViewProvider.view(mutableNotebookObject, [mutableNotebookObject]); notebookView = notebookViewProvider.view(mutableNotebookObject, [mutableNotebookObject]);
notebookView.show(child); notebookView.show(child);
await Vue.nextTick(); await nextTick();
}); });
afterEach(() => { afterEach(() => {
@ -237,7 +237,7 @@ describe('Notebook plugin:', () => {
'Modified entry text'; 'Modified entry text';
objectProviderObserver(objectCloneToSyncFrom); objectProviderObserver(objectCloneToSyncFrom);
return Vue.nextTick().then(() => { return nextTick().then(() => {
expect(getEntryText(0).innerText.trim()).toBe('Modified entry text'); expect(getEntryText(0).innerText.trim()).toBe('Modified entry text');
}); });
}); });
@ -252,7 +252,7 @@ describe('Notebook plugin:', () => {
}); });
objectProviderObserver(objectCloneToSyncFrom); objectProviderObserver(objectCloneToSyncFrom);
return Vue.nextTick().then(() => { return nextTick().then(() => {
expect(allNotebookEntryElements().length).toBe(3); expect(allNotebookEntryElements().length).toBe(3);
}); });
}); });
@ -263,7 +263,7 @@ describe('Notebook plugin:', () => {
entries.splice(0, 1); entries.splice(0, 1);
objectProviderObserver(objectCloneToSyncFrom); objectProviderObserver(objectCloneToSyncFrom);
return Vue.nextTick().then(() => { return nextTick().then(() => {
expect(allNotebookEntryElements().length).toBe(1); expect(allNotebookEntryElements().length).toBe(1);
}); });
}); });
@ -281,7 +281,7 @@ describe('Notebook plugin:', () => {
objectCloneToSyncFrom.configuration.sections[0].pages.push(newPage); objectCloneToSyncFrom.configuration.sections[0].pages.push(newPage);
objectProviderObserver(objectCloneToSyncFrom); objectProviderObserver(objectCloneToSyncFrom);
await Vue.nextTick(); await nextTick();
expect(allNotebookPageElements().length).toBe(3); expect(allNotebookPageElements().length).toBe(3);
}); });
@ -290,7 +290,7 @@ describe('Notebook plugin:', () => {
objectCloneToSyncFrom.configuration.sections[0].pages.splice(0, 1); objectCloneToSyncFrom.configuration.sections[0].pages.splice(0, 1);
objectProviderObserver(objectCloneToSyncFrom); objectProviderObserver(objectCloneToSyncFrom);
await Vue.nextTick(); await nextTick();
expect(allNotebookPageElements().length).toBe(1); expect(allNotebookPageElements().length).toBe(1);
}); });
@ -315,7 +315,7 @@ describe('Notebook plugin:', () => {
objectCloneToSyncFrom.configuration.sections.push(newSection); objectCloneToSyncFrom.configuration.sections.push(newSection);
objectProviderObserver(objectCloneToSyncFrom); objectProviderObserver(objectCloneToSyncFrom);
return Vue.nextTick().then(() => { return nextTick().then(() => {
expect(allNotebookSectionElements().length).toBe(3); expect(allNotebookSectionElements().length).toBe(3);
}); });
}); });
@ -325,7 +325,7 @@ describe('Notebook plugin:', () => {
objectCloneToSyncFrom.configuration.sections.splice(0, 1); objectCloneToSyncFrom.configuration.sections.splice(0, 1);
objectProviderObserver(objectCloneToSyncFrom); objectProviderObserver(objectCloneToSyncFrom);
return Vue.nextTick().then(() => { return nextTick().then(() => {
expect(allNotebookSectionElements().length).toBe(1); expect(allNotebookSectionElements().length).toBe(1);
}); });
}); });
@ -351,7 +351,7 @@ describe('Notebook plugin:', () => {
element.append(snapshotIndicator); element.append(snapshotIndicator);
return Vue.nextTick().then(() => { return nextTick().then(() => {
drawerElement = document.querySelector('.l-shell__drawer'); drawerElement = document.querySelector('.l-shell__drawer');
}); });
}); });

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import NotificationIndicatorPlugin from './plugin.js'; import NotificationIndicatorPlugin from './plugin.js';
@ -58,7 +58,7 @@ describe('the plugin', () => {
beforeEach(() => { beforeEach(() => {
parentElement.append(indicatorElement); parentElement.append(indicatorElement);
return Vue.nextTick(); return nextTick();
}); });
it('notifies the user of the number of notifications', () => { it('notifies the user of the number of notifications', () => {

View File

@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
import { createOpenMct, resetApplicationState, spyOnBuiltins } from 'utils/testing'; import { createOpenMct, resetApplicationState, spyOnBuiltins } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import { CONNECTED, DISCONNECTED, PENDING, UNKNOWN } from './CouchStatusIndicator'; import { CONNECTED, DISCONNECTED, PENDING, UNKNOWN } from './CouchStatusIndicator';
import CouchPlugin from './plugin.js'; import CouchPlugin from './plugin.js';
@ -478,7 +478,7 @@ describe('the view', () => {
namespace: '', namespace: '',
key: 'object-1' key: 'object-1'
}); });
await Vue.nextTick(); await nextTick();
assertCouchIndicatorStatus(CONNECTED); assertCouchIndicatorStatus(CONNECTED);
}); });
@ -490,7 +490,7 @@ describe('the view', () => {
namespace: '', namespace: '',
key: 'object-1' key: 'object-1'
}); });
await Vue.nextTick(); await nextTick();
assertCouchIndicatorStatus(DISCONNECTED); assertCouchIndicatorStatus(DISCONNECTED);
}); });
@ -523,7 +523,7 @@ describe('the view', () => {
// Simulate 'pending' state from worker message // Simulate 'pending' state from worker message
provider.onSharedWorkerMessage(workerMessage); provider.onSharedWorkerMessage(workerMessage);
await Vue.nextTick(); await nextTick();
assertCouchIndicatorStatus(PENDING); assertCouchIndicatorStatus(PENDING);
}); });
@ -556,7 +556,7 @@ describe('the view', () => {
// Simulate 'pending' state from worker message // Simulate 'pending' state from worker message
provider.onSharedWorkerMessage(workerMessage); provider.onSharedWorkerMessage(workerMessage);
await Vue.nextTick(); await nextTick();
assertCouchIndicatorStatus(UNKNOWN); assertCouchIndicatorStatus(UNKNOWN);
}); });

View File

@ -69,11 +69,11 @@ export default {
const label = this.activity[key].label; const label = this.activity[key].label;
const value = String(this.activity[key].value); const value = String(this.activity[key].value);
this.$set(this.timeProperties, this.timeProperties.length, { this.timeProperties[this.timeProperties.length] = {
id: uuid(), id: uuid(),
label, label,
value value
}); };
} }
}); });
} }

View File

@ -20,8 +20,9 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
import mount from 'utils/mount';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import Properties from '../inspectorViews/properties/PropertiesComponent.vue'; import Properties from '../inspectorViews/properties/PropertiesComponent.vue';
import PlanPlugin from '../plan/plugin'; import PlanPlugin from '../plan/plugin';
@ -187,7 +188,7 @@ describe('the plugin', function () {
let view = planView.view(planDomainObject, mockObjectPath); let view = planView.view(planDomainObject, mockObjectPath);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
it('loads activities into the view', () => { it('loads activities into the view', () => {
@ -210,7 +211,7 @@ describe('the plugin', function () {
openmct.time.bounds(bounds); openmct.time.bounds(bounds);
await Vue.nextTick(); await nextTick();
const rectEls = element.querySelectorAll('.c-plan__contents use'); const rectEls = element.querySelectorAll('.c-plan__contents use');
expect(rectEls.length).toEqual(2); expect(rectEls.length).toEqual(2);
const textEls = element.querySelectorAll('.c-plan__contents text'); const textEls = element.querySelectorAll('.c-plan__contents text');
@ -226,7 +227,7 @@ describe('the plugin', function () {
'draft' 'draft'
); );
await Vue.nextTick(); await nextTick();
const statusEl = element.querySelector('.c-plan__contents .is-status--draft'); const statusEl = element.querySelector('.c-plan__contents .is-status--draft');
expect(statusEl).toBeDefined(); expect(statusEl).toBeDefined();
}); });
@ -235,6 +236,7 @@ describe('the plugin', function () {
describe('the plan version', () => { describe('the plan version', () => {
let component; let component;
let componentObject; let componentObject;
let _destroy;
let testPlanObject = { let testPlanObject = {
name: 'Plan', name: 'Plan',
type: 'plan', type: 'plan',
@ -267,27 +269,28 @@ describe('the plugin', function () {
false false
); );
await Vue.nextTick(); await nextTick();
let viewContainer = document.createElement('div'); let viewContainer = document.createElement('div');
child.append(viewContainer); child.append(viewContainer);
component = new Vue({ const { vNode, destroy } = mount({
el: viewContainer,
components: { components: {
Properties Properties
}, },
provide: { provide: {
openmct: openmct openmct: openmct
}, },
template: '<properties/>' template: '<properties ref="root"/>'
}); });
_destroy = destroy;
component = vNode.componentInstance;
}); });
afterEach(() => { afterEach(() => {
component.$destroy(); _destroy();
}); });
it('provides an inspector view with the version information if available', () => { it('provides an inspector view with the version information if available', () => {
componentObject = component.$root.$children[0]; componentObject = component.$refs.root;
const propertiesEls = componentObject.$el.querySelectorAll('.c-inspect-properties__row'); const propertiesEls = componentObject.$el.querySelectorAll('.c-inspect-properties__row');
const found = Array.from(propertiesEls).some((propertyEl) => { const found = Array.from(propertiesEls).some((propertyEl) => {
return ( return (

View File

@ -32,6 +32,7 @@
:model="{ progressPerc: null }" :model="{ progressPerc: null }"
/> />
<mct-plot <mct-plot
ref="mctPlot"
:class="[plotLegendExpandedStateClass, plotLegendPositionClass]" :class="[plotLegendExpandedStateClass, plotLegendPositionClass]"
:init-grid-lines="gridLinesProp" :init-grid-lines="gridLinesProp"
:init-cursor-guide="cursorGuide" :init-cursor-guide="cursorGuide"

View File

@ -28,7 +28,7 @@ import {
resetApplicationState, resetApplicationState,
spyOnBuiltins spyOnBuiltins
} from 'utils/testing'; } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import configStore from './configuration/ConfigStore'; import configStore from './configuration/ConfigStore';
import PlotConfigurationModel from './configuration/PlotConfigurationModel'; import PlotConfigurationModel from './configuration/PlotConfigurationModel';
@ -172,7 +172,7 @@ describe('the plugin', function () {
end: 2 end: 2
}); });
await Vue.nextTick(); await nextTick();
configStore.deleteAll(); configStore.deleteAll();
return resetApplicationState(openmct); return resetApplicationState(openmct);
}); });
@ -374,7 +374,7 @@ describe('the plugin', function () {
plotView = plotViewProvider.view(testTelemetryObject, []); plotView = plotViewProvider.view(testTelemetryObject, []);
plotView.show(child, true); plotView.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
afterEach(() => { afterEach(() => {
@ -386,14 +386,14 @@ describe('the plugin', function () {
}); });
it('Renders a collapsed legend for every telemetry', async () => { it('Renders a collapsed legend for every telemetry', async () => {
await Vue.nextTick(); await nextTick();
let legend = element.querySelectorAll('.plot-wrapper-collapsed-legend .plot-series-name'); let legend = element.querySelectorAll('.plot-wrapper-collapsed-legend .plot-series-name');
expect(legend.length).toBe(1); expect(legend.length).toBe(1);
expect(legend[0].innerHTML).toEqual('Test Object'); expect(legend[0].innerHTML).toEqual('Test Object');
}); });
it('Renders an expanded legend for every telemetry', async () => { it('Renders an expanded legend for every telemetry', async () => {
await Vue.nextTick(); await nextTick();
let legendControl = element.querySelector( let legendControl = element.querySelector(
'.c-plot-legend__view-control.gl-plot-legend__view-control.c-disclosure-triangle' '.c-plot-legend__view-control.gl-plot-legend__view-control.c-disclosure-triangle'
); );
@ -413,7 +413,7 @@ describe('the plugin', function () {
max: 4 max: 4
}); });
Vue.nextTick(() => { nextTick(() => {
let xAxisElement = element.querySelectorAll( let xAxisElement = element.querySelectorAll(
'.gl-plot-axis-area.gl-plot-x .gl-plot-tick-wrapper' '.gl-plot-axis-area.gl-plot-x .gl-plot-tick-wrapper'
); );
@ -427,7 +427,7 @@ describe('the plugin', function () {
}); });
it('Renders Y-axis options for the telemetry object', async () => { it('Renders Y-axis options for the telemetry object', async () => {
await Vue.nextTick(); await nextTick();
let yAxisElement = element.querySelectorAll( let yAxisElement = element.querySelectorAll(
'.gl-plot-axis-area.gl-plot-y .gl-plot-y-label__select' '.gl-plot-axis-area.gl-plot-y .gl-plot-y-label__select'
); );
@ -468,11 +468,11 @@ describe('the plugin', function () {
end: 100 end: 100
}); });
return Vue.nextTick(); return nextTick();
}); });
it('shows the pause controls', (done) => { it('shows the pause controls', (done) => {
Vue.nextTick(() => { nextTick(() => {
let pauseEl = element.querySelectorAll('.c-button-set .icon-pause'); let pauseEl = element.querySelectorAll('.c-button-set .icon-pause');
expect(pauseEl.length).toBe(1); expect(pauseEl.length).toBe(1);
done(); done();
@ -484,7 +484,7 @@ describe('the plugin', function () {
const clickEvent = createMouseEvent('click'); const clickEvent = createMouseEvent('click');
pauseEl.dispatchEvent(clickEvent); pauseEl.dispatchEvent(clickEvent);
Vue.nextTick(() => { nextTick(() => {
let playEl = element.querySelectorAll('.c-button-set .is-paused'); let playEl = element.querySelectorAll('.c-button-set .is-paused');
expect(playEl.length).toBe(1); expect(playEl.length).toBe(1);
done(); done();
@ -500,7 +500,7 @@ describe('the plugin', function () {
end: 100 end: 100
}); });
return Vue.nextTick(); return nextTick();
}); });
it('clicking the plot view without movement resumes the plot while active', async () => { it('clicking the plot view without movement resumes the plot while active', async () => {
@ -516,7 +516,7 @@ describe('the plugin', function () {
canvas.dispatchEvent(mouseDownEvent); canvas.dispatchEvent(mouseDownEvent);
// mouseup event is bound to the window // mouseup event is bound to the window
window.dispatchEvent(mouseUpEvent); window.dispatchEvent(mouseUpEvent);
await Vue.nextTick(); await nextTick();
const pauseElAfterClick = element.querySelectorAll('.c-button-set .icon-pause'); const pauseElAfterClick = element.querySelectorAll('.c-button-set .icon-pause');
console.log('pauseElAfterClick', pauseElAfterClick); console.log('pauseElAfterClick', pauseElAfterClick);
@ -527,7 +527,7 @@ describe('the plugin', function () {
const pauseEl = element.querySelector('.c-button-set .icon-pause'); const pauseEl = element.querySelector('.c-button-set .icon-pause');
// pause the plot // pause the plot
pauseEl.dispatchEvent(createMouseEvent('click')); pauseEl.dispatchEvent(createMouseEvent('click'));
await Vue.nextTick(); await nextTick();
const playEl = element.querySelectorAll('.c-button-set .is-paused'); const playEl = element.querySelectorAll('.c-button-set .is-paused');
expect(playEl.length).toBe(1); expect(playEl.length).toBe(1);
@ -540,7 +540,7 @@ describe('the plugin', function () {
canvas.dispatchEvent(mouseDownEvent); canvas.dispatchEvent(mouseDownEvent);
// mouseup event is bound to the window // mouseup event is bound to the window
window.dispatchEvent(mouseUpEvent); window.dispatchEvent(mouseUpEvent);
await Vue.nextTick(); await nextTick();
const playElAfterChartClick = element.querySelectorAll('.c-button-set .is-paused'); const playElAfterChartClick = element.querySelectorAll('.c-button-set .is-paused');
expect(playElAfterChartClick.length).toBe(1); expect(playElAfterChartClick.length).toBe(1);
@ -557,7 +557,7 @@ describe('the plugin', function () {
canvas.dispatchEvent(mouseDownEvent); canvas.dispatchEvent(mouseDownEvent);
// mouseup event is bound to the window // mouseup event is bound to the window
window.dispatchEvent(mouseUpEvent); window.dispatchEvent(mouseUpEvent);
await Vue.nextTick(); await nextTick();
expect(openmct.telemetry.request).toHaveBeenCalledTimes(2); expect(openmct.telemetry.request).toHaveBeenCalledTimes(2);
}); });
@ -569,7 +569,7 @@ describe('the plugin', function () {
}); });
it('lines are displayed when configuration is set to true', async () => { it('lines are displayed when configuration is set to true', async () => {
await Vue.nextTick(); await nextTick();
const configId = openmct.objects.makeKeyString(testTelemetryObject.identifier); const configId = openmct.objects.makeKeyString(testTelemetryObject.identifier);
const config = configStore.get(configId); const config = configStore.get(configId);
config.yAxis.set('displayRange', { config.yAxis.set('displayRange', {
@ -578,7 +578,7 @@ describe('the plugin', function () {
}); });
config.series.models[0].set('limitLines', true); config.series.models[0].set('limitLines', true);
await Vue.nextTick(); await nextTick();
let limitEl = element.querySelectorAll('.js-limit-area .js-limit-line'); let limitEl = element.querySelectorAll('.js-limit-area .js-limit-line');
expect(limitEl.length).toBe(4); expect(limitEl.length).toBe(4);
}); });
@ -666,13 +666,13 @@ describe('the plugin', function () {
plotContainerResizeObserver = new ResizeObserver(handlePlotResize); plotContainerResizeObserver = new ResizeObserver(handlePlotResize);
plotContainerResizeObserver.observe( plotContainerResizeObserver.observe(
plotView.getComponent().$children[0].$children[1].$parent.$refs.plotWrapper plotView.getComponent().$refs.plotComponent.$refs.plotWrapper
); );
return Vue.nextTick(() => { return nextTick(() => {
plotView.getComponent().$children[0].$children[1].stopFollowingTimeContext(); plotView.getComponent().$refs.plotComponent.$refs.mctPlot.stopFollowingTimeContext();
spyOn( spyOn(
plotView.getComponent().$children[0].$children[1], plotView.getComponent().$refs.plotComponent.$refs.mctPlot,
'loadSeriesData' 'loadSeriesData'
).and.callThrough(); ).and.callThrough();
}); });
@ -684,22 +684,20 @@ describe('the plugin', function () {
}); });
xit('requests historical data when over the threshold', async () => { xit('requests historical data when over the threshold', async () => {
await Vue.nextTick(); await nextTick();
element.style.width = '680px'; element.style.width = '680px';
await resizePromise; await resizePromise;
expect( expect(
plotView.getComponent().$children[0].$children[1].loadSeriesData plotView.getComponent().$refs.plotComponent.$refs.mctPlot.loadSeriesData
).toHaveBeenCalledTimes(1); ).toHaveBeenCalledTimes(1);
}); });
it('does not request historical data when under the threshold', (done) => { it('does not request historical data when under the threshold', async () => {
element.style.width = '644px'; element.style.width = '644px';
resizePromise.then(() => { await resizePromise;
expect( expect(
plotView.getComponent().$children[0].$children[1].loadSeriesData plotView.getComponent().$refs.plotComponent.$refs.mctPlot.loadSeriesData
).not.toHaveBeenCalled(); ).not.toHaveBeenCalled();
done();
});
}); });
}); });
@ -815,7 +813,7 @@ describe('the plugin', function () {
domainObject: selection[0][0].context.item, domainObject: selection[0][0].context.item,
path: [selection[0][0].context.item, selection[0][1].context.item] path: [selection[0][0].context.item, selection[0][1].context.item]
}, },
template: '<plot-options/>' template: '<plot-options ref="root"/>'
}, },
{ {
element: viewContainer element: viewContainer
@ -823,8 +821,8 @@ describe('the plugin', function () {
); );
component = vNode.componentInstance; component = vNode.componentInstance;
Vue.nextTick(() => { nextTick(() => {
viewComponentObject = component.$root.$children[0]; viewComponentObject = component.$refs.root;
done(); done();
}); });
}); });
@ -873,7 +871,7 @@ describe('the plugin', function () {
beforeEach((done) => { beforeEach((done) => {
viewComponentObject.setEditState(true); viewComponentObject.setEditState(true);
Vue.nextTick(() => { nextTick(() => {
editOptionsEl = viewComponentObject.$el.querySelector('.js-plot-options-edit'); editOptionsEl = viewComponentObject.$el.querySelector('.js-plot-options-edit');
browseOptionsEl = viewComponentObject.$el.querySelector('.js-plot-options-browse'); browseOptionsEl = viewComponentObject.$el.querySelector('.js-plot-options-browse');
done(); done();

View File

@ -38,6 +38,7 @@
<div class="l-view-section"> <div class="l-view-section">
<stacked-plot-item <stacked-plot-item
v-for="objectWrapper in compositionObjects" v-for="objectWrapper in compositionObjects"
ref="stackedPlotItems"
:key="objectWrapper.keyString" :key="objectWrapper.keyString"
class="c-plot--stacked-container" class="c-plot--stacked-container"
:child-object="objectWrapper.object" :child-object="objectWrapper.object"

View File

@ -28,7 +28,7 @@ import {
resetApplicationState, resetApplicationState,
spyOnBuiltins spyOnBuiltins
} from 'utils/testing'; } from 'utils/testing';
import Vue from 'vue'; import { nextTick, ref } from 'vue';
import configStore from '../configuration/ConfigStore'; import configStore from '../configuration/ConfigStore';
import PlotConfigurationModel from '../configuration/PlotConfigurationModel'; import PlotConfigurationModel from '../configuration/PlotConfigurationModel';
@ -342,7 +342,7 @@ describe('the plugin', function () {
destroyStackedPlot = destroy; destroyStackedPlot = destroy;
await telemetryPromise; await telemetryPromise;
await Vue.nextTick(); await nextTick();
plotViewComponentObject = component.$refs.stackedPlotRef; plotViewComponentObject = component.$refs.stackedPlotRef;
const configId = openmct.objects.makeKeyString(testTelemetryObject.identifier); const configId = openmct.objects.makeKeyString(testTelemetryObject.identifier);
config = configStore.get(configId); config = configStore.get(configId);
@ -390,7 +390,7 @@ describe('the plugin', function () {
min: 10, min: 10,
max: 20 max: 20
}); });
await Vue.nextTick(); await nextTick();
let yAxisElement = element.querySelectorAll( let yAxisElement = element.querySelectorAll(
'.gl-plot-axis-area.gl-plot-y .gl-plot-tick-wrapper' '.gl-plot-axis-area.gl-plot-y .gl-plot-tick-wrapper'
); );
@ -411,10 +411,10 @@ describe('the plugin', function () {
}); });
it('turns on cursor Guides all telemetry objects', async () => { it('turns on cursor Guides all telemetry objects', async () => {
let cursorGuide = Vue.ref(plotViewComponentObject.cursorGuide); let cursorGuide = ref(plotViewComponentObject.cursorGuide);
expect(cursorGuide.value).toBeFalse(); expect(cursorGuide.value).toBeFalse();
cursorGuide.value = true; cursorGuide.value = true;
await Vue.nextTick(); await nextTick();
let childCursorGuides = element.querySelectorAll('.c-cursor-guide--v'); let childCursorGuides = element.querySelectorAll('.c-cursor-guide--v');
expect(childCursorGuides.length).toBe(1); expect(childCursorGuides.length).toBe(1);
}); });
@ -432,10 +432,10 @@ describe('the plugin', function () {
}); });
it('hides grid lines for all telemetry objects', async () => { it('hides grid lines for all telemetry objects', async () => {
let gridLines = Vue.ref(plotViewComponentObject.gridLines); let gridLines = ref(plotViewComponentObject.gridLines);
expect(gridLines.value).toBeTrue(); expect(gridLines.value).toBeTrue();
gridLines.value = false; gridLines.value = false;
await Vue.nextTick(); await nextTick();
expect(gridLines.value).toBeFalse(); expect(gridLines.value).toBeFalse();
let gridLinesContainer = element.querySelectorAll('.gl-plot-display-area .js-ticks'); let gridLinesContainer = element.querySelectorAll('.gl-plot-display-area .js-ticks');
let visible = 0; let visible = 0;
@ -488,7 +488,7 @@ describe('the plugin', function () {
max: 10 max: 10
}); });
expect( expect(
plotViewComponentObject.$children[0].component.$children[0].$children[1].xScale.domain() plotViewComponentObject.$refs.stackedPlotItems[0].component.$refs.plotComponent.$refs.mctPlot.xScale.domain()
).toEqual({ ).toEqual({
min: 0, min: 0,
max: 10 max: 10
@ -505,7 +505,8 @@ describe('the plugin', function () {
}); });
const yAxesScales = const yAxesScales =
plotViewComponentObject.$children[0].component.$children[0].$children[1].yScale; plotViewComponentObject.$refs.stackedPlotItems[0].component.$refs.plotComponent.$refs
.mctPlot.yScale;
yAxesScales.forEach((yAxisScale) => { yAxesScales.forEach((yAxisScale) => {
expect(yAxisScale.scale.domain()).toEqual({ expect(yAxisScale.scale.domain()).toEqual({
min: 10, min: 10,
@ -628,7 +629,7 @@ describe('the plugin', function () {
); );
destroyPlotOptions = destroy; destroyPlotOptions = destroy;
await Vue.nextTick(); await nextTick();
viewComponentObject = vNode.componentInstance; viewComponentObject = vNode.componentInstance;
}); });
@ -783,7 +784,7 @@ describe('the plugin', function () {
); );
destroyPlotOptions = destroy; destroyPlotOptions = destroy;
await Vue.nextTick(); await nextTick();
viewComponentObject = vNode.componentInstance; viewComponentObject = vNode.componentInstance;
}); });

View File

@ -22,7 +22,7 @@
import EventEmitter from 'EventEmitter'; import EventEmitter from 'EventEmitter';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import TabsLayout from './plugin'; import TabsLayout from './plugin';
@ -128,7 +128,7 @@ describe('the plugin', function () {
let view = tabsLayoutViewProvider.view(testViewObject, []); let view = tabsLayoutViewProvider.view(testViewObject, []);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
it('provides a view', () => { it('provides a view', () => {
@ -172,7 +172,7 @@ describe('the plugin', function () {
let view = tabsLayoutViewProvider.view(testViewObject, []); let view = tabsLayoutViewProvider.view(testViewObject, []);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
afterEach(() => { afterEach(() => {
@ -194,7 +194,7 @@ describe('the plugin', function () {
const tab = tabEls[i]; const tab = tabEls[i];
tab.click(); tab.click();
await Vue.nextTick(); await nextTick();
const tabViewEls = element.querySelectorAll('.c-tabs-view__object'); const tabViewEls = element.querySelectorAll('.c-tabs-view__object');
expect(tabViewEls.length).toEqual(2); expect(tabViewEls.length).toEqual(2);
@ -204,7 +204,7 @@ describe('the plugin', function () {
it('false, will only keep the current tab view loaded', async () => { it('false, will only keep the current tab view loaded', async () => {
testViewObject.keep_alive = false; testViewObject.keep_alive = false;
await Vue.nextTick(); await nextTick();
let tabViewEls = element.querySelectorAll('.c-tabs-view__object'); let tabViewEls = element.querySelectorAll('.c-tabs-view__object');

View File

@ -25,7 +25,7 @@ import {
resetApplicationState, resetApplicationState,
spyOnBuiltins spyOnBuiltins
} from 'utils/testing'; } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import TablePlugin from './plugin.js'; import TablePlugin from './plugin.js';
@ -225,7 +225,7 @@ describe('the plugin', () => {
tableInstance = tableView.getTable(); tableInstance = tableView.getTable();
await Vue.nextTick(); await nextTick();
}); });
afterEach(() => { afterEach(() => {
@ -242,7 +242,7 @@ describe('the plugin', () => {
it('Shows a progress bar while making requests', async () => { it('Shows a progress bar while making requests', async () => {
tableInstance.incrementOutstandingRequests(); tableInstance.incrementOutstandingRequests();
await Vue.nextTick(); await nextTick();
let progressBar = element.querySelector('.c-progress-bar'); let progressBar = element.querySelector('.c-progress-bar');
@ -252,7 +252,7 @@ describe('the plugin', () => {
it('Renders a row for every telemetry datum returned', async () => { it('Renders a row for every telemetry datum returned', async () => {
let rows = element.querySelectorAll('table.c-telemetry-table__body tr'); let rows = element.querySelectorAll('table.c-telemetry-table__body tr');
await Vue.nextTick(); await nextTick();
expect(rows.length).toBe(3); expect(rows.length).toBe(3);
}); });
@ -287,7 +287,7 @@ describe('the plugin', () => {
toColumn.dispatchEvent(dragOverEvent); toColumn.dispatchEvent(dragOverEvent);
toColumn.dispatchEvent(dropEvent); toColumn.dispatchEvent(dropEvent);
await Vue.nextTick(); await nextTick();
columns = element.querySelectorAll('tr.c-telemetry-table__headers__labels th'); columns = element.querySelectorAll('tr.c-telemetry-table__headers__labels th');
let firstColumn = columns[0]; let firstColumn = columns[0];
let secondColumn = columns[1]; let secondColumn = columns[1];
@ -305,12 +305,12 @@ describe('the plugin', () => {
it('Supports filtering telemetry by regular text search', async () => { it('Supports filtering telemetry by regular text search', async () => {
tableInstance.tableRows.setColumnFilter('some-key', '1'); tableInstance.tableRows.setColumnFilter('some-key', '1');
await Vue.nextTick(); await nextTick();
let filteredRowElements = element.querySelectorAll('table.c-telemetry-table__body tr'); let filteredRowElements = element.querySelectorAll('table.c-telemetry-table__body tr');
expect(filteredRowElements.length).toEqual(1); expect(filteredRowElements.length).toEqual(1);
tableInstance.tableRows.setColumnFilter('some-key', ''); tableInstance.tableRows.setColumnFilter('some-key', '');
await Vue.nextTick(); await nextTick();
let allRowElements = element.querySelectorAll('table.c-telemetry-table__body tr'); let allRowElements = element.querySelectorAll('table.c-telemetry-table__body tr');
expect(allRowElements.length).toEqual(3); expect(allRowElements.length).toEqual(3);
@ -318,13 +318,13 @@ describe('the plugin', () => {
it('Supports filtering using Regex', async () => { it('Supports filtering using Regex', async () => {
tableInstance.tableRows.setColumnRegexFilter('some-key', '^some-value$'); tableInstance.tableRows.setColumnRegexFilter('some-key', '^some-value$');
await Vue.nextTick(); await nextTick();
let filteredRowElements = element.querySelectorAll('table.c-telemetry-table__body tr'); let filteredRowElements = element.querySelectorAll('table.c-telemetry-table__body tr');
expect(filteredRowElements.length).toEqual(0); expect(filteredRowElements.length).toEqual(0);
tableInstance.tableRows.setColumnRegexFilter('some-key', '^some-value'); tableInstance.tableRows.setColumnRegexFilter('some-key', '^some-value');
await Vue.nextTick(); await nextTick();
let allRowElements = element.querySelectorAll('table.c-telemetry-table__body tr'); let allRowElements = element.querySelectorAll('table.c-telemetry-table__body tr');
expect(allRowElements.length).toEqual(3); expect(allRowElements.length).toEqual(3);
@ -339,7 +339,7 @@ describe('the plugin', () => {
tableInstanceConfiguration tableInstanceConfiguration
); );
await Vue.nextTick(); await nextTick();
let tableHeaderElements = element.querySelectorAll('.c-telemetry-table__headers__label'); let tableHeaderElements = element.querySelectorAll('.c-telemetry-table__headers__label');
expect(tableHeaderElements.length).toEqual(3); expect(tableHeaderElements.length).toEqual(3);
@ -350,7 +350,7 @@ describe('the plugin', () => {
tableInstanceConfiguration tableInstanceConfiguration
); );
await Vue.nextTick(); await nextTick();
tableHeaderElements = element.querySelectorAll('.c-telemetry-table__headers__label'); tableHeaderElements = element.querySelectorAll('.c-telemetry-table__headers__label');
expect(tableHeaderElements.length).toEqual(4); expect(tableHeaderElements.length).toEqual(4);
}); });
@ -364,7 +364,7 @@ describe('the plugin', () => {
tableInstanceConfiguration tableInstanceConfiguration
); );
await Vue.nextTick(); await nextTick();
let tableRowCells = element.querySelectorAll( let tableRowCells = element.querySelectorAll(
'table.c-telemetry-table__body > tbody > tr:first-child td' 'table.c-telemetry-table__body > tbody > tr:first-child td'
); );
@ -377,7 +377,7 @@ describe('the plugin', () => {
tableInstanceConfiguration tableInstanceConfiguration
); );
await Vue.nextTick(); await nextTick();
tableRowCells = element.querySelectorAll( tableRowCells = element.querySelectorAll(
'table.c-telemetry-table__body > tbody > tr:first-child td' 'table.c-telemetry-table__body > tbody > tr:first-child td'
); );
@ -391,7 +391,7 @@ describe('the plugin', () => {
// Mark a row // Mark a row
firstRow.dispatchEvent(clickEvent); firstRow.dispatchEvent(clickEvent);
await Vue.nextTick(); await nextTick();
// Verify table is paused // Verify table is paused
expect(element.querySelector('div.c-table.is-paused')).not.toBeNull(); expect(element.querySelector('div.c-table.is-paused')).not.toBeNull();
@ -404,13 +404,13 @@ describe('the plugin', () => {
// Mark a row // Mark a row
firstRow.dispatchEvent(clickEvent); firstRow.dispatchEvent(clickEvent);
await Vue.nextTick(); await nextTick();
// Verify table is paused // Verify table is paused
expect(element.querySelector('div.c-table.is-paused')).not.toBeNull(); expect(element.querySelector('div.c-table.is-paused')).not.toBeNull();
const currentBounds = openmct.time.bounds(); const currentBounds = openmct.time.bounds();
await Vue.nextTick(); await nextTick();
const newBounds = { const newBounds = {
start: currentBounds.start, start: currentBounds.start,
end: currentBounds.end - 3 end: currentBounds.end - 3
@ -418,7 +418,7 @@ describe('the plugin', () => {
// Manually change the time bounds // Manually change the time bounds
openmct.time.bounds(newBounds); openmct.time.bounds(newBounds);
await Vue.nextTick(); await nextTick();
// Verify table is no longer paused // Verify table is no longer paused
expect(element.querySelector('div.c-table.is-paused')).toBeNull(); expect(element.querySelector('div.c-table.is-paused')).toBeNull();
@ -429,13 +429,13 @@ describe('the plugin', () => {
// Pause by button // Pause by button
viewContext.togglePauseByButton(); viewContext.togglePauseByButton();
await Vue.nextTick(); await nextTick();
// Verify table is paused // Verify table is paused
expect(element.querySelector('div.c-table.is-paused')).not.toBeNull(); expect(element.querySelector('div.c-table.is-paused')).not.toBeNull();
const currentBounds = openmct.time.bounds(); const currentBounds = openmct.time.bounds();
await Vue.nextTick(); await nextTick();
const newBounds = { const newBounds = {
start: currentBounds.start, start: currentBounds.start,
@ -444,7 +444,7 @@ describe('the plugin', () => {
// Manually change the time bounds // Manually change the time bounds
openmct.time.bounds(newBounds); openmct.time.bounds(newBounds);
await Vue.nextTick(); await nextTick();
// Verify table is no longer paused // Verify table is no longer paused
expect(element.querySelector('div.c-table.is-paused')).toBeNull(); expect(element.querySelector('div.c-table.is-paused')).toBeNull();
@ -456,7 +456,7 @@ describe('the plugin', () => {
// Pause by button // Pause by button
viewContext.togglePauseByButton(); viewContext.togglePauseByButton();
await Vue.nextTick(); await nextTick();
// Verify table displays the correct number of rows // Verify table displays the correct number of rows
let tableRows = element.querySelectorAll('table.c-telemetry-table__body > tbody > tr'); let tableRows = element.querySelectorAll('table.c-telemetry-table__body > tbody > tr');
@ -468,12 +468,12 @@ describe('the plugin', () => {
// Tick the clock // Tick the clock
openmct.time.tick(1); openmct.time.tick(1);
await Vue.nextTick(); await nextTick();
// Verify table is still paused // Verify table is still paused
expect(element.querySelector('div.c-table.is-paused')).not.toBeNull(); expect(element.querySelector('div.c-table.is-paused')).not.toBeNull();
await Vue.nextTick(); await nextTick();
// Verify table displays the correct number of rows // Verify table displays the correct number of rows
tableRows = element.querySelectorAll('table.c-telemetry-table__body > tbody > tr'); tableRows = element.querySelectorAll('table.c-telemetry-table__body > tbody > tr');

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing'; import { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import { FIXED_MODE_KEY } from '../../api/time/constants'; import { FIXED_MODE_KEY } from '../../api/time/constants';
import { getPreciseDuration, millisecondsToDHMS } from '../../utils/duration'; import { getPreciseDuration, millisecondsToDHMS } from '../../utils/duration';
@ -80,7 +80,7 @@ describe('time conductor', () => {
start: config.menuOptions[0].bounds.start, start: config.menuOptions[0].bounds.start,
end: config.menuOptions[0].bounds.end end: config.menuOptions[0].bounds.end
}); });
Vue.nextTick(() => { nextTick(() => {
done(); done();
}); });
}); });
@ -118,18 +118,18 @@ describe('time conductor', () => {
const switcher = appHolder.querySelector('.is-fixed-mode'); const switcher = appHolder.querySelector('.is-fixed-mode');
const clickEvent = createMouseEvent('click'); const clickEvent = createMouseEvent('click');
switcher.dispatchEvent(clickEvent); switcher.dispatchEvent(clickEvent);
await Vue.nextTick(); await nextTick();
const modeButton = switcher.querySelector('.c-tc-input-popup .c-button--menu'); const modeButton = switcher.querySelector('.c-tc-input-popup .c-button--menu');
const clickEvent1 = createMouseEvent('click'); const clickEvent1 = createMouseEvent('click');
modeButton.dispatchEvent(clickEvent1); modeButton.dispatchEvent(clickEvent1);
await Vue.nextTick(); await nextTick();
const clockItem = document.querySelectorAll( const clockItem = document.querySelectorAll(
'.c-conductor__mode-menu .c-super-menu__menu li' '.c-conductor__mode-menu .c-super-menu__menu li'
)[1]; )[1];
const clickEvent2 = createMouseEvent('click'); const clickEvent2 = createMouseEvent('click');
clockItem.dispatchEvent(clickEvent2); clockItem.dispatchEvent(clickEvent2);
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
}); });
it('shows delta inputs', () => { it('shows delta inputs', () => {

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import EventEmitter from 'EventEmitter'; import EventEmitter from 'EventEmitter';
import Vue from 'vue'; import { nextTick } from 'vue';
import { createOpenMct, resetApplicationState } from '@/utils/testing'; import { createOpenMct, resetApplicationState } from '@/utils/testing';
@ -184,11 +184,11 @@ describe('the plugin', function () {
let view = timelineView.view(testViewObject, mockObjectPath); let view = timelineView.view(testViewObject, mockObjectPath);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
it('provides a view', async () => { it('provides a view', async () => {
await Vue.nextTick(); await nextTick();
expect(timelineView).toBeDefined(); expect(timelineView).toBeDefined();
}); });
@ -240,12 +240,12 @@ describe('the plugin', function () {
let view = timelineView.view(timelineDomainObject, [timelineDomainObject]); let view = timelineView.view(timelineDomainObject, [timelineDomainObject]);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
xit('loads the plan from composition', async () => { xit('loads the plan from composition', async () => {
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
const items = element.querySelectorAll('.js-timeline__content'); const items = element.querySelectorAll('.js-timeline__content');
expect(items.length).toEqual(1); expect(items.length).toEqual(1);
}); });
@ -267,11 +267,11 @@ describe('the plugin', function () {
let view = timelineView.view(testViewObject, mockObjectPath); let view = timelineView.view(testViewObject, mockObjectPath);
view.show(child, true); view.show(child, true);
Vue.nextTick(done); nextTick(done);
}); });
xit('displays an independent time conductor with saved options - local clock', () => { xit('displays an independent time conductor with saved options - local clock', () => {
return Vue.nextTick(() => { return nextTick(() => {
const independentTimeConductorEl = element.querySelector( const independentTimeConductorEl = element.querySelector(
'.c-timeline-holder > .c-conductor__controls' '.c-timeline-holder > .c-conductor__controls'
); );
@ -308,11 +308,11 @@ describe('the plugin', function () {
let view = timelineView.view(testViewObject2, mockObjectPath); let view = timelineView.view(testViewObject2, mockObjectPath);
view.show(child, true); view.show(child, true);
Vue.nextTick(done); nextTick(done);
}); });
xit('displays an independent time conductor with saved options - fixed timespan', () => { xit('displays an independent time conductor with saved options - fixed timespan', () => {
return Vue.nextTick(() => { return nextTick(() => {
const independentTimeConductorEl = element.querySelector( const independentTimeConductorEl = element.querySelector(
'.c-timeline-holder > .c-conductor__controls' '.c-timeline-holder > .c-conductor__controls'
); );

View File

@ -22,7 +22,7 @@
import EventEmitter from 'EventEmitter'; import EventEmitter from 'EventEmitter';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import { FIXED_MODE_KEY } from '../../api/time/constants'; import { FIXED_MODE_KEY } from '../../api/time/constants';
import { TIMELIST_TYPE } from './constants'; import { TIMELIST_TYPE } from './constants';
@ -210,7 +210,7 @@ describe('the plugin', function () {
let view = timelistView.view(timelistDomainObject, []); let view = timelistView.view(timelistDomainObject, []);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
it('displays the activities', () => { it('displays the activities', () => {
@ -226,7 +226,7 @@ describe('the plugin', function () {
it('displays activity details', (done) => { it('displays activity details', (done) => {
const timeFormat = openmct.time.timeSystem().timeFormat; const timeFormat = openmct.time.timeSystem().timeFormat;
const timeFormatter = openmct.telemetry.getValueFormatter({ format: timeFormat }).formatter; const timeFormatter = openmct.telemetry.getValueFormatter({ format: timeFormat }).formatter;
Vue.nextTick(() => { nextTick(() => {
const itemEls = element.querySelectorAll(LIST_ITEM_CLASS); const itemEls = element.querySelectorAll(LIST_ITEM_CLASS);
const itemValues = itemEls[0].querySelectorAll(LIST_ITEM_VALUE_CLASS); const itemValues = itemEls[0].querySelectorAll(LIST_ITEM_VALUE_CLASS);
expect(itemValues.length).toEqual(4); expect(itemValues.length).toEqual(4);
@ -287,13 +287,13 @@ describe('the plugin', function () {
let view = timelistView.view(timelistDomainObject, [timelistDomainObject]); let view = timelistView.view(timelistDomainObject, [timelistDomainObject]);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
it('loads the plan from composition', () => { it('loads the plan from composition', () => {
mockComposition.emit('add', planObject); mockComposition.emit('add', planObject);
return Vue.nextTick(() => { return nextTick(() => {
const items = element.querySelectorAll(LIST_ITEM_CLASS); const items = element.querySelectorAll(LIST_ITEM_CLASS);
expect(items.length).toEqual(2); expect(items.length).toEqual(2);
}); });
@ -342,13 +342,13 @@ describe('the plugin', function () {
let view = timelistView.view(timelistDomainObject, [timelistDomainObject]); let view = timelistView.view(timelistDomainObject, [timelistDomainObject]);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
it('activities', () => { it('activities', () => {
mockComposition.emit('add', planObject); mockComposition.emit('add', planObject);
return Vue.nextTick(() => { return nextTick(() => {
const items = element.querySelectorAll(LIST_ITEM_CLASS); const items = element.querySelectorAll(LIST_ITEM_CLASS);
expect(items.length).toEqual(1); expect(items.length).toEqual(1);
}); });
@ -397,13 +397,13 @@ describe('the plugin', function () {
let view = timelistView.view(timelistDomainObject, [timelistDomainObject]); let view = timelistView.view(timelistDomainObject, [timelistDomainObject]);
view.show(child, true); view.show(child, true);
return Vue.nextTick(); return nextTick();
}); });
it('hides past events', () => { it('hides past events', () => {
mockComposition.emit('add', planObject); mockComposition.emit('add', planObject);
return Vue.nextTick(() => { return nextTick(() => {
const items = element.querySelectorAll(LIST_ITEM_CLASS); const items = element.querySelectorAll(LIST_ITEM_CLASS);
expect(items.length).toEqual(1); expect(items.length).toEqual(1);
}); });

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { createOpenMct, resetApplicationState, spyOnBuiltins } from 'utils/testing'; import { createOpenMct, resetApplicationState, spyOnBuiltins } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import timerPlugin from './plugin'; import timerPlugin from './plugin';
@ -108,7 +108,7 @@ xdescribe('Timer plugin:', () => {
timerView = timerViewProvider.view(mutableTimerObject, timerObjectPath); timerView = timerViewProvider.view(mutableTimerObject, timerObjectPath);
timerView.show(child); timerView.show(child);
await Vue.nextTick(); await nextTick();
}); });
afterEach(() => { afterEach(() => {
@ -168,7 +168,7 @@ xdescribe('Timer plugin:', () => {
timerView = timerViewProvider.view(mutableTimerObject, timerObjectPath); timerView = timerViewProvider.view(mutableTimerObject, timerObjectPath);
timerView.show(child); timerView.show(child);
await Vue.nextTick(); await nextTick();
}); });
afterEach(() => { afterEach(() => {
@ -211,7 +211,7 @@ xdescribe('Timer plugin:', () => {
}); });
it('gets errors from actions if configuration is not passed', async () => { it('gets errors from actions if configuration is not passed', async () => {
await Vue.nextTick(); await nextTick();
const objectPath = _.cloneDeep(timerObjectPath); const objectPath = _.cloneDeep(timerObjectPath);
delete objectPath[0].configuration; delete objectPath[0].configuration;
@ -265,7 +265,7 @@ xdescribe('Timer plugin:', () => {
openmct.objects.mutate(timerViewObject, 'configuration.timestamp', newBaseTime); openmct.objects.mutate(timerViewObject, 'configuration.timestamp', newBaseTime);
jasmine.clock().tick(5000); jasmine.clock().tick(5000);
await Vue.nextTick(); await nextTick();
const timerElement = element.querySelector('.c-timer'); const timerElement = element.querySelector('.c-timer');
const timerPausePlayButton = timerElement.querySelector('.c-timer__ctrl-pause-play'); const timerPausePlayButton = timerElement.querySelector('.c-timer__ctrl-pause-play');
@ -282,7 +282,7 @@ xdescribe('Timer plugin:', () => {
openmct.objects.mutate(timerViewObject, 'configuration.timestamp', newBaseTime); openmct.objects.mutate(timerViewObject, 'configuration.timestamp', newBaseTime);
jasmine.clock().tick(5000); jasmine.clock().tick(5000);
await Vue.nextTick(); await nextTick();
const timerElement = element.querySelector('.c-timer'); const timerElement = element.querySelector('.c-timer');
const timerPausePlayButton = timerElement.querySelector('.c-timer__ctrl-pause-play'); const timerPausePlayButton = timerElement.querySelector('.c-timer__ctrl-pause-play');
@ -296,14 +296,14 @@ xdescribe('Timer plugin:', () => {
it('displays a paused timer correctly in the DOM', async () => { it('displays a paused timer correctly in the DOM', async () => {
jasmine.clock().tick(5000); jasmine.clock().tick(5000);
await Vue.nextTick(); await nextTick();
let action = openmct.actions.getAction('timer.pause'); let action = openmct.actions.getAction('timer.pause');
if (action) { if (action) {
action.invoke(timerObjectPath, timerView); action.invoke(timerObjectPath, timerView);
} }
await Vue.nextTick(); await nextTick();
const timerElement = element.querySelector('.c-timer'); const timerElement = element.querySelector('.c-timer');
const timerPausePlayButton = timerElement.querySelector('.c-timer__ctrl-pause-play'); const timerPausePlayButton = timerElement.querySelector('.c-timer__ctrl-pause-play');
let timerValue = timerElement.querySelector('.c-timer__value').innerText; let timerValue = timerElement.querySelector('.c-timer__value').innerText;
@ -312,7 +312,7 @@ xdescribe('Timer plugin:', () => {
expect(timerValue).toBe('0D 23:59:55'); expect(timerValue).toBe('0D 23:59:55');
jasmine.clock().tick(5000); jasmine.clock().tick(5000);
await Vue.nextTick(); await nextTick();
expect(timerValue).toBe('0D 23:59:55'); expect(timerValue).toBe('0D 23:59:55');
action = openmct.actions.getAction('timer.start'); action = openmct.actions.getAction('timer.start');
@ -320,13 +320,13 @@ xdescribe('Timer plugin:', () => {
action.invoke(timerObjectPath, timerView); action.invoke(timerObjectPath, timerView);
} }
await Vue.nextTick(); await nextTick();
action = openmct.actions.getAction('timer.pause'); action = openmct.actions.getAction('timer.pause');
if (action) { if (action) {
action.invoke(timerObjectPath, timerView); action.invoke(timerObjectPath, timerView);
} }
await Vue.nextTick(); await nextTick();
timerValue = timerElement.querySelector('.c-timer__value').innerText; timerValue = timerElement.querySelector('.c-timer__value').innerText;
expect(timerValue).toBe('1D 00:00:00'); expect(timerValue).toBe('1D 00:00:00');
}); });
@ -337,7 +337,7 @@ xdescribe('Timer plugin:', () => {
action.invoke(timerObjectPath, timerView); action.invoke(timerObjectPath, timerView);
} }
await Vue.nextTick(); await nextTick();
const timerElement = element.querySelector('.c-timer'); const timerElement = element.querySelector('.c-timer');
const timerValue = timerElement.querySelector('.c-timer__value').innerText; const timerValue = timerElement.querySelector('.c-timer__value').innerText;
const timerResetButton = timerElement.querySelector('.c-timer__ctrl-reset'); const timerResetButton = timerElement.querySelector('.c-timer__ctrl-reset');
@ -355,7 +355,7 @@ xdescribe('Timer plugin:', () => {
} }
jasmine.clock().tick(5000); jasmine.clock().tick(5000);
await Vue.nextTick(); await nextTick();
const timerElement = element.querySelector('.c-timer'); const timerElement = element.querySelector('.c-timer');
const timerValue = timerElement.querySelector('.c-timer__value').innerText; const timerValue = timerElement.querySelector('.c-timer__value').innerText;
const timerPausePlayButton = timerElement.querySelector('.c-timer__ctrl-pause-play'); const timerPausePlayButton = timerElement.querySelector('.c-timer__ctrl-pause-play');

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import ExampleUserProvider from '../../../example/exampleUser/ExampleUserProvider'; import ExampleUserProvider from '../../../example/exampleUser/ExampleUserProvider';
@ -69,7 +69,7 @@ describe('The User Indicator plugin', () => {
openmct.user.setProvider(provider); openmct.user.setProvider(provider);
return Vue.nextTick(); return nextTick();
}); });
it('exists', () => { it('exists', () => {
@ -85,7 +85,7 @@ describe('The User Indicator plugin', () => {
openmct.user openmct.user
.getCurrentUser() .getCurrentUser()
.then(async (user) => { .then(async (user) => {
await Vue.nextTick(); await nextTick();
userIndicator = openmct.indicators.indicatorObjects.find( userIndicator = openmct.indicators.indicatorObjects.find(
(indicator) => indicator.key === 'user-indicator' (indicator) => indicator.key === 'user-indicator'

View File

@ -27,6 +27,7 @@
<script> <script>
import _ from 'lodash'; import _ from 'lodash';
import { toRaw } from 'vue';
import StyleRuleManager from '@/plugins/condition/StyleRuleManager'; import StyleRuleManager from '@/plugins/condition/StyleRuleManager';
import { STYLE_CONSTANTS } from '@/plugins/condition/utils/constants'; import { STYLE_CONSTANTS } from '@/plugins/condition/utils/constants';
@ -272,16 +273,16 @@ export default {
if (provider.edit && this.showEditView) { if (provider.edit && this.showEditView) {
if (this.openmct.editor.isEditing()) { if (this.openmct.editor.isEditing()) {
this.currentView = provider.edit(this.domainObject, true, objectPath); this.currentView = provider.edit(toRaw(this.domainObject), true, objectPath);
} else { } else {
this.currentView = provider.view(this.domainObject, objectPath); this.currentView = provider.view(toRaw(this.domainObject), objectPath);
} }
this.openmct.editor.on('isEditing', this.toggleEditView); this.openmct.editor.on('isEditing', this.toggleEditView);
this.releaseEditModeHandler = () => this.releaseEditModeHandler = () =>
this.openmct.editor.off('isEditing', this.toggleEditView); this.openmct.editor.off('isEditing', this.toggleEditView);
} else { } else {
this.currentView = provider.view(this.domainObject, objectPath); this.currentView = provider.view(toRaw(this.domainObject), objectPath);
if (this.currentView.onEditModeChange) { if (this.currentView.onEditModeChange) {
this.openmct.editor.on('isEditing', this.invokeEditModeHandler); this.openmct.editor.on('isEditing', this.invokeEditModeHandler);
@ -439,7 +440,7 @@ export default {
if ( if (
provider && provider &&
provider.canEdit && provider.canEdit &&
provider.canEdit(this.domainObject, objectPath) && provider.canEdit(toRaw(this.domainObject), objectPath) &&
this.isEditingAllowed() && this.isEditingAllowed() &&
!this.openmct.editor.isEditing() !this.openmct.editor.isEditing()
) { ) {

View File

@ -20,16 +20,16 @@
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<template> <template>
<div class="c-search" :class="{ 'is-active': active }"> <div class="c-search" v-bind="$attrs" :class="{ 'is-active': active }">
<input <input
v-bind="$attrs"
class="c-search__input" class="c-search__input"
aria-label="Search Input" aria-label="Search Input"
tabindex="10000" tabindex="10000"
type="search" type="search"
:value="value" :value="value"
@input="handleInput" v-bind="$attrs"
@click="handleClick" @click="() => $emit('click')"
@input="($event) => $emit('input', $event.target.value)"
/> />
<a v-if="value" class="c-search__clear-input icon-x-in-circle" @click="clearInput"></a> <a v-if="value" class="c-search__clear-input icon-x-in-circle" @click="clearInput"></a>
<slot></slot> <slot></slot>
@ -46,7 +46,7 @@ export default {
} }
}, },
emits: ['input', 'clear', 'click'], emits: ['input', 'clear', 'click'],
data: function () { data() {
return { return {
active: false active: false
}; };
@ -61,12 +61,6 @@ export default {
// Clear the user's input and set 'active' to false // Clear the user's input and set 'active' to false
this.$emit('clear', ''); this.$emit('clear', '');
this.active = false; this.active = false;
},
handleInput(event) {
this.$emit('input', event.target.value);
},
handleClick() {
this.$emit('click');
} }
} }
}; };

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
const INSPECTOR_SELECTOR_PREFIX = '.c-inspect-properties__'; const INSPECTOR_SELECTOR_PREFIX = '.c-inspect-properties__';
@ -67,7 +67,7 @@ describe('the inspector', () => {
it('displays default details for selection', async () => { it('displays default details for selection', async () => {
openmct.selection.select(selection); openmct.selection.select(selection);
await Vue.nextTick(); await nextTick();
const details = getDetails(); const details = getDetails();
const [title, type, createdBy, modifiedBy, notes, timestamp] = details; const [title, type, createdBy, modifiedBy, notes, timestamp] = details;
@ -92,7 +92,7 @@ describe('the inspector', () => {
folderItem.modified = modifiedTimestamp; folderItem.modified = modifiedTimestamp;
openmct.selection.select(selection); openmct.selection.select(selection);
await Vue.nextTick(); await nextTick();
const details = getDetails(); const details = getDetails();
const timestamp = details[details.length - 1]; const timestamp = details[details.length - 1];
@ -115,7 +115,7 @@ describe('the inspector', () => {
selection[0].context.details = customDetails; selection[0].context.details = customDetails;
openmct.selection.select(selection); openmct.selection.select(selection);
await Vue.nextTick(); await nextTick();
const details = getDetails(); const details = getDetails();

View File

@ -60,11 +60,11 @@ describe('the inspector', () => {
stylesViewComponent = createViewComponent(StylesView, selection, openmct); stylesViewComponent = createViewComponent(StylesView, selection, openmct);
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
expect(savedStylesViewComponent.$children[0].savedStyles.length).toBe(0); expect(savedStylesViewComponent.$refs.root.savedStyles.length).toBe(0);
stylesViewComponent.$children[0].saveStyle(mockStyle); stylesViewComponent.$refs.root.saveStyle(mockStyle);
expect(savedStylesViewComponent.$children[0].savedStyles.length).toBe(1); expect(savedStylesViewComponent.$refs.root.savedStyles.length).toBe(1);
}); });
it('should display all saved styles', () => { it('should display all saved styles', () => {
@ -72,11 +72,11 @@ describe('the inspector', () => {
stylesViewComponent = createViewComponent(StylesView, selection, openmct); stylesViewComponent = createViewComponent(StylesView, selection, openmct);
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
expect(savedStylesViewComponent.$children[0].$children.length).toBe(0); expect(savedStylesViewComponent.$refs.root.savedStyles.length).toBe(0);
stylesViewComponent.$children[0].saveStyle(mockStyle); stylesViewComponent.$refs.root.saveStyle(mockStyle);
return stylesViewComponent.$nextTick().then(() => { return stylesViewComponent.$nextTick().then(() => {
expect(savedStylesViewComponent.$children[0].$children.length).toBe(1); expect(savedStylesViewComponent.$refs.root.savedStyles.length).toBe(1);
}); });
}); });
@ -87,17 +87,15 @@ describe('the inspector', () => {
stylesViewComponent = createViewComponent(StylesView, selection, openmct); stylesViewComponent = createViewComponent(StylesView, selection, openmct);
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
stylesViewComponent.$children[0].saveStyle(mockStyle); stylesViewComponent.$refs.root.saveStyle(mockStyle);
return stylesViewComponent.$nextTick().then(() => { return stylesViewComponent.$nextTick().then(() => {
const styleSelectorComponent = savedStylesViewComponent.$children[0].$children[0]; const styleSelectorComponent = savedStylesViewComponent.$refs.root.$refs.root;
styleSelectorComponent.selectStyle(); styleSelectorComponent.selectStyle();
return savedStylesViewComponent.$nextTick().then(() => { return savedStylesViewComponent.$nextTick().then(() => {
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1; const styleEditorComponent = stylesViewComponent.$refs.root.$refs.styleEditor;
const styleEditorComponent =
stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
const styles = styleEditorComponent.$children.filter( const styles = styleEditorComponent.$children.filter(
(component) => component.options.value === mockStyle.color (component) => component.options.value === mockStyle.color
); );
@ -112,13 +110,13 @@ describe('the inspector', () => {
stylesViewComponent = createViewComponent(StylesView, selection, openmct); stylesViewComponent = createViewComponent(StylesView, selection, openmct);
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
stylesViewComponent.$children[0].saveStyle(mockStyle); stylesViewComponent.$refs.root.saveStyle(mockStyle);
expect(savedStylesViewComponent.$children[0].savedStyles.length).toBe(1); expect(savedStylesViewComponent.$refs.root.savedStyles.length).toBe(1);
savedStylesViewComponent.$children[0].deleteStyle(0); savedStylesViewComponent.$refs.root.deleteStyle(0);
expect(savedStylesViewComponent.$children[0].savedStyles.length).toBe(0); expect(savedStylesViewComponent.$refs.root.savedStyles.length).toBe(0);
}); });
it('should prevent a style from being saved when the number of saved styles is at the limit', () => { it('should prevent a style from being saved when the number of saved styles is at the limit', () => {
@ -129,16 +127,16 @@ describe('the inspector', () => {
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
for (let i = 1; i <= 20; i++) { for (let i = 1; i <= 20; i++) {
stylesViewComponent.$children[0].saveStyle(mockStyle); stylesViewComponent.$refs.root.saveStyle(mockStyle);
} }
expect(SavedStylesView.methods.showLimitReachedDialog).not.toHaveBeenCalled(); expect(SavedStylesView.methods.showLimitReachedDialog).not.toHaveBeenCalled();
expect(savedStylesViewComponent.$children[0].savedStyles.length).toBe(20); expect(savedStylesViewComponent.$refs.root.savedStyles.length).toBe(20);
stylesViewComponent.$children[0].saveStyle(mockStyle); stylesViewComponent.$refs.root.saveStyle(mockStyle);
expect(SavedStylesView.methods.showLimitReachedDialog).toHaveBeenCalled(); expect(SavedStylesView.methods.showLimitReachedDialog).toHaveBeenCalled();
expect(savedStylesViewComponent.$children[0].savedStyles.length).toBe(20); expect(savedStylesViewComponent.$refs.root.savedStyles.length).toBe(20);
}); });
it('should allow styles from multi-selections to be saved', () => { it('should allow styles from multi-selections to be saved', () => {
@ -149,17 +147,14 @@ describe('the inspector', () => {
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
return stylesViewComponent.$nextTick().then(() => { return stylesViewComponent.$nextTick().then(() => {
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1; const styleEditorComponent = stylesViewComponent.$refs.root.$refs.styleEditor;
const styleEditorComponent = const saveStyleButton = styleEditorComponent.$refs.saveStyleButton;
stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
const saveStyleButton = styleEditorComponent.$children[saveStyleButtonIndex];
expect(saveStyleButton.$listeners.click).not.toBe(undefined); expect(saveStyleButton).not.toBe(undefined);
saveStyleButton.$listeners.click(); saveStyleButton.$refs.button.click();
expect(savedStylesViewComponent.$children[0].savedStyles.length).toBe(1); expect(savedStylesViewComponent.$refs.root.$data.savedStyles.length).toBe(1);
}); });
}); });
@ -171,13 +166,11 @@ describe('the inspector', () => {
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
return stylesViewComponent.$nextTick().then(() => { return stylesViewComponent.$nextTick().then(() => {
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1; const styleEditorComponent = stylesViewComponent.$refs.root.$refs.styleEditor;
const styleEditorComponent = const saveStyleButton = styleEditorComponent.$refs.saveStyleButton;
stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
const saveStyleButton = styleEditorComponent.$children[saveStyleButtonIndex];
expect(saveStyleButton.$listeners.click).toBe(undefined); // Saving should not be enabled, thus the button ref should be undefined
expect(saveStyleButton).toBe(undefined);
}); });
}); });
@ -189,13 +182,11 @@ describe('the inspector', () => {
savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
return stylesViewComponent.$nextTick().then(() => { return stylesViewComponent.$nextTick().then(() => {
const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1; const styleEditorComponent = stylesViewComponent.$refs.root.$refs.styleEditor;
const styleEditorComponent = const saveStyleButton = styleEditorComponent.$refs.saveStyleButton;
stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
const saveStyleButton = styleEditorComponent.$children[saveStyleButtonIndex];
expect(saveStyleButton.$listeners.click).toBe(undefined); // Saving should not be enabled, thus the button ref should be undefined
expect(saveStyleButton).toBe(undefined);
}); });
}); });
@ -211,7 +202,7 @@ describe('the inspector', () => {
stylesManager stylesManager
}, },
components: {}, components: {},
template: `<${component.name} />` template: `<${component.name} ref="root"/>`
}; };
config.components[component.name] = component; config.components[component.name] = component;

View File

@ -22,7 +22,7 @@
import mount from 'utils/mount'; import mount from 'utils/mount';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import Layout from './AppLayout.vue'; import Layout from './AppLayout.vue';
@ -48,7 +48,7 @@ describe('Open MCT Layout:', () => {
describe('the pane:', () => { describe('the pane:', () => {
it('is displayed on layout load', async () => { it('is displayed on layout load', async () => {
await createLayout(); await createLayout();
await Vue.nextTick(); await nextTick();
Object.entries(components).forEach(([name, component]) => { Object.entries(components).forEach(([name, component]) => {
expect(component.pane).toBeTruthy(); expect(component.pane).toBeTruthy();
@ -61,8 +61,8 @@ describe('Open MCT Layout:', () => {
setHideParams(); setHideParams();
await createLayout(); await createLayout();
await Vue.nextTick(); await nextTick();
await Vue.nextTick(); await nextTick();
Object.entries(components).forEach(([name, component]) => { Object.entries(components).forEach(([name, component]) => {
expect(isCollapsed(component.pane)).toBeTrue(); expect(isCollapsed(component.pane)).toBeTrue();
@ -71,9 +71,9 @@ describe('Open MCT Layout:', () => {
it('on toggle collapses if expanded', async () => { it('on toggle collapses if expanded', async () => {
await createLayout(); await createLayout();
await Vue.nextTick(); await nextTick();
toggleCollapseButtons(); toggleCollapseButtons();
await Vue.nextTick(); await nextTick();
Object.entries(components).forEach(([name, component]) => { Object.entries(components).forEach(([name, component]) => {
expect(openmct.router.getSearchParam(component.param)).toEqual('true'); expect(openmct.router.getSearchParam(component.param)).toEqual('true');
@ -86,7 +86,7 @@ describe('Open MCT Layout:', () => {
setHideParams(); setHideParams();
await createLayout(); await createLayout();
await Vue.nextTick(); await nextTick();
toggleExpandButtons(); toggleExpandButtons();
Object.entries(components).forEach(([name, component]) => { Object.entries(components).forEach(([name, component]) => {

View File

@ -187,7 +187,7 @@ export default {
const clickedPreviewClose = const clickedPreviewClose =
event.target.parentElement && event.target.parentElement &&
event.target.parentElement.querySelector('.js-preview-window'); event.target.parentElement.querySelector('.js-preview-window');
const searchResultsDropDown = this.$refs.searchResultsDropDown._data; const searchResultsDropDown = this.$refs.searchResultsDropDown._.data;
if ( if (
!clickedInsideDropdown && !clickedInsideDropdown &&
searchResultsDropDown.resultsShown && searchResultsDropDown.resultsShown &&

View File

@ -22,7 +22,7 @@
import mount from 'utils/mount'; import mount from 'utils/mount';
import { createOpenMct, resetApplicationState } from 'utils/testing'; import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue'; import { nextTick } from 'vue';
import ExampleTagsPlugin from '../../../../example/exampleTags/plugin'; import ExampleTagsPlugin from '../../../../example/exampleTags/plugin';
import DisplayLayoutPlugin from '../../../plugins/displayLayout/plugin'; import DisplayLayoutPlugin from '../../../plugins/displayLayout/plugin';
@ -197,7 +197,7 @@ describe('GrandSearch', () => {
provide: { provide: {
openmct openmct
}, },
template: '<GrandSearch/>' template: '<GrandSearch ref="root"/>'
}, },
{ {
element: viewContainer element: viewContainer
@ -205,7 +205,7 @@ describe('GrandSearch', () => {
); );
grandSearchComponent = vNode.componentInstance; grandSearchComponent = vNode.componentInstance;
_destroy = destroy; _destroy = destroy;
await Vue.nextTick(); await nextTick();
done(); done();
}); });
openmct.startHeadless(); openmct.startHeadless();
@ -220,8 +220,8 @@ describe('GrandSearch', () => {
}); });
it('should render an object search result', async () => { it('should render an object search result', async () => {
await grandSearchComponent.$children[0].searchEverything('foo'); await grandSearchComponent.$refs.root.searchEverything('foo');
await Vue.nextTick(); await nextTick();
const searchResults = document.querySelectorAll( const searchResults = document.querySelectorAll(
'[aria-label="fooRabbitNotebook notebook result"]' '[aria-label="fooRabbitNotebook notebook result"]'
); );
@ -233,9 +233,9 @@ describe('GrandSearch', () => {
const composition = openmct.composition.get(mockFolderObject); const composition = openmct.composition.get(mockFolderObject);
composition.add(mockNewObject); composition.add(mockNewObject);
// after adding, need to wait a beat for the folder to be indexed // after adding, need to wait a beat for the folder to be indexed
await Vue.nextTick(); await nextTick();
await grandSearchComponent.$children[0].searchEverything('apple'); await grandSearchComponent.$refs.root.searchEverything('apple');
await Vue.nextTick(); await nextTick();
const searchResults = document.querySelectorAll( const searchResults = document.querySelectorAll(
'[aria-label="New Apple Test Folder folder result"]' '[aria-label="New Apple Test Folder folder result"]'
); );
@ -259,8 +259,8 @@ describe('GrandSearch', () => {
const composition = openmct.composition.get(mockFolderObject); const composition = openmct.composition.get(mockFolderObject);
composition.add(mockNewObject); composition.add(mockNewObject);
await grandSearchComponent.$children[0].searchEverything('apple'); await grandSearchComponent.$refs.root.searchEverything('apple');
await Vue.nextTick(); await nextTick();
const searchResults = document.querySelectorAll( const searchResults = document.querySelectorAll(
'[aria-label="New Apple Test Folder folder result"]' '[aria-label="New Apple Test Folder folder result"]'
); );
@ -270,24 +270,24 @@ describe('GrandSearch', () => {
}); });
it('should render an annotation search result', async () => { it('should render an annotation search result', async () => {
await grandSearchComponent.$children[0].searchEverything('S'); await grandSearchComponent.$refs.root.searchEverything('S');
await Vue.nextTick(); await nextTick();
const annotationResults = document.querySelectorAll('[aria-label="Search Result"]'); const annotationResults = document.querySelectorAll('[aria-label="Search Result"]');
expect(annotationResults.length).toBe(2); expect(annotationResults.length).toBe(2);
expect(annotationResults[1].innerText).toContain('Driving'); expect(annotationResults[1].innerText).toContain('Driving');
}); });
it('should render no annotation search results if no match', async () => { it('should render no annotation search results if no match', async () => {
await grandSearchComponent.$children[0].searchEverything('Qbert'); await grandSearchComponent.$refs.root.searchEverything('Qbert');
await Vue.nextTick(); await nextTick();
const annotationResults = document.querySelectorAll('[aria-label="Search Result"]'); const annotationResults = document.querySelectorAll('[aria-label="Search Result"]');
expect(annotationResults.length).toBe(0); expect(annotationResults.length).toBe(0);
}); });
it('should preview object search results in edit mode if object clicked', async () => { it('should preview object search results in edit mode if object clicked', async () => {
await grandSearchComponent.$children[0].searchEverything('Folder'); await grandSearchComponent.$refs.root.searchEverything('Folder');
grandSearchComponent.$children[0].openmct.router.path = [mockDisplayLayout]; grandSearchComponent.$refs.root.openmct.router.path = [mockDisplayLayout];
await Vue.nextTick(); await nextTick();
const searchResults = document.querySelectorAll('[name="Test Folder"]'); const searchResults = document.querySelectorAll('[name="Test Folder"]');
expect(searchResults.length).toBe(1); expect(searchResults.length).toBe(1);
expect(searchResults[0].innerText).toContain('Folder'); expect(searchResults[0].innerText).toContain('Folder');
@ -297,9 +297,9 @@ describe('GrandSearch', () => {
}); });
it('should preview annotation search results in edit mode if annotation clicked', async () => { it('should preview annotation search results in edit mode if annotation clicked', async () => {
await grandSearchComponent.$children[0].searchEverything('Dri'); await grandSearchComponent.$refs.root.searchEverything('Dri');
grandSearchComponent.$children[0].openmct.router.path = [mockDisplayLayout]; grandSearchComponent.$refs.root.openmct.router.path = [mockDisplayLayout];
await Vue.nextTick(); await nextTick();
const annotationResults = document.querySelectorAll('[aria-label="Search Result"]'); const annotationResults = document.querySelectorAll('[aria-label="Search Result"]');
expect(annotationResults.length).toBe(1); expect(annotationResults.length).toBe(1);
expect(annotationResults[0].innerText).toContain('Driving'); expect(annotationResults[0].innerText).toContain('Driving');

View File

@ -22,6 +22,7 @@
<template> <template>
<div class="c-ctrl-wrapper"> <div class="c-ctrl-wrapper">
<div <div
ref="button"
class="c-icon-button" class="c-icon-button"
:title="options.title" :title="options.title"
:class="{ :class="{