Skip to content

test(material-experimental/mdc-slider): create e2e tests #22463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/e2e-app/mdc-slider/mdc-slider-e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,20 @@ import {Component} from '@angular/core';

@Component({
selector: 'mdc-slider-e2e',
template: `<mat-slider></mat-slider>`,
template: `
<mat-slider id="standard-slider">
<input aria-label="Standard slider" matSliderThumb>
</mat-slider>

<mat-slider id="disabled-slider" disabled>
<input aria-label="Disabled slider" matSliderThumb>
</mat-slider>

<mat-slider id="range-slider">
<input aria-label="Range slider start thumb" matSliderStartThumb>
<input aria-label="Range slider end thumb" matSliderEndThumb>
</mat-slider>
`,
})
export class MdcSliderE2e {
}
1 change: 1 addition & 0 deletions src/material-experimental/mdc-slider/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ ng_e2e_test_library(
deps = [
":mdc-slider",
"//src/cdk/testing/private/e2e",
"@npm//@material/slider",
],
)

Expand Down
124 changes: 119 additions & 5 deletions src/material-experimental/mdc-slider/slider.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,125 @@
* 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;
beforeEach(() => { 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;
beforeEach(() => { 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;
beforeEach(() => { 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<number> {
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<void> {
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<void> {
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<Point> {
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 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
// 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};
}