From e8c26161b7ce49be1908827392fa17b7e6b8878b Mon Sep 17 00:00:00 2001 From: wagnermaciel Date: Mon, 12 Apr 2021 11:29:41 -0700 Subject: [PATCH 1/4] test(material-experimental/mdc-slider): create e2e tests * create basic tests for standard, disabled, and range sliders --- src/e2e-app/mdc-slider/mdc-slider-e2e.ts | 15 +- .../mdc-slider/BUILD.bazel | 1 + .../mdc-slider/slider.e2e.spec.ts | 132 +++++++++++++++++- 3 files changed, 142 insertions(+), 6 deletions(-) diff --git a/src/e2e-app/mdc-slider/mdc-slider-e2e.ts b/src/e2e-app/mdc-slider/mdc-slider-e2e.ts index ec5fe2d2b71d..5df32c062fee 100644 --- a/src/e2e-app/mdc-slider/mdc-slider-e2e.ts +++ b/src/e2e-app/mdc-slider/mdc-slider-e2e.ts @@ -10,7 +10,20 @@ import {Component} from '@angular/core'; @Component({ selector: 'mdc-slider-e2e', - template: ``, + template: ` + + + + + + + + + + + + + `, }) export class MdcSliderE2e { } diff --git a/src/material-experimental/mdc-slider/BUILD.bazel b/src/material-experimental/mdc-slider/BUILD.bazel index cb14d0a3ba2c..2c3fa6c98228 100644 --- a/src/material-experimental/mdc-slider/BUILD.bazel +++ b/src/material-experimental/mdc-slider/BUILD.bazel @@ -97,6 +97,7 @@ ng_e2e_test_library( deps = [ ":mdc-slider", "//src/cdk/testing/private/e2e", + "@npm//@material/slider", ], ) diff --git a/src/material-experimental/mdc-slider/slider.e2e.spec.ts b/src/material-experimental/mdc-slider/slider.e2e.spec.ts index fd79d7568fee..a6a86a7cde6f 100644 --- a/src/material-experimental/mdc-slider/slider.e2e.spec.ts +++ b/src/material-experimental/mdc-slider/slider.e2e.spec.ts @@ -6,11 +6,133 @@ * found in the LICENSE file at https://angular.io/license */ -/* tslint:disable-next-line:no-unused-variable */ -import {MatSlider} from './index'; - -// TODO(wagnermaciel): Implement this in a separate PR +import {clickElementAtPoint, getElement, Point} from '@angular/cdk/testing/private/e2e'; +import {Thumb} from '@material/slider'; +import {browser, by, element, ElementFinder} from 'protractor'; describe('MDC-based MatSlider' , () => { - it('does nothing yet', async () => {}); + const getStandardSlider = () => element(by.id('standard-slider')); + const getDisabledSlider = () => element(by.id('disabled-slider')); + const getRangeSlider = () => element(by.id('range-slider')); + + beforeEach(async () => await browser.get('mdc-slider')); + + describe('standard slider', async () => { + let slider: ElementFinder; + beforeAll(() => { slider = getStandardSlider(); }); + + it('should update the value on click', async () => { + await setValueByClick(slider, 15); + expect(await getSliderValue(slider, Thumb.END)).toBe(15); + }); + + it('should update the value on slide', async () => { + await slideToValue(slider, 35, Thumb.END); + expect(await getSliderValue(slider, Thumb.END)).toBe(35); + }); + }); + + describe('disabled slider', async () => { + let slider: ElementFinder; + beforeAll(() => { slider = getDisabledSlider(); }); + + it('should not update the value on click', async () => { + await setValueByClick(slider, 15); + expect(await getSliderValue(slider, Thumb.END)).not.toBe(15); + }); + + it('should not update the value on slide', async () => { + await slideToValue(slider, 35, Thumb.END); + expect(await getSliderValue(slider, Thumb.END)).not.toBe(35); + }); + }); + + describe('range slider', async () => { + let slider: ElementFinder; + beforeAll(() => { slider = getRangeSlider(); }); + + it('should update the start thumb value on slide', async () => { + await slideToValue(slider, 35, Thumb.START); + expect(await getSliderValue(slider, Thumb.START)).toBe(35); + }); + + it('should update the end thumb value on slide', async () => { + console.log('value:', await getSliderValue(slider, Thumb.END)); + await slideToValue(slider, 55, Thumb.END); + console.log('value:', await getSliderValue(slider, Thumb.END)); + expect(await getSliderValue(slider, Thumb.END)).toBe(55); + }); + + it('should update the start thumb value on click between thumbs ' + + 'but closer to the start thumb', async () => { + await setValueByClick(slider, 49); + expect(await getSliderValue(slider, Thumb.START)).toBe(49); + expect(await getSliderValue(slider, Thumb.END)).toBe(100); + }); + + it('should update the end thumb value on click between thumbs ' + + 'but closer to the end thumb', async () => { + await setValueByClick(slider, 51); + expect(await getSliderValue(slider, Thumb.START)).toBe(0); + expect(await getSliderValue(slider, Thumb.END)).toBe(51); + }); + }); }); + +/** Returns the current value of the slider. */ +async function getSliderValue(slider: ElementFinder, thumbPosition: Thumb): Promise { + const inputs = await slider.all(by.css('.mdc-slider__input')); + return thumbPosition === Thumb.END + ? Number(await inputs[inputs.length - 1].getAttribute('value')) + : Number(await inputs[0].getAttribute('value')); +} + +/** Clicks on the MatSlider at the coordinates corresponding to the given value. */ +async function setValueByClick(slider: ElementFinder, value: number): Promise { + return clickElementAtPoint(slider, await getCoordsForValue(slider, value)); +} + +/** Clicks on the MatSlider at the coordinates corresponding to the given value. */ +async function slideToValue + (slider: ElementFinder, value: number, thumbPosition: Thumb): Promise { + const webElement = await getElement(slider).getWebElement(); + const startCoords = await getCoordsForValue( + slider, + await getSliderValue(slider, thumbPosition), + ); + const endCoords = await getCoordsForValue(slider, value); + return await browser.actions() + .mouseMove(webElement, startCoords) + .mouseDown() + .mouseMove(webElement, endCoords) + .mouseUp() + .perform(); +} + +/** Returns the x and y coordinates for the given slider value. */ +async function getCoordsForValue(slider: ElementFinder, value: number): Promise { + const inputs = await slider.all(by.css('.mdc-slider__input')); + + const min = Number(await inputs[0].getAttribute('min')); + const max = Number(await inputs[inputs.length - 1].getAttribute('max')); + const percent = (value - min) / (max - min); + + const {width, height} = await getBoundingClientRect(slider); + + // NOTE: We use Math.round here because protractor silently breaks if you pass in an imprecise + // floating point number with lots of decimals. This allows us to avoid the headache but it may + // cause some innaccuracies in places where these decimals mean the difference between values. + + const x = Math.round(width * percent); + const y = Math.round(height / 2); + + return {x, y}; +} + +/** Uses browser.executeScript to retrieve the client rect of the given protractor element. */ +async function getBoundingClientRect(elementFinder: ElementFinder): Promise { + return browser.executeScript( + 'return arguments[0].getBoundingClientRect()', + await elementFinder.getWebElement() + ) as unknown as DOMRect; +} From 064547d9fd8c9889d5d0427711af84683d1e6c88 Mon Sep 17 00:00:00 2001 From: wagnermaciel Date: Mon, 12 Apr 2021 12:28:24 -0700 Subject: [PATCH 2/4] fixup! test(material-experimental/mdc-slider): create e2e tests --- .../mdc-slider/slider.e2e.spec.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/material-experimental/mdc-slider/slider.e2e.spec.ts b/src/material-experimental/mdc-slider/slider.e2e.spec.ts index a6a86a7cde6f..c10d61fe5b4d 100644 --- a/src/material-experimental/mdc-slider/slider.e2e.spec.ts +++ b/src/material-experimental/mdc-slider/slider.e2e.spec.ts @@ -117,7 +117,7 @@ async function getCoordsForValue(slider: ElementFinder, value: number): Promise< const max = Number(await inputs[inputs.length - 1].getAttribute('max')); const percent = (value - min) / (max - min); - const {width, height} = await getBoundingClientRect(slider); + const {width, height} = await slider.getSize(); // NOTE: We use Math.round here because protractor silently breaks if you pass in an imprecise // floating point number with lots of decimals. This allows us to avoid the headache but it may @@ -128,11 +128,3 @@ async function getCoordsForValue(slider: ElementFinder, value: number): Promise< return {x, y}; } - -/** Uses browser.executeScript to retrieve the client rect of the given protractor element. */ -async function getBoundingClientRect(elementFinder: ElementFinder): Promise { - return browser.executeScript( - 'return arguments[0].getBoundingClientRect()', - await elementFinder.getWebElement() - ) as unknown as DOMRect; -} From 46255a663c4465df7c5a856b48e486bf7eeeccb6 Mon Sep 17 00:00:00 2001 From: wagnermaciel Date: Mon, 12 Apr 2021 12:42:54 -0700 Subject: [PATCH 3/4] fixup! test(material-experimental/mdc-slider): create e2e tests --- src/material-experimental/mdc-slider/slider.e2e.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/material-experimental/mdc-slider/slider.e2e.spec.ts b/src/material-experimental/mdc-slider/slider.e2e.spec.ts index c10d61fe5b4d..d6aca9fdd198 100644 --- a/src/material-experimental/mdc-slider/slider.e2e.spec.ts +++ b/src/material-experimental/mdc-slider/slider.e2e.spec.ts @@ -19,7 +19,7 @@ describe('MDC-based MatSlider' , () => { describe('standard slider', async () => { let slider: ElementFinder; - beforeAll(() => { slider = getStandardSlider(); }); + beforeEach(() => { slider = getStandardSlider(); }); it('should update the value on click', async () => { await setValueByClick(slider, 15); @@ -34,7 +34,7 @@ describe('MDC-based MatSlider' , () => { describe('disabled slider', async () => { let slider: ElementFinder; - beforeAll(() => { slider = getDisabledSlider(); }); + beforeEach(() => { slider = getDisabledSlider(); }); it('should not update the value on click', async () => { await setValueByClick(slider, 15); @@ -49,7 +49,7 @@ describe('MDC-based MatSlider' , () => { describe('range slider', async () => { let slider: ElementFinder; - beforeAll(() => { slider = getRangeSlider(); }); + beforeEach(() => { slider = getRangeSlider(); }); it('should update the start thumb value on slide', async () => { await slideToValue(slider, 35, Thumb.START); From fa21adee98a432cf162cccd483386e43188a1da0 Mon Sep 17 00:00:00 2001 From: wagnermaciel Date: Mon, 12 Apr 2021 13:39:57 -0700 Subject: [PATCH 4/4] fixup! test(material-experimental/mdc-slider): create e2e tests --- src/e2e-app/mdc-slider/mdc-slider-e2e.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/e2e-app/mdc-slider/mdc-slider-e2e.ts b/src/e2e-app/mdc-slider/mdc-slider-e2e.ts index 5df32c062fee..fe9f07e698dd 100644 --- a/src/e2e-app/mdc-slider/mdc-slider-e2e.ts +++ b/src/e2e-app/mdc-slider/mdc-slider-e2e.ts @@ -20,8 +20,8 @@ import {Component} from '@angular/core'; - - + + `, })