From 525496fbcaf889d2da96e848be3c0f1fe5a56d6e Mon Sep 17 00:00:00 2001 From: Joe Pea Date: Mon, 11 Apr 2022 11:22:44 -0700 Subject: [PATCH] fix: autoscale turned off could cause errors (#5040) * fix: autoscale turned off could cause errors * remove commented code * add tests for plot ticks * make sure autoscale tests use a certain window size so they work consistently * add commented code to use once playwright snapshot testing is fixed * default the user selected range to the current range prior to when they turn off autoscale * add snapshot tests for plots autoscale turned off test --- e2e/tests/plugins/plot/autoscale.e2e.spec.js | 190 ++++++++++++++++++ .../autoscale-canvas-panned-chrome.png | Bin 0 -> 16263 bytes .../autoscale-canvas-prepan-chrome.png | Bin 0 -> 26903 bytes .../configuration/PlotConfigurationModel.js | 3 +- src/plugins/plot/configuration/XAxisModel.js | 8 +- src/plugins/plot/configuration/YAxisModel.js | 81 ++++---- .../plot/inspector/forms/YAxisForm.vue | 48 ++--- src/plugins/plot/inspector/forms/formUtil.js | 12 +- 8 files changed, 263 insertions(+), 79 deletions(-) create mode 100644 e2e/tests/plugins/plot/autoscale.e2e.spec.js create mode 100644 e2e/tests/plugins/plot/autoscale.e2e.spec.js-snapshots/autoscale-canvas-panned-chrome.png create mode 100644 e2e/tests/plugins/plot/autoscale.e2e.spec.js-snapshots/autoscale-canvas-prepan-chrome.png diff --git a/e2e/tests/plugins/plot/autoscale.e2e.spec.js b/e2e/tests/plugins/plot/autoscale.e2e.spec.js new file mode 100644 index 0000000000..27b647e3fd --- /dev/null +++ b/e2e/tests/plugins/plot/autoscale.e2e.spec.js @@ -0,0 +1,190 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2022, 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. + *****************************************************************************/ + +/* +Test for plot autoscale. +*/ + +const { test: _test, expect } = require('@playwright/test'); + +// create a new `test` API that will not append platform details to snapshot +// file names, only for the tests in this file, so that the same snapshots will +// be used for all platforms. +const test = _test.extend({ + _autoSnapshotSuffix: [ + async ({}, use, testInfo) => { + testInfo.snapshotSuffix = ''; + await use(); + }, + { auto: true } + ] +}); + +test.use({ + viewport: { + width: 1280, + height: 720 + } +}); + +test.describe('ExportAsJSON', () => { + test.only('autoscale off causes no error from undefined user range', async ({ page }) => { + await page.goto('/', { waitUntil: 'networkidle' }); + + await setTimeRange(page); + + await createSinewaveOverlayPlot(page); + + await testYTicks(page, ['-1.00', '-0.50', '0.00', '0.50', '1.00']); + + await turnOffAutoscale(page); + + const canvas = page.locator('canvas').nth(1); + + // Make sure that after turning off autoscale, the user selected range values start at the same values the plot had prior. + await Promise.all([ + testYTicks(page, ['-1.00', '-0.50', '0.00', '0.50', '1.00']), + new Promise(r => setTimeout(r, 100)) + .then(() => canvas.screenshot()) + .then(shot => expect(shot).toMatchSnapshot('autoscale-canvas-prepan.png', { maxDiffPixels: 40 })) + ]); + + let errorCount = 0; + + function onError() { + errorCount++; + } + + page.on('pageerror', onError); + + await page.keyboard.down('Alt'); + + await canvas.dragTo(canvas, { + sourcePosition: { + x: 200, + y: 200 + }, + targetPosition: { + x: 400, + y: 400 + } + }); + + await page.keyboard.up('Alt'); + + page.off('pageerror', onError); + + // There would have been an error at this point. So if there isn't, then + // we fixed it. + expect(errorCount).toBe(0); + + // Ensure the drag worked. + await Promise.all([ + testYTicks(page, ['0.00', '0.50', '1.00', '1.50', '2.00']), + new Promise(r => setTimeout(r, 100)) + .then(() => canvas.screenshot()) + .then(shot => expect(shot).toMatchSnapshot('autoscale-canvas-panned.png', { maxDiffPixels: 20 })) + ]); + }); +}); + +/** + * @param {import('@playwright/test').Page} page + * @param {string} start + * @param {string} end + */ +async function setTimeRange(page, start = '2022-03-29 22:00:00.000Z', end = '2022-03-29 22:00:30.000Z') { + // Set a specific time range for consistency, otherwise it will change + // on every test to a range based on the current time. + + const timeInputs = page.locator('input.c-input--datetime'); + await timeInputs.first().click(); + await timeInputs.first().fill(start); + + await timeInputs.nth(1).click(); + await timeInputs.nth(1).fill(end); +} + +/** + * @param {import('@playwright/test').Page} page + */ +async function createSinewaveOverlayPlot(page) { + // click create button + await page.locator('button:has-text("Create")').click(); + + // add overlay plot with defaults + await page.locator('li:has-text("Overlay Plot")').click(); + await Promise.all([ + page.waitForNavigation(/*{ url: 'http://localhost:8080/#/browse/mine/a9268c6f-45cc-4bcd-a6a0-50ac4036e396?tc.mode=fixed&tc.startBound=1649305424163&tc.endBound=1649307224163&tc.timeSystem=utc&view=plot-overlay' }*/), + page.locator('text=OK').click() + ]); + + // save (exit edit mode) + await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click(); + await page.locator('text=Save and Finish Editing').click(); + + // click create button + await page.locator('button:has-text("Create")').click(); + + // add sine wave generator with defaults + await page.locator('li:has-text("Sine Wave Generator")').click(); + await Promise.all([ + page.waitForNavigation(/*{ url: 'http://localhost:8080/#/browse/mine/a9268c6f-45cc-4bcd-a6a0-50ac4036e396/5cfa5c69-17bc-4a99-9545-4da8125380c5?tc.mode=fixed&tc.startBound=1649305424163&tc.endBound=1649307224163&tc.timeSystem=utc&view=plot-single' }*/), + page.locator('text=OK').click() + ]); + + // focus the overlay plot + await page.locator('text=Open MCT My Items >> span').nth(3).click(); + await Promise.all([ + page.waitForNavigation(/*{ url: 'http://localhost:8080/#/browse/mine/a9268c6f-45cc-4bcd-a6a0-50ac4036e396?tc.mode=fixed&tc.startBound=1649305424163&tc.endBound=1649307224163&tc.timeSystem=utc&view=plot-overlay' }*/), + page.locator('text=Unnamed Overlay Plot').first().click() + ]); +} + +/** + * @param {import('@playwright/test').Page} page + */ +async function turnOffAutoscale(page) { + // enter edit mode + await page.locator('text=Unnamed Overlay Plot Snapshot >> button').nth(3).click(); + + // uncheck autoscale + await page.locator('text=Y Axis Scaling Auto scale Padding >> input[type="checkbox"]').uncheck(); + + // save + await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click(); + await page.locator('text=Save and Finish Editing').click(); +} + +/** + * @param {import('@playwright/test').Page} page + */ +async function testYTicks(page, values) { + const yTicks = page.locator('.gl-plot-y-tick-label'); + let promises = [yTicks.count().then(c => expect(c).toBe(values.length))]; + + for (let i = 0, l = values.length; i < l; i += 1) { + promises.push(expect(yTicks.nth(i)).toHaveText(values[i])); // eslint-disable-line + } + + await Promise.all(promises); +} diff --git a/e2e/tests/plugins/plot/autoscale.e2e.spec.js-snapshots/autoscale-canvas-panned-chrome.png b/e2e/tests/plugins/plot/autoscale.e2e.spec.js-snapshots/autoscale-canvas-panned-chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..56bd7aa94a5bbef1ec4e072edc0f7fc5037eb9d3 GIT binary patch literal 16263 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 L-nm>&+mQbOE6rgS literal 0 HcmV?d00001 diff --git a/e2e/tests/plugins/plot/autoscale.e2e.spec.js-snapshots/autoscale-canvas-prepan-chrome.png b/e2e/tests/plugins/plot/autoscale.e2e.spec.js-snapshots/autoscale-canvas-prepan-chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..f9c2910b7b4b49be78269971dc97681fdbb76c0f GIT binary patch literal 26903 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

G6+!A*qLRi;l@G`7R3B|bNRMEAwBu^ z0fq$P;=(~oNswI#4R>rolzM0$AZ#Kh2nGTd20`vq zWY=(?dtWAykb<5@5;d)6K4wvtu}{P_J^vJfo`?m5}_#TvaI^S~z?e$?aj)!~BeDSPS{b9^j4uZE*2tIq47V zgE5cX=U84J-Vl)KrnGCS4dGXa{g`}5`Ze9{ZVOK*CdlM5CcjwwUMs?NH_X+n3Fo~- zQ95^>{M2lqUlK?W&?aFn)(w8YU$E-lx0V2SCCjjx$Uy1VBWnc#V0I-mf3ivphE zwmTDuAc}12yyQHu4!}r{%c;kZkVq*0>H+M`X>i8ZCxEAnGME{#qjO5|=6DMH__>ZM z?pj#nGw^)_P&jWdC(>{}3JeVIr* zz6C1iyHdf5y&GHp;2>YBYwiF70hjJ>RXmMDId!CN^hyVYi-|sf?-+Wnjl`5_*Y0-^ zC@|R2)M^PX<>Y{sLvUpxhhWu3>h{AoS8^ZfED@Bjy(Le)j|7hQVN{(kAHGv)P%k!C z7Pv8G-g0#&eAN!3rnA98p;+tf?&WLx5gzY!rUj4p8;HxFbY(*?D^ zQa5wsPMJN$Qr_}CwtF zC7@{hgbkwVxrOSy0cO~Sj6uI(3MD_#KW3Dqw&%99SN54V)LU@{k}-G+6|21fp%F8Kh@v) zovx)n1kkR|bobH=1r2qTkXn98OZ?TzSI-{I)wZ5J@j$TK{r>(IKl{2gMK+o4*Tc1R zu^ae%VCsXDSRs^iKZBprYzKzjH!TduL&F|K8jRArJCl-_TdS}@H^+ACmQ2QA4^)NH zc5XkK0w^xXZq;Ox!S%>Hp};hf%E*g=$(iEJ74LTChM!M(kU@a{ThXN!g+dZ+Y>W=J?rQsV5i6AzkKe%q}-* zh#BZ;I!eiw)wc4#} z5zKSi6^lyf8tx7zDAJ@SK_Cvp%H;Q0y*#90X4T+G1S;e5$*=iu2k8l^LA$=m&717; zbeg*3o{}@P4^uIJTz)H!g{n|u7CY6@i7?CK#=^Hc5rnxG^r*>VY{BY69keVO0ja2< z?>g|x`IDdK*b-#-4bM96d7|GDx!~LRrP-gA9teJl>-O!l-@%tk2#k>R;5Q9Z4ZPq* z(||V(u$L6HFf2uT_kkr$Y;kchfQR?L?irvyg=kdss4fd=mQsMV11Hzr^R< z-Enbp?aOpx?PdQ6u4{Uq`lT+LW?Txk+L)!okxrtfR=u*;PWm4JO}cULP3n$ixl|A@ zc0EuPm)N3^(H4}p>{fgyze{#Z!xNbH1%9BPNuP}m|Kfa63!-KqeP^9r&? z!B4@XSun3Ysi^2^l8B`F6=z&RUgr7Sz(CA(dnECfclb<(o{YME*`WS$_g}JCg+NCT z;u_wCY0JmhiKghV*c7R0{O+C=imQ3^=92z@9d6t~iXE|GjfT+b+E$ER%y@{!9I^9DALwKwicnTj0k#8iZmpbGK^K9)pZT=H>0H2J z7tZ+KOV3}udJ7PA#sB+*?$y3RuK$0E7V(aWMvj9L9l1Yk&t z76Uu#|2Dxu5BQ8lL8J!o@coZGOtnhM#11i~8h_ud-r43OWn82n(l9Y0;l+O~ceb3u z_`w*WZ~p&}{oQD45MM}KfS~}0hV5ej0XM6ly$uVo3k`9FVk98lzz)PgYy1XHcH(N# mX!rjS@Lu=-8m&;{p|DmB{bcQS`YVIFA! literal 0 HcmV?d00001 diff --git a/src/plugins/plot/configuration/PlotConfigurationModel.js b/src/plugins/plot/configuration/PlotConfigurationModel.js index 2a1de87e3b..0f6a56cd6f 100644 --- a/src/plugins/plot/configuration/PlotConfigurationModel.js +++ b/src/plugins/plot/configuration/PlotConfigurationModel.js @@ -157,7 +157,8 @@ export default class PlotConfigurationModel extends Model { @typedef {{ configuration: { series: import('./PlotSeries').PlotSeriesModelType[] - } + yAxis: import('./YAxisModel').YAxisModelType + }, }} SomeDomainObject_NeedsName */ diff --git a/src/plugins/plot/configuration/XAxisModel.js b/src/plugins/plot/configuration/XAxisModel.js index da313528d3..b228305ad7 100644 --- a/src/plugins/plot/configuration/XAxisModel.js +++ b/src/plugins/plot/configuration/XAxisModel.js @@ -19,7 +19,7 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -import Model from "./Model"; +import Model from './Model'; /** * @extends {Model} @@ -49,11 +49,11 @@ export default class XAxisModel extends Model { } }); - this.on('change:frozen', ((frozen) => { + this.on('change:frozen', (frozen) => { if (!frozen) { this.set('range', this.get('range')); } - })); + }); if (this.get('range')) { this.set('range', this.get('range')); @@ -126,7 +126,7 @@ export default class XAxisModel extends Model { /** @typedef {import("./Model").ModelType<{ - range: NumberRange + range?: NumberRange displayRange: NumberRange frozen: boolean label: string diff --git a/src/plugins/plot/configuration/YAxisModel.js b/src/plugins/plot/configuration/YAxisModel.js index f10ac83bbd..09f8803b30 100644 --- a/src/plugins/plot/configuration/YAxisModel.js +++ b/src/plugins/plot/configuration/YAxisModel.js @@ -19,7 +19,6 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -import _ from 'lodash'; import Model from './Model'; /** @@ -63,14 +62,14 @@ export default class YAxisModel extends Model { */ listenToSeriesCollection(seriesCollection) { this.seriesCollection = seriesCollection; - this.listenTo(this.seriesCollection, 'add', (series => { + this.listenTo(this.seriesCollection, 'add', series => { this.trackSeries(series); this.updateFromSeries(this.seriesCollection); - }), this); - this.listenTo(this.seriesCollection, 'remove', (series => { + }, this); + this.listenTo(this.seriesCollection, 'remove', series => { this.untrackSeries(series); this.updateFromSeries(this.seriesCollection); - }), this); + }, this); this.seriesCollection.forEach(this.trackSeries, this); this.updateFromSeries(this.seriesCollection); } @@ -140,11 +139,11 @@ export default class YAxisModel extends Model { } resetStats() { this.unset('stats'); - this.seriesCollection.forEach(function (series) { + this.seriesCollection.forEach(series => { if (series.has('stats')) { this.updateStats(series.get('stats')); } - }, this); + }); } /** * @param {import('./PlotSeries').default} series @@ -170,7 +169,18 @@ export default class YAxisModel extends Model { if (autoscale && this.has('stats')) { this.set('displayRange', this.applyPadding(this.get('stats'))); } else { - this.set('displayRange', this.get('range')); + const range = this.get('range'); + + if (range) { + // If we already have a user-defined range, make sure it maps to the + // range we'll actually use for the ticks. + this.set('displayRange', range); + } else { + // Otherwise use the last known displayRange as the initial + // values for the user-defined range, so that we don't end up + // with any error from an undefined user range. + this.set('range', this.get('displayRange')); + } } } /** @@ -179,7 +189,7 @@ export default class YAxisModel extends Model { */ updateFromSeries(seriesCollection) { const plotModel = this.plot.get('domainObject'); - const label = _.get(plotModel, 'configuration.yAxis.label'); + const label = plotModel?.configuration?.yAxis?.label; const sampleSeries = seriesCollection.first(); if (!sampleSeries) { if (!label) { @@ -195,19 +205,19 @@ export default class YAxisModel extends Model { this.set('format', yFormat.format.bind(yFormat)); this.set('values', yMetadata.values); if (!label) { - const labelName = seriesCollection.map(function (s) { - return s.metadata ? s.metadata.value(s.get('yKey')).name : ''; - }).reduce(function (a, b) { - if (a === undefined) { - return b; - } + const labelName = seriesCollection + .map(s => (s.metadata ? s.metadata.value(s.get('yKey')).name : '')) + .reduce((a, b) => { + if (a === undefined) { + return b; + } - if (a === b) { - return a; - } + if (a === b) { + return a; + } - return ''; - }, undefined); + return ''; + }, undefined); if (labelName) { this.set('label', labelName); @@ -215,19 +225,19 @@ export default class YAxisModel extends Model { return; } - const labelUnits = seriesCollection.map(function (s) { - return s.metadata ? s.metadata.value(s.get('yKey')).units : ''; - }).reduce(function (a, b) { - if (a === undefined) { - return b; - } + const labelUnits = seriesCollection + .map(s => (s.metadata ? s.metadata.value(s.get('yKey')).units : '')) + .reduce((a, b) => { + if (a === undefined) { + return b; + } - if (a === b) { - return a; - } + if (a === b) { + return a; + } - return ''; - }, undefined); + return ''; + }, undefined); if (labelUnits) { this.set('label', labelUnits); @@ -239,14 +249,17 @@ export default class YAxisModel extends Model { /** * @override * @param {import('./Model').ModelOptions} options - * @returns {YAxisModelType} + * @returns {Partial} */ defaultModel(options) { - // @ts-ignore incomplete YAxisModelType object used for default value. return { frozen: false, autoscale: true, autoscalePadding: 0.1 + + // 'range' is not specified here, it is undefined at first. When the + // user turns off autoscale, the current 'displayRange' is used for + // the initial value of 'range'. }; } } @@ -257,7 +270,7 @@ export default class YAxisModel extends Model { @typedef {import('./XAxisModel').AxisModelType & { autoscale: boolean autoscalePadding: number - stats: import('./XAxisModel').NumberRange + stats?: import('./XAxisModel').NumberRange values: Array }} YAxisModelType */ diff --git a/src/plugins/plot/inspector/forms/YAxisForm.vue b/src/plugins/plot/inspector/forms/YAxisForm.vue index 6bcabd9e7e..9c16cf1da0 100644 --- a/src/plugins/plot/inspector/forms/YAxisForm.vue +++ b/src/plugins/plot/inspector/forms/YAxisForm.vue @@ -52,10 +52,10 @@ class="l-inspector-part" >

- {{ validation.range }} + {{ validationErrors.range }}