Compare commits
27 Commits
mct5327
...
plots-prog
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e00a84bd5 | ||
|
|
32524f04af | ||
|
|
6eafc885f1 | ||
|
|
0a48a37be0 | ||
|
|
7e5392a6ce | ||
|
|
e5fcb6e768 | ||
|
|
040b686f96 | ||
|
|
e01378aefc | ||
|
|
5550f4cef1 | ||
|
|
925d6905a5 | ||
|
|
bd9ce0e8c4 | ||
|
|
9346ff31cd | ||
|
|
50db655bae | ||
|
|
1b03e5c7df | ||
|
|
8ba69b5e08 | ||
|
|
d389e928ba | ||
|
|
34442c53c6 | ||
|
|
451ca075fe | ||
|
|
84f1a61a8d | ||
|
|
ea041aaaf9 | ||
|
|
ac9420bfa1 | ||
|
|
0ebab10578 | ||
|
|
cbdb9fc437 | ||
|
|
63d2246345 | ||
|
|
78002f0a24 | ||
|
|
f08fd58486 | ||
|
|
730272e165 |
22
e2e/test-data/VisualTestData_storage.json
Normal file
22
e2e/test-data/VisualTestData_storage.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"cookies": [],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "http://localhost:8080",
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "tcHistory",
|
||||
"value": "{\"utc\":[{\"start\":1654548551471,\"end\":1654550351471}]}"
|
||||
},
|
||||
{
|
||||
"name": "mct",
|
||||
"value": "{\"mine\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"527856c0-cced-4b64-bb19-f943432326d0\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"persisted\":1654550352296,\"modified\":1654550352296},\"527856c0-cced-4b64-bb19-f943432326d0\":{\"identifier\":{\"key\":\"527856c0-cced-4b64-bb19-f943432326d0\",\"namespace\":\"\"},\"name\":\"Unnamed Overlay Plot\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"ce88ce37-8bb9-45e1-a85b-bb7e3c8453b9\",\"namespace\":\"\"}],\"configuration\":{\"series\":[{\"identifier\":{\"key\":\"ce88ce37-8bb9-45e1-a85b-bb7e3c8453b9\",\"namespace\":\"\"}}],\"yAxis\":{},\"xAxis\":{}},\"modified\":1654550353356,\"location\":\"mine\",\"persisted\":1654550353357},\"ce88ce37-8bb9-45e1-a85b-bb7e3c8453b9\":{\"name\":\"Unnamed Sine Wave Generator\",\"type\":\"generator\",\"identifier\":{\"key\":\"ce88ce37-8bb9-45e1-a85b-bb7e3c8453b9\",\"namespace\":\"\"},\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":\"5000\"},\"modified\":1654550353350,\"location\":\"527856c0-cced-4b64-bb19-f943432326d0\",\"persisted\":1654550353350}}"
|
||||
},
|
||||
{
|
||||
"name": "mct-tree-expanded",
|
||||
"value": "[\"/browse/mine\"]"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
22
e2e/test-data/recycled_local_storage.json
Normal file
22
e2e/test-data/recycled_local_storage.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"cookies": [],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "http://localhost:8080",
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "tcHistory",
|
||||
"value": "{\"utc\":[{\"start\":1654537164464,\"end\":1654538964464},{\"start\":1652301954635,\"end\":1652303754635}]}"
|
||||
},
|
||||
{
|
||||
"name": "mct",
|
||||
"value": "{\"mine\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"f64bea3b-58a7-4586-8c05-8b651e5f0bfd\",\"namespace\":\"\"},{\"key\":\"2d02a680-eb7e-4645-bba2-dd298f76efb8\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"persisted\":1654538965703,\"modified\":1654538965703},\"f64bea3b-58a7-4586-8c05-8b651e5f0bfd\":{\"name\":\"Unnamed Condition Set\",\"type\":\"conditionSet\",\"identifier\":{\"key\":\"f64bea3b-58a7-4586-8c05-8b651e5f0bfd\",\"namespace\":\"\"},\"configuration\":{\"conditionTestData\":[],\"conditionCollection\":[{\"isDefault\":true,\"id\":\"73f2d9ae-d1f3-4561-b7fc-ecd5df557249\",\"configuration\":{\"name\":\"Default\",\"output\":\"Default\",\"trigger\":\"all\",\"criteria\":[]},\"summary\":\"Default condition\"}]},\"composition\":[],\"telemetry\":{},\"modified\":1652303755999,\"location\":\"mine\",\"persisted\":1652303756002},\"2d02a680-eb7e-4645-bba2-dd298f76efb8\":{\"name\":\"Unnamed Condition Set\",\"type\":\"conditionSet\",\"identifier\":{\"key\":\"2d02a680-eb7e-4645-bba2-dd298f76efb8\",\"namespace\":\"\"},\"configuration\":{\"conditionTestData\":[],\"conditionCollection\":[{\"isDefault\":true,\"id\":\"4291d80c-303c-4d8d-85e1-10f012b864fb\",\"configuration\":{\"name\":\"Default\",\"output\":\"Default\",\"trigger\":\"all\",\"criteria\":[]},\"summary\":\"Default condition\"}]},\"composition\":[],\"telemetry\":{},\"modified\":1654538965702,\"location\":\"mine\",\"persisted\":1654538965702}}"
|
||||
},
|
||||
{
|
||||
"name": "mct-tree-expanded",
|
||||
"value": "[]"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -52,7 +52,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
||||
]);
|
||||
|
||||
//Save localStorage for future test execution
|
||||
await context.storageState({ path: './e2e/tests/recycled_storage.json' });
|
||||
await context.storageState({ path: './e2e/test-data/recycled_local_storage.json' });
|
||||
|
||||
//Set object identifier from url
|
||||
conditionSetUrl = await page.url();
|
||||
@@ -65,7 +65,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
||||
await browser.close();
|
||||
});
|
||||
//Load localStorage for subsequent tests
|
||||
test.use({ storageState: './e2e/tests/recycled_storage.json' });
|
||||
test.use({ storageState: './e2e/test-data/recycled_local_storage.json' });
|
||||
//Begin suite of tests again localStorage
|
||||
test('Condition set object properties persist in main view and inspector', async ({ page }) => {
|
||||
//Navigate to baseURL with injected localStorage
|
||||
|
||||
@@ -76,7 +76,15 @@ test.describe('Example Imagery', () => {
|
||||
expect(imageMouseZoomedIn.width).toBeGreaterThan(originalImageDimensions.width);
|
||||
expect(imageMouseZoomedOut.height).toBeLessThan(imageMouseZoomedIn.height);
|
||||
expect(imageMouseZoomedOut.width).toBeLessThan(imageMouseZoomedIn.width);
|
||||
});
|
||||
|
||||
test('Can adjust image brightness/contrast by dragging the sliders', async ({ page }) => {
|
||||
// Open the image filter menu
|
||||
await page.locator('[role=toolbar] button[title="Brightness and contrast"]').click();
|
||||
|
||||
// Drag the brightness and contrast sliders around and assert filter values
|
||||
await dragBrightnessSliderAndAssertFilterValues(page);
|
||||
await dragContrastSliderAndAssertFilterValues(page);
|
||||
});
|
||||
|
||||
test('Can use alt+drag to move around image once zoomed in', async ({ page }) => {
|
||||
@@ -246,10 +254,8 @@ test('Example Imagery in Display layout', async ({ page }) => {
|
||||
await page.click('text=Example Imagery');
|
||||
|
||||
// Clear and set Image load delay to minimum value
|
||||
// FIXME: Update the value to 5000 ms when this bug is fixed.
|
||||
// See: https://github.com/nasa/openmct/issues/5265
|
||||
await page.locator('input[type="number"]').fill('');
|
||||
await page.locator('input[type="number"]').fill('0');
|
||||
await page.locator('input[type="number"]').fill('5000');
|
||||
|
||||
// Click text=OK
|
||||
await Promise.all([
|
||||
@@ -307,14 +313,7 @@ test('Example Imagery in Display layout', async ({ page }) => {
|
||||
await page.locator('[data-testid=conductor-modeOption-realtime]').click();
|
||||
|
||||
// Zoom in on next image
|
||||
await bgImageLocator.hover({trial: true});
|
||||
await page.mouse.wheel(0, deltaYStep * 2);
|
||||
|
||||
// Wait for zoom animation to finish
|
||||
await bgImageLocator.hover({trial: true});
|
||||
const imageNextMouseZoomedIn = await page.locator(backgroundImageSelector).boundingBox();
|
||||
expect(imageNextMouseZoomedIn.height).toBeGreaterThan(originalImageDimensions.height);
|
||||
expect(imageNextMouseZoomedIn.width).toBeGreaterThan(originalImageDimensions.width);
|
||||
await mouseZoomIn(page);
|
||||
|
||||
// Click previous image button
|
||||
await previousImageButton.click();
|
||||
@@ -339,27 +338,14 @@ test('Example Imagery in Display layout', async ({ page }) => {
|
||||
await page.locator('.pause-play').click();
|
||||
|
||||
//Get background-image url from background-image css prop
|
||||
const backgroundImage = page.locator('.c-imagery__main-image__background-image');
|
||||
let backgroundImageUrl = await backgroundImage.evaluate((el) => {
|
||||
return window.getComputedStyle(el).getPropertyValue('background-image').match(/url\(([^)]+)\)/)[1];
|
||||
});
|
||||
let backgroundImageUrl1 = backgroundImageUrl.slice(1, -1); //forgive me, padre
|
||||
console.log('backgroundImageUrl1 ' + backgroundImageUrl1);
|
||||
await assertBackgroundImageUrlFromBackgroundCss(page);
|
||||
|
||||
let backgroundImageUrl2;
|
||||
await expect.poll(async () => {
|
||||
// Verify next image has updated
|
||||
let backgroundImageUrlNext = await backgroundImage.evaluate((el) => {
|
||||
return window.getComputedStyle(el).getPropertyValue('background-image').match(/url\(([^)]+)\)/)[1];
|
||||
});
|
||||
backgroundImageUrl2 = backgroundImageUrlNext.slice(1, -1); //forgive me, padre
|
||||
// Open the image filter menu
|
||||
await page.locator('[role=toolbar] button[title="Brightness and contrast"]').click();
|
||||
|
||||
return backgroundImageUrl2;
|
||||
}, {
|
||||
message: "verify next image has updated",
|
||||
timeout: 6 * 1000
|
||||
}).not.toBe(backgroundImageUrl1);
|
||||
console.log('backgroundImageUrl2 ' + backgroundImageUrl2);
|
||||
// Drag the brightness and contrast sliders around and assert filter values
|
||||
await dragBrightnessSliderAndAssertFilterValues(page);
|
||||
await dragContrastSliderAndAssertFilterValues(page);
|
||||
});
|
||||
|
||||
test.describe('Example imagery thumbnails resize in display layouts', () => {
|
||||
@@ -451,15 +437,333 @@ test.describe('Example imagery thumbnails resize in display layouts', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// test.fixme('Can use Mouse Wheel to zoom in and out of previous image');
|
||||
// test.fixme('Can use alt+drag to move around image once zoomed in');
|
||||
// test.fixme('Clicking on the left arrow should pause the imagery and go to previous image');
|
||||
// test.fixme('If the imagery view is in pause mode, images still come in');
|
||||
// test.fixme('If the imagery view is not in pause mode, it should be updated when new images come in');
|
||||
test.describe('Example Imagery in Flexible layout', () => {
|
||||
test.fixme('Can use Mouse Wheel to zoom in and out of previous image');
|
||||
test.fixme('Can use alt+drag to move around image once zoomed in');
|
||||
test.fixme('Can zoom into the latest image and the real-time/fixed-time imagery will pause');
|
||||
test.fixme('Clicking on the left arrow should pause the imagery and go to previous image');
|
||||
test.fixme('If the imagery view is in pause mode, it should not be updated when new images come in');
|
||||
test.fixme('If the imagery view is not in pause mode, it should be updated when new images come in');
|
||||
test('Example Imagery in Flexible layout', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nasa/openmct/issues/5326'
|
||||
});
|
||||
|
||||
// Go to baseURL
|
||||
await page.goto('/', { waitUntil: 'networkidle' });
|
||||
|
||||
// Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
|
||||
// Click text=Example Imagery
|
||||
await page.click('text=Example Imagery');
|
||||
|
||||
// Clear and set Image load delay (milliseconds)
|
||||
await page.click('input[type="number"]', {clickCount: 3});
|
||||
await page.type('input[type="number"]', "20");
|
||||
|
||||
// Click text=OK
|
||||
await Promise.all([
|
||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
||||
page.click('text=OK'),
|
||||
//Wait for Save Banner to appear
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
// Wait until Save Banner is gone
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Example Imagery');
|
||||
const bgImageLocator = await page.locator(backgroundImageSelector);
|
||||
await bgImageLocator.hover();
|
||||
|
||||
// Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
|
||||
// Click text=Flexible Layout
|
||||
await page.click('text=Flexible Layout');
|
||||
|
||||
// Assert Flexable layout
|
||||
await expect(page.locator('.js-form-title')).toHaveText('Create a New Flexible Layout');
|
||||
|
||||
// Click text=OK
|
||||
page.click('text=OK');
|
||||
|
||||
// Wait until Save Banner is gone
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
||||
|
||||
// Click My Items
|
||||
await page.locator('form[name="mctForm"] >> text=My Items').click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation({waitUntil: 'networkidle'})
|
||||
]);
|
||||
|
||||
// Click My Items
|
||||
await page.locator('.c-disclosure-triangle').click();
|
||||
|
||||
// Right click example imagery
|
||||
await page.click(('text=Unnamed Example Imagery'), { button: 'right' });
|
||||
|
||||
// Click move
|
||||
await page.locator('.icon-move').click();
|
||||
|
||||
// Click triangle to open sub menu
|
||||
await page.locator('.c-form__section .c-disclosure-triangle').click();
|
||||
|
||||
// Click Flexable Layout
|
||||
await page.click('.c-overlay__outer >> text=Unnamed Flexible Layout');
|
||||
|
||||
// Click text=OK
|
||||
await page.locator('text=OK').click();
|
||||
|
||||
// Save template
|
||||
await saveTemplate(page);
|
||||
|
||||
// Zoom in
|
||||
await mouseZoomIn(page);
|
||||
|
||||
// Center the mouse pointer
|
||||
const zoomedBoundingBox = await bgImageLocator.boundingBox();
|
||||
const imageCenterX = zoomedBoundingBox.x + zoomedBoundingBox.width / 2;
|
||||
const imageCenterY = zoomedBoundingBox.y + zoomedBoundingBox.height / 2;
|
||||
await page.mouse.move(imageCenterX, imageCenterY);
|
||||
|
||||
// Pan zoom
|
||||
await panZoomAndAssertImageProperties(page);
|
||||
|
||||
// Click previous image button
|
||||
const previousImageButton = page.locator('.c-nav--prev');
|
||||
await previousImageButton.click();
|
||||
|
||||
// Verify previous image
|
||||
const selectedImage = page.locator('.selected');
|
||||
await expect(selectedImage).toBeVisible();
|
||||
|
||||
// Click time conductor mode button
|
||||
await page.locator('.c-mode-button').click();
|
||||
|
||||
// Select local clock mode
|
||||
await page.locator('[data-testid=conductor-modeOption-realtime]').click();
|
||||
|
||||
// Zoom in on next image
|
||||
await mouseZoomIn(page);
|
||||
|
||||
// Click previous image button
|
||||
await previousImageButton.click();
|
||||
|
||||
// Verify previous image
|
||||
await expect(selectedImage).toBeVisible();
|
||||
|
||||
const imageCount = await page.locator('.c-imagery__thumb').count();
|
||||
await expect.poll(async () => {
|
||||
const newImageCount = await page.locator('.c-imagery__thumb').count();
|
||||
|
||||
return newImageCount;
|
||||
}, {
|
||||
message: "verify that new images still stream in",
|
||||
timeout: 6 * 1000
|
||||
}).toBeGreaterThan(imageCount);
|
||||
|
||||
// Verify selected image is still displayed
|
||||
await expect(selectedImage).toBeVisible();
|
||||
|
||||
// Unpause imagery
|
||||
await page.locator('.pause-play').click();
|
||||
|
||||
//Get background-image url from background-image css prop
|
||||
await assertBackgroundImageUrlFromBackgroundCss(page);
|
||||
|
||||
// Open the image filter menu
|
||||
await page.locator('[role=toolbar] button[title="Brightness and contrast"]').click();
|
||||
|
||||
// Drag the brightness and contrast sliders around and assert filter values
|
||||
await dragBrightnessSliderAndAssertFilterValues(page);
|
||||
await dragContrastSliderAndAssertFilterValues(page);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function saveTemplate(page) {
|
||||
await page.locator('.c-button--menu.c-button--major.icon-save').click();
|
||||
await page.locator('text=Save and Finish Editing').click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drag the brightness slider to max, min, and midpoint and assert the filter values
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function dragBrightnessSliderAndAssertFilterValues(page) {
|
||||
const brightnessSlider = 'div.c-image-controls__slider-wrapper.icon-brightness > input';
|
||||
const brightnessBoundingBox = await page.locator(brightnessSlider).boundingBox();
|
||||
const brightnessMidX = brightnessBoundingBox.x + brightnessBoundingBox.width / 2;
|
||||
const brightnessMidY = brightnessBoundingBox.y + brightnessBoundingBox.height / 2;
|
||||
|
||||
await page.locator(brightnessSlider).hover();
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(brightnessBoundingBox.x + brightnessBoundingBox.width, brightnessMidY);
|
||||
await assertBackgroundImageBrightness(page, '500');
|
||||
await page.mouse.move(brightnessBoundingBox.x, brightnessMidY);
|
||||
await assertBackgroundImageBrightness(page, '0');
|
||||
await page.mouse.move(brightnessMidX, brightnessMidY);
|
||||
await assertBackgroundImageBrightness(page, '250');
|
||||
await page.mouse.up();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drag the contrast slider to max, min, and midpoint and assert the filter values
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function dragContrastSliderAndAssertFilterValues(page) {
|
||||
const contrastSlider = 'div.c-image-controls__slider-wrapper.icon-contrast > input';
|
||||
const contrastBoundingBox = await page.locator(contrastSlider).boundingBox();
|
||||
const contrastMidX = contrastBoundingBox.x + contrastBoundingBox.width / 2;
|
||||
const contrastMidY = contrastBoundingBox.y + contrastBoundingBox.height / 2;
|
||||
|
||||
await page.locator(contrastSlider).hover();
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(contrastBoundingBox.x + contrastBoundingBox.width, contrastMidY);
|
||||
await assertBackgroundImageContrast(page, '500');
|
||||
await page.mouse.move(contrastBoundingBox.x, contrastMidY);
|
||||
await assertBackgroundImageContrast(page, '0');
|
||||
await page.mouse.move(contrastMidX, contrastMidY);
|
||||
await assertBackgroundImageContrast(page, '250');
|
||||
await page.mouse.up();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filter:brightness value of the current background-image and
|
||||
* asserts against an expected value
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @param {String} expected The expected brightness value
|
||||
*/
|
||||
async function assertBackgroundImageBrightness(page, expected) {
|
||||
const backgroundImage = page.locator('.c-imagery__main-image__background-image');
|
||||
|
||||
// Get the brightness filter value (i.e: filter: brightness(500%) => "500")
|
||||
const actual = await backgroundImage.evaluate((el) => {
|
||||
return el.style.filter.match(/brightness\((\d{1,3})%\)/)[1];
|
||||
});
|
||||
expect(actual).toBe(expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filter:contrast value of the current background-image and
|
||||
* asserts against an expected value
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @param {String} expected The expected contrast value
|
||||
*/
|
||||
async function assertBackgroundImageContrast(page, expected) {
|
||||
const backgroundImage = page.locator('.c-imagery__main-image__background-image');
|
||||
|
||||
// Get the contrast filter value (i.e: filter: contrast(500%) => "500")
|
||||
const actual = await backgroundImage.evaluate((el) => {
|
||||
return el.style.filter.match(/contrast\((\d{1,3})%\)/)[1];
|
||||
});
|
||||
expect(actual).toBe(expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function assertBackgroundImageUrlFromBackgroundCss(page) {
|
||||
const backgroundImage = page.locator('.c-imagery__main-image__background-image');
|
||||
let backgroundImageUrl = await backgroundImage.evaluate((el) => {
|
||||
return window.getComputedStyle(el).getPropertyValue('background-image').match(/url\(([^)]+)\)/)[1];
|
||||
});
|
||||
let backgroundImageUrl1 = backgroundImageUrl.slice(1, -1); //forgive me, padre
|
||||
console.log('backgroundImageUrl1 ' + backgroundImageUrl1);
|
||||
|
||||
let backgroundImageUrl2;
|
||||
await expect.poll(async () => {
|
||||
// Verify next image has updated
|
||||
let backgroundImageUrlNext = await backgroundImage.evaluate((el) => {
|
||||
return window.getComputedStyle(el).getPropertyValue('background-image').match(/url\(([^)]+)\)/)[1];
|
||||
});
|
||||
backgroundImageUrl2 = backgroundImageUrlNext.slice(1, -1); //forgive me, padre
|
||||
|
||||
return backgroundImageUrl2;
|
||||
}, {
|
||||
message: "verify next image has updated",
|
||||
timeout: 6 * 1000
|
||||
}).not.toBe(backgroundImageUrl1);
|
||||
console.log('backgroundImageUrl2 ' + backgroundImageUrl2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function panZoomAndAssertImageProperties(page) {
|
||||
const panHotkey = process.platform === 'linux' ? ['Control', 'Alt'] : ['Alt'];
|
||||
const expectedAltText = process.platform === 'linux' ? 'Ctrl+Alt drag to pan' : 'Alt drag to pan';
|
||||
const imageryHintsText = await page.locator('.c-imagery__hints').innerText();
|
||||
expect(expectedAltText).toEqual(imageryHintsText);
|
||||
const bgImageLocator = page.locator(backgroundImageSelector);
|
||||
const zoomedBoundingBox = await bgImageLocator.boundingBox();
|
||||
const imageCenterX = zoomedBoundingBox.x + zoomedBoundingBox.width / 2;
|
||||
const imageCenterY = zoomedBoundingBox.y + zoomedBoundingBox.height / 2;
|
||||
|
||||
// Pan right
|
||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(imageCenterX - 200, imageCenterY, 10);
|
||||
await page.mouse.up();
|
||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
||||
const afterRightPanBoundingBox = await bgImageLocator.boundingBox();
|
||||
expect(zoomedBoundingBox.x).toBeGreaterThan(afterRightPanBoundingBox.x);
|
||||
|
||||
// Pan left
|
||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(imageCenterX, imageCenterY, 10);
|
||||
await page.mouse.up();
|
||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
||||
const afterLeftPanBoundingBox = await bgImageLocator.boundingBox();
|
||||
expect(afterRightPanBoundingBox.x).toBeLessThan(afterLeftPanBoundingBox.x);
|
||||
|
||||
// Pan up
|
||||
await page.mouse.move(imageCenterX, imageCenterY);
|
||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(imageCenterX, imageCenterY + 200, 10);
|
||||
await page.mouse.up();
|
||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
||||
const afterUpPanBoundingBox = await bgImageLocator.boundingBox();
|
||||
expect(afterUpPanBoundingBox.y).toBeGreaterThanOrEqual(afterLeftPanBoundingBox.y);
|
||||
|
||||
// Pan down
|
||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(imageCenterX, imageCenterY - 200, 10);
|
||||
await page.mouse.up();
|
||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
||||
const afterDownPanBoundingBox = await bgImageLocator.boundingBox();
|
||||
expect(afterDownPanBoundingBox.y).toBeLessThanOrEqual(afterUpPanBoundingBox.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function mouseZoomIn(page) {
|
||||
const bgImageLocator = await page.locator(backgroundImageSelector);
|
||||
// Zoom in
|
||||
const originalImageDimensions = await page.locator(backgroundImageSelector).boundingBox();
|
||||
await bgImageLocator.hover();
|
||||
const deltaYStep = 100; // equivalent to 1x zoom
|
||||
await page.mouse.wheel(0, deltaYStep * 2);
|
||||
const zoomedBoundingBox = await bgImageLocator.boundingBox();
|
||||
const imageCenterX = zoomedBoundingBox.x + zoomedBoundingBox.width / 2;
|
||||
const imageCenterY = zoomedBoundingBox.y + zoomedBoundingBox.height / 2;
|
||||
|
||||
// center the mouse pointer
|
||||
await page.mouse.move(imageCenterX, imageCenterY);
|
||||
|
||||
// Wait for zoom animation to finish
|
||||
await bgImageLocator.hover();
|
||||
const imageMouseZoomedIn = await page.locator(backgroundImageSelector).boundingBox();
|
||||
expect(imageMouseZoomedIn.height).toBeGreaterThan(originalImageDimensions.height);
|
||||
expect(imageMouseZoomedIn.width).toBeGreaterThan(originalImageDimensions.width);
|
||||
}
|
||||
|
||||
test.describe('Example Imagery in Tabs view', () => {
|
||||
test.fixme('Can use Mouse Wheel to zoom in and out of previous image');
|
||||
test.fixme('Can use alt+drag to move around image once zoomed in');
|
||||
|
||||
70
e2e/tests/visual/controlledClock.visual.spec.js
Normal file
70
e2e/tests/visual/controlledClock.visual.spec.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Collection of Visual Tests set to run in a default context. The tests within this suite
|
||||
are only meant to run against openmct's app.js started by `npm run start` within the
|
||||
`./e2e/playwright-visual.config.js` file.
|
||||
|
||||
These should only use functional expect statements to verify assumptions about the state
|
||||
in a test and not for functional verification of correctness. Visual tests are not supposed
|
||||
to "fail" on assertions. Instead, they should be used to detect changes between builds or branches.
|
||||
|
||||
Note: Larger testsuite sizes are OK due to the setup time associated with these tests.
|
||||
*/
|
||||
|
||||
const { test, expect } = require('@playwright/test');
|
||||
const percySnapshot = require('@percy/playwright');
|
||||
const path = require('path');
|
||||
const sinon = require('sinon');
|
||||
|
||||
// Snippet from https://github.com/microsoft/playwright/issues/6347#issuecomment-965887758
|
||||
// Will replace with cy.clock() equivalent
|
||||
test.beforeEach(async ({ context }) => {
|
||||
await context.addInitScript({
|
||||
// eslint-disable-next-line no-undef
|
||||
path: path.join(__dirname, '../../..', './node_modules/sinon/pkg/sinon.js')
|
||||
});
|
||||
await context.addInitScript(() => {
|
||||
window.__clock = sinon.useFakeTimers({
|
||||
now: 0, //Set browser clock to UNIX Epoch
|
||||
shouldAdvanceTime: false, //Don't advance the clock
|
||||
toFake: ["setTimeout", "nextTick"]
|
||||
});
|
||||
});
|
||||
});
|
||||
test.use({ storageState: './e2e/test-data/VisualTestData_storage.json' });
|
||||
|
||||
test('Visual - Overlay Plot Loading Indicator @localstorage', async ({ page }) => {
|
||||
// Go to baseURL
|
||||
await page.goto('/', { waitUntil: 'networkidle' });
|
||||
|
||||
await page.locator('a:has-text("Unnamed Overlay Plot Overlay Plot")').click();
|
||||
//Ensure that we're on the Unnamed Overlay Plot object
|
||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Overlay Plot');
|
||||
|
||||
//Wait for canvas to be rendered and stop animating
|
||||
await page.locator('canvas >> nth=1').hover({trial: true});
|
||||
|
||||
//Take snapshot of Sine Wave Generator within Overlay Plot
|
||||
await percySnapshot(page, 'SineWaveInOverlayPlot');
|
||||
});
|
||||
95
e2e/tests/visual/generateVisualTestData.e2e.spec.js
Normal file
95
e2e/tests/visual/generateVisualTestData.e2e.spec.js
Normal file
@@ -0,0 +1,95 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
This test suite is dedicated to generating LocalStorage via Session Storage to be used
|
||||
in some visual test suites like controlledClock.visual.spec.js. This suite should run to completion
|
||||
and generate an artifact named ./e2e/test-data/VisualTestData_storage.json . This will run
|
||||
on every Commit to ensure that this object still loads into tests correctly and will retain the
|
||||
.e2e.spec.js suffix.
|
||||
|
||||
TODO: Provide additional validation of object properties as it grows.
|
||||
|
||||
*/
|
||||
|
||||
const { test } = require('../../fixtures.js');
|
||||
const { expect } = require('@playwright/test');
|
||||
|
||||
test('Generate Visual Test Data @localStorage', async ({ page, context }) => {
|
||||
//Go to baseURL
|
||||
await page.goto('/', { waitUntil: 'networkidle' });
|
||||
|
||||
await page.locator('button:has-text("Create")').click();
|
||||
|
||||
// add overlay plot with defaults
|
||||
await page.locator('li:has-text("Overlay Plot")').click();
|
||||
|
||||
// Click on My Items in Tree. Workaround for https://github.com/nasa/openmct/issues/5184
|
||||
await page.click('form[name="mctForm"] a:has-text("My Items")');
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=OK').click(),
|
||||
//Wait for Save Banner to appear1
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
//Wait until Save Banner is gone
|
||||
await page.locator('.c-message-banner__close-button').click();
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
||||
|
||||
// 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();
|
||||
|
||||
//Add a 5000 ms Delay
|
||||
await page.locator('[aria-label="Loading Delay \\(ms\\)"]').fill('5000');
|
||||
|
||||
// Click on My Items in Tree. Workaround for https://github.com/nasa/openmct/issues/5184
|
||||
await page.click('form[name="mctForm"] a:has-text("Overlay Plot")');
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=OK').click(),
|
||||
//Wait for Save Banner to appear1
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
//Wait until Save Banner is gone
|
||||
await page.locator('.c-message-banner__close-button').click();
|
||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
||||
|
||||
// focus the overlay plot
|
||||
await page.locator('text=Open MCT My Items >> span').nth(3).click();
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=Unnamed Overlay Plot').first().click()
|
||||
]);
|
||||
|
||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Overlay Plot');
|
||||
//Save localStorage for future test execution
|
||||
await context.storageState({ path: './e2e/test-data/VisualTestData_storage.json' });
|
||||
});
|
||||
@@ -32,7 +32,8 @@ define([
|
||||
offset: 0,
|
||||
dataRateInHz: 1,
|
||||
randomness: 0,
|
||||
phase: 0
|
||||
phase: 0,
|
||||
loadDelay: 0
|
||||
};
|
||||
|
||||
function GeneratorProvider(openmct) {
|
||||
@@ -53,8 +54,9 @@ define([
|
||||
'period',
|
||||
'offset',
|
||||
'dataRateInHz',
|
||||
'randomness',
|
||||
'phase',
|
||||
'randomness'
|
||||
'loadDelay'
|
||||
];
|
||||
|
||||
request = request || {};
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
var dataRateInHz = request.dataRateInHz;
|
||||
var phase = request.phase;
|
||||
var randomness = request.randomness;
|
||||
var loadDelay = Math.max(request.loadDelay, 0);
|
||||
|
||||
var step = 1000 / dataRateInHz;
|
||||
var nextStep = start - (start % step) + step;
|
||||
@@ -133,6 +134,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
if (loadDelay === 0) {
|
||||
postOnRequest(message, request, data);
|
||||
} else {
|
||||
setTimeout(() => postOnRequest(message, request, data), loadDelay);
|
||||
}
|
||||
}
|
||||
|
||||
function postOnRequest(message, request, data) {
|
||||
self.postMessage({
|
||||
id: message.id,
|
||||
data: request.spectra ? {
|
||||
|
||||
@@ -132,6 +132,17 @@ define([
|
||||
"telemetry",
|
||||
"randomness"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Loading Delay (ms)",
|
||||
control: "numberfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
key: "loadDelay",
|
||||
required: true,
|
||||
property: [
|
||||
"telemetry",
|
||||
"loadDelay"
|
||||
]
|
||||
}
|
||||
],
|
||||
initialize: function (object) {
|
||||
@@ -141,7 +152,8 @@ define([
|
||||
offset: 0,
|
||||
dataRateInHz: 1,
|
||||
phase: 0,
|
||||
randomness: 0
|
||||
randomness: 0,
|
||||
loadDelay: 0
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -168,7 +168,7 @@ function getImageUrlListFromConfig(configuration) {
|
||||
}
|
||||
|
||||
function getImageLoadDelay(domainObject) {
|
||||
const imageLoadDelay = domainObject.configuration.imageLoadDelayInMilliSeconds;
|
||||
const imageLoadDelay = Math.trunc(Number(domainObject.configuration.imageLoadDelayInMilliSeconds));
|
||||
if (!imageLoadDelay) {
|
||||
openmctInstance.objects.mutate(domainObject, 'configuration.imageLoadDelayInMilliSeconds', DEFAULT_IMAGE_LOAD_DELAY_IN_MILISECONDS);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"eslint": "8.13.0",
|
||||
"eslint-plugin-compat": "4.0.2",
|
||||
"eslint-plugin-playwright": "0.9.0",
|
||||
"eslint-plugin-vue": "9.1.0",
|
||||
"eslint-plugin-vue": "9.1.1",
|
||||
"eslint-plugin-you-dont-need-lodash-underscore": "6.12.0",
|
||||
"eventemitter3": "1.2.0",
|
||||
"express": "4.13.1",
|
||||
@@ -33,7 +33,7 @@
|
||||
"git-rev-sync": "3.0.2",
|
||||
"html2canvas": "1.4.1",
|
||||
"imports-loader": "0.8.0",
|
||||
"jasmine-core": "4.1.1",
|
||||
"jasmine-core": "4.2.0",
|
||||
"jsdoc": "3.5.5",
|
||||
"karma": "6.3.20",
|
||||
"karma-chrome-launcher": "3.1.1",
|
||||
@@ -49,7 +49,7 @@
|
||||
"lighthouse": "9.6.1",
|
||||
"location-bar": "3.0.1",
|
||||
"lodash": "4.17.21",
|
||||
"mini-css-extract-plugin": "2.6.0",
|
||||
"mini-css-extract-plugin": "2.6.1",
|
||||
"moment": "2.29.3",
|
||||
"moment-duration-format": "2.3.2",
|
||||
"moment-timezone": "0.5.34",
|
||||
@@ -70,7 +70,7 @@
|
||||
"vue-loader": "15.9.8",
|
||||
"vue-template-compiler": "2.6.14",
|
||||
"webpack": "5.68.0",
|
||||
"webpack-cli": "4.9.2",
|
||||
"webpack-cli": "4.10.0",
|
||||
"webpack-dev-middleware": "5.3.3",
|
||||
"webpack-hot-middleware": "2.25.1",
|
||||
"webpack-merge": "5.8.0"
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
tabindex="0"
|
||||
:disabled="isInvalid"
|
||||
class="c-button c-button--major"
|
||||
aria-label="Save"
|
||||
@click="onSave"
|
||||
>
|
||||
{{ submitLabel }}
|
||||
@@ -67,6 +68,7 @@
|
||||
<button
|
||||
tabindex="0"
|
||||
class="c-button js-cancel-button"
|
||||
aria-label="Cancel"
|
||||
@click="onDismiss"
|
||||
>
|
||||
{{ cancelLabel }}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
>
|
||||
<input
|
||||
v-model="field"
|
||||
:aria-label="model.name"
|
||||
type="number"
|
||||
:min="model.min"
|
||||
:max="model.max"
|
||||
|
||||
@@ -484,7 +484,7 @@ export default {
|
||||
end: range.max,
|
||||
domain: this.config.xAxis.get('key')
|
||||
})
|
||||
.then(this.stopLoading());
|
||||
.then(this.stopLoading.bind(this));
|
||||
if (purge) {
|
||||
plotSeries.purgeRecordsOutsideRange(range);
|
||||
}
|
||||
|
||||
@@ -24,16 +24,16 @@
|
||||
ref="plotWrapper"
|
||||
class="c-plot holder holder-plot has-control-bar"
|
||||
>
|
||||
|
||||
<div
|
||||
ref="plotContainer"
|
||||
class="l-view-section u-style-receiver js-style-receiver"
|
||||
:class="{'s-status-timeconductor-unsynced': status && status === 'timeconductor-unsynced'}"
|
||||
>
|
||||
<div
|
||||
<progress-bar
|
||||
v-show="!!loading"
|
||||
class="c-loading--overlay loading"
|
||||
></div>
|
||||
class="c-telemetry-table__progress-bar"
|
||||
:model="{progressPerc: undefined}"
|
||||
/>
|
||||
<mct-plot
|
||||
:init-grid-lines="gridLines"
|
||||
:init-cursor-guide="cursorGuide"
|
||||
@@ -49,10 +49,12 @@
|
||||
import eventHelpers from './lib/eventHelpers';
|
||||
import ImageExporter from '../../exporters/ImageExporter';
|
||||
import MctPlot from './MctPlot.vue';
|
||||
import ProgressBar from "../../ui/components/ProgressBar.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MctPlot
|
||||
MctPlot,
|
||||
ProgressBar
|
||||
},
|
||||
inject: ['openmct', 'domainObject', 'path'],
|
||||
props: {
|
||||
@@ -89,17 +91,14 @@ export default {
|
||||
destroy() {
|
||||
this.stopListening();
|
||||
},
|
||||
|
||||
exportJPG() {
|
||||
const plotElement = this.$refs.plotContainer;
|
||||
this.imageExporter.exportJPG(plotElement, 'plot.jpg', 'export-plot');
|
||||
},
|
||||
|
||||
exportPNG() {
|
||||
const plotElement = this.$refs.plotContainer;
|
||||
this.imageExporter.exportPNG(plotElement, 'plot.png', 'export-plot');
|
||||
},
|
||||
|
||||
setStatus(status) {
|
||||
this.status = status;
|
||||
},
|
||||
|
||||
@@ -29,6 +29,7 @@ import Vue from "vue";
|
||||
import conditionalStylesMixin from "./mixins/objectStyles-mixin";
|
||||
import configStore from "@/plugins/plot/configuration/ConfigStore";
|
||||
import PlotConfigurationModel from "@/plugins/plot/configuration/PlotConfigurationModel";
|
||||
import ProgressBar from "../../../ui/components/ProgressBar.vue";
|
||||
|
||||
export default {
|
||||
mixins: [conditionalStylesMixin],
|
||||
@@ -125,7 +126,6 @@ export default {
|
||||
const onConfigLoaded = this.onConfigLoaded;
|
||||
const onCursorGuideChange = this.onCursorGuideChange;
|
||||
const onGridLinesChange = this.onGridLinesChange;
|
||||
const loadingUpdated = this.loadingUpdated;
|
||||
const setStatus = this.setStatus;
|
||||
|
||||
const openmct = this.openmct;
|
||||
@@ -140,7 +140,8 @@ export default {
|
||||
this.component = new Vue({
|
||||
el: viewContainer,
|
||||
components: {
|
||||
MctPlot
|
||||
MctPlot,
|
||||
ProgressBar
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
@@ -156,11 +157,16 @@ export default {
|
||||
onConfigLoaded,
|
||||
onCursorGuideChange,
|
||||
onGridLinesChange,
|
||||
loadingUpdated,
|
||||
setStatus
|
||||
setStatus,
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
template: '<div ref="plotWrapper" class="l-view-section u-style-receiver js-style-receiver" :class="{\'s-status-timeconductor-unsynced\': status && status === \'timeconductor-unsynced\'}"><div v-show="!!loading" class="c-loading--overlay loading"></div><mct-plot :init-grid-lines="gridLines" :init-cursor-guide="cursorGuide" :plot-tick-width="plotTickWidth" :limit-line-labels="limitLineLabels" :color-palette="colorPalette" :options="options" @plotTickWidth="onTickWidthChange" @lockHighlightPoint="onLockHighlightPointUpdated" @highlights="onHighlightsUpdated" @configLoaded="onConfigLoaded" @cursorGuide="onCursorGuideChange" @gridLines="onGridLinesChange" @statusUpdated="setStatus" @loadingUpdated="loadingUpdated"/></div>'
|
||||
methods: {
|
||||
loadingUpdated(loaded) {
|
||||
this.loading = loaded;
|
||||
},
|
||||
},
|
||||
template: '<div ref="plotWrapper" class="l-view-section u-style-receiver js-style-receiver" :class="{\'s-status-timeconductor-unsynced\': status && status === \'timeconductor-unsynced\'}"><progress-bar v-show="loading !== false" class="c-telemetry-table__progress-bar" :model="{progressPerc: undefined}" /><mct-plot :init-grid-lines="gridLines" :init-cursor-guide="cursorGuide" :plot-tick-width="plotTickWidth" :options="options" @plotTickWidth="onTickWidthChange" @cursorGuide="onCursorGuideChange" @gridLines="onGridLinesChange" @statusUpdated="setStatus" @loadingUpdated="loadingUpdated"/></div>'
|
||||
});
|
||||
|
||||
this.setSelection();
|
||||
@@ -198,17 +204,12 @@ export default {
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context);
|
||||
},
|
||||
loadingUpdated(loaded) {
|
||||
this.loading = loaded;
|
||||
this.updateComponentProp('loading', loaded);
|
||||
},
|
||||
getProps() {
|
||||
return {
|
||||
limitLineLabels: this.showLimitLineLabels,
|
||||
gridLines: this.gridLines,
|
||||
cursorGuide: this.cursorGuide,
|
||||
plotTickWidth: this.plotTickWidth,
|
||||
loading: this.loading,
|
||||
options: this.options,
|
||||
status: this.status,
|
||||
colorPalette: this.colorPalette
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
<progress-bar
|
||||
v-if="loading"
|
||||
class="c-telemetry-table__progress-bar"
|
||||
:model="progressLoad"
|
||||
:model="{progressPerc: undefined}"
|
||||
/>
|
||||
|
||||
<!-- Headers table -->
|
||||
@@ -385,11 +385,6 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
progressLoad() {
|
||||
return {
|
||||
progressPerc: undefined
|
||||
};
|
||||
},
|
||||
dropTargetStyle() {
|
||||
return {
|
||||
top: this.$refs.headersTable.offsetTop + 'px',
|
||||
|
||||
@@ -6,6 +6,17 @@ const webpack = require('webpack');
|
||||
|
||||
module.exports = merge(common, {
|
||||
mode: 'development',
|
||||
watchOptions: {
|
||||
// Since we use require.context, webpack is watching the entire directory.
|
||||
// We need to exclude any files we don't want webpack to watch.
|
||||
// See: https://webpack.js.org/configuration/watch/#watchoptions-exclude
|
||||
ignored: [
|
||||
'**/{node_modules,dist,docs,e2e}', // All files in node_modules, dist, docs, e2e,
|
||||
'**/{*.yml,Procfile,webpack*.js,babel*.js,package*.json,tsconfig.json,jsdoc.json}', // Config files
|
||||
'**/*.{sh,md,png,ttf,woff,svg}', // Non source files
|
||||
'**/.*' // dotfiles and dotfolders
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"vue": path.join(__dirname, "node_modules/vue/dist/vue.js")
|
||||
|
||||
Reference in New Issue
Block a user