From 84f1a61a8d6fb4858b34a2d65ca1a300c9495acd Mon Sep 17 00:00:00 2001 From: Jesse Mazzella Date: Mon, 13 Jun 2022 15:24:44 -0700 Subject: [PATCH] Allow dragging of imagery filter sliders when embedded in flexible layout (#5342) * Fix imagery filter sliders within flexible layout * Add image filter value checks to e2e test - Tests if filter values are updated correctly when dragging contrast/brightness sliders on imagery embedded in a flexible layout * More e2e tests, add aria-role and update selectors - Add 'toolbar' role for Image controls --- .../imagery/exampleImagery.e2e.spec.js | 101 ++++++++++++++++++ .../imagery/components/FilterSettings.vue | 4 + .../imagery/components/ImageControls.vue | 6 +- 3 files changed, 110 insertions(+), 1 deletion(-) diff --git a/e2e/tests/plugins/imagery/exampleImagery.e2e.spec.js b/e2e/tests/plugins/imagery/exampleImagery.e2e.spec.js index 4a6a780b21..7fb96b78fd 100644 --- a/e2e/tests/plugins/imagery/exampleImagery.e2e.spec.js +++ b/e2e/tests/plugins/imagery/exampleImagery.e2e.spec.js @@ -79,7 +79,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 }) => { @@ -334,6 +342,13 @@ test('Example Imagery in Display layout', async ({ page }) => { //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); }); test.describe('Example imagery thumbnails resize in display layouts', () => { @@ -432,6 +447,11 @@ test.describe('Example imagery thumbnails resize in display layouts', () => { // 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('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' }); @@ -553,6 +573,13 @@ test.describe('Example Imagery in Flexible layout', () => { //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); }); }); @@ -564,6 +591,80 @@ async function saveTemplate(page) { 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 */ diff --git a/src/plugins/imagery/components/FilterSettings.vue b/src/plugins/imagery/components/FilterSettings.vue index c88d215d55..16aaadbb54 100644 --- a/src/plugins/imagery/components/FilterSettings.vue +++ b/src/plugins/imagery/components/FilterSettings.vue @@ -14,6 +14,8 @@ type="range" min="0" max="500" + draggable="true" + @dragstart.stop.prevent @change="notifyFiltersChanged" @input="notifyFiltersChanged" > @@ -24,6 +26,8 @@ type="range" min="0" max="500" + draggable="true" + @dragstart.stop.prevent @change="notifyFiltersChanged" @input="notifyFiltersChanged" > diff --git a/src/plugins/imagery/components/ImageControls.vue b/src/plugins/imagery/components/ImageControls.vue index eae50f6b49..96cf702bc5 100644 --- a/src/plugins/imagery/components/ImageControls.vue +++ b/src/plugins/imagery/components/ImageControls.vue @@ -21,7 +21,11 @@ *****************************************************************************/