Skip to content

feat(material-experimental): add test harness for slider #16688

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 1 commit into from
Aug 16, 2019
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
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@
# Note to implementer: please repossess
/src/material-experimental/mdc-radio/** @mmalerba
/src/material-experimental/mdc-slide-toggle/** @crisbeto
# Note to implementer: please repossess
/src/material-experimental/mdc-slider/** @devversion
/src/material-experimental/mdc-tabs/** @crisbeto
/src/material-experimental/mdc-theming/** @mmalerba
/src/material-experimental/mdc-typography/** @mmalerba
Expand Down
17 changes: 17 additions & 0 deletions src/cdk-experimental/testing/element-dimensions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

/**
* Dimensions for element size and its position relative to the viewport.
*/
export interface ElementDimensions {
top: number;
left: number;
width: number;
height: number;
}
14 changes: 12 additions & 2 deletions src/cdk-experimental/testing/protractor/protractor-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import {ModifierKeys} from '@angular/cdk/testing';
import {browser, ElementFinder, Key} from 'protractor';
import {ElementDimensions} from '../element-dimensions';
import {TestElement, TestKey} from '../test-element';

/** Maps the `TestKey` constants to Protractor's `Key` constants. */
Expand Down Expand Up @@ -74,8 +75,11 @@ export class ProtractorElement implements TestElement {
return this.element.clear();
}

async click(): Promise<void> {
return this.element.click();
async click(relativeX = 0, relativeY = 0): Promise<void> {
await browser.actions()
.mouseMove(await this.element.getWebElement(), {x: relativeX, y: relativeY})
.click()
.perform();
}

async focus(): Promise<void> {
Expand Down Expand Up @@ -126,4 +130,10 @@ export class ProtractorElement implements TestElement {
const classes = (await this.getAttribute('class')) || '';
return new Set(classes.split(/\s+/).filter(c => c)).has(name);
}

async getDimensions(): Promise<ElementDimensions> {
const {width, height} = await this.element.getSize();
const {x: left, y: top} = await this.element.getLocation();
return {width, height, left, top};
}
}
13 changes: 10 additions & 3 deletions src/cdk-experimental/testing/test-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/

/** Keyboard keys that do not result in input characters. */
import {ModifierKeys} from '@angular/cdk/testing';
import {ElementDimensions} from './element-dimensions';

/** An enum of non-text keys that can be used with the `sendKeys` method. */
// NOTE: This is a separate enum from `@angular/cdk/keycodes` because we don't necessarily want to
Expand Down Expand Up @@ -59,8 +59,12 @@ export interface TestElement {
/** Clear the element's input (for input elements only). */
clear(): Promise<void>;

/** Click the element. */
click(): Promise<void>;
/**
* Click the element.
* @param relativeX Coordinate within the element, along the X-axis at which to click.
* @param relativeY Coordinate within the element, along the Y-axis at which to click.
*/
click(relativeX?: number, relativeY?: number): Promise<void>;

/** Focus the element. */
focus(): Promise<void>;
Expand Down Expand Up @@ -94,4 +98,7 @@ export interface TestElement {

/** Checks whether the element has the given class. */
hasClass(name: string): Promise<boolean>;

/** Gets the dimensions of the element. */
getDimensions(): Promise<ElementDimensions>;
}
17 changes: 15 additions & 2 deletions src/cdk-experimental/testing/testbed/unit-test-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
typeInElement
} from '@angular/cdk/testing';
import {TestElement, TestKey} from '../test-element';
import {ElementDimensions} from '../element-dimensions';

/** Maps `TestKey` constants to the `keyCode` and `key` values used by native browser events. */
const keyMap = {
Expand Down Expand Up @@ -71,9 +72,16 @@ export class UnitTestElement implements TestElement {
await this._stabilize();
}

async click(): Promise<void> {
async click(relativeX = 0, relativeY = 0): Promise<void> {
await this._stabilize();
dispatchMouseEvent(this.element, 'click');
const {left, top} = this.element.getBoundingClientRect();
// Round the computed click position as decimal pixels are not
// supported by mouse events and could lead to unexpected results.
const clientX = Math.round(left + relativeX);
const clientY = Math.round(top + relativeY);
dispatchMouseEvent(this.element, 'mousedown', clientX, clientY);
dispatchMouseEvent(this.element, 'mouseup', clientX, clientY);
dispatchMouseEvent(this.element, 'click', clientX, clientY);
await this._stabilize();
}

Expand Down Expand Up @@ -126,4 +134,9 @@ export class UnitTestElement implements TestElement {
await this._stabilize();
return this.element.classList.contains(name);
}

async getDimensions(): Promise<ElementDimensions> {
await this._stabilize();
return this.element.getBoundingClientRect();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export class MainComponentHarness extends ComponentHarness {
readonly allLabels = this.locatorForAll('label');
readonly allLists = this.locatorForAll(SubComponentHarness);
readonly memo = this.locatorFor('textarea');
readonly clickTest = this.locatorFor('.click-test');
readonly clickTestResult = this.locatorFor('.click-test-result');
// Allow null for element
readonly nullItem = this.locatorForOptional('wrong locator');
// Allow null for component harness
Expand All @@ -36,7 +38,7 @@ export class MainComponentHarness extends ComponentHarness {
readonly errorGlobalEl = this.documentRootLocatorFactory().locatorFor('wrong locator');
readonly nullGlobalEl = this.documentRootLocatorFactory().locatorForOptional('wrong locator');

readonly optionalDiv = this.locatorForOptional('div');
readonly optionalUsername = this.locatorForOptional('#username');
readonly optionalSubComponent = this.locatorForOptional(SubComponentHarness);
readonly errorSubComponent = this.locatorFor(WrongComponentHarness);

Expand Down
16 changes: 14 additions & 2 deletions src/cdk-experimental/testing/tests/protractor.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ describe('ProtractorHarnessEnvironment', () => {
});

it('should locate an optional element based on CSS selector', async () => {
const present = await harness.optionalDiv();
const present = await harness.optionalUsername();
const missing = await harness.nullItem();
expect(present).not.toBeNull();
expect(await present!.text()).toBe('Hello Yi from Angular 2!');
Expand Down Expand Up @@ -192,6 +192,13 @@ describe('ProtractorHarnessEnvironment', () => {
expect(await counter.text()).toBe('3');
});

it('should be able to click at a specific position within an element', async () => {
const clickTest = await harness.clickTest();
const clickTestResult = await harness.clickTestResult();
await clickTest.click(50, 50);
expect(await clickTestResult.text()).toBe('50-50');
});

it('should be able to send key', async () => {
const input = await harness.input();
const value = await harness.value();
Expand All @@ -208,6 +215,11 @@ describe('ProtractorHarnessEnvironment', () => {
.toBe(await browser.driver.switchTo().activeElement().getAttribute('id'));
});

it('should be able to retrieve dimensions', async () => {
const dimensions = await (await harness.title()).getDimensions();
expect(dimensions).toEqual(jasmine.objectContaining({height: 100, width: 200}));
});

it('should be able to hover', async () => {
const host = await harness.host();
let classAttr = await host.getAttribute('class');
Expand All @@ -229,7 +241,7 @@ describe('ProtractorHarnessEnvironment', () => {

it('should be able to getCssValue', async () => {
const title = await harness.title();
expect(await title.getCssValue('height')).toBe('50px');
expect(await title.getCssValue('height')).toBe('100px');
});

it('should focus and blur element', async () => {
Expand Down
7 changes: 6 additions & 1 deletion src/cdk-experimental/testing/tests/test-main-component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
<h1 style="height: 50px">Main Component</h1>
<div class="click-test" (click)="onClick($event)"
style="width: 100px; height: 100px; background: grey"
#clickTestElement>
</div>
<div class="click-test-result">{{relativeX}}-{{relativeY}}</div>
<h1 style="height: 100px; width: 200px;">Main Component</h1>
<div id="username">Hello {{username}} from Angular 2!</div>
<div class="counters">
<button (click)="click()">Up</button><br>
Expand Down
12 changes: 12 additions & 0 deletions src/cdk-experimental/testing/tests/test-main-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
ViewChild,
ViewEncapsulation
} from '@angular/core';

Expand All @@ -37,6 +39,10 @@ export class TestMainComponent {
testMethods: string[];
_isHovering: boolean;
specialKey = '';
relativeX = 0;
relativeY = 0;

@ViewChild('clickTestElement', {static: false}) clickTestElement: ElementRef<HTMLElement>;

onMouseOver() {
this._isHovering = true;
Expand Down Expand Up @@ -75,4 +81,10 @@ export class TestMainComponent {
this.specialKey = 'alt-j';
}
}

onClick(event: MouseEvent) {
const {top, left} = this.clickTestElement.nativeElement.getBoundingClientRect();
this.relativeX = Math.round(event.clientX - left);
this.relativeY = Math.round(event.clientY - top);
}
}
16 changes: 14 additions & 2 deletions src/cdk-experimental/testing/tests/testbed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ describe('TestbedHarnessEnvironment', () => {
});

it('should locate an optional element based on CSS selector', async () => {
const present = await harness.optionalDiv();
const present = await harness.optionalUsername();
const missing = await harness.nullItem();
expect(present).not.toBeNull();
expect(await present!.text()).toBe('Hello Yi from Angular 2!');
Expand Down Expand Up @@ -212,6 +212,13 @@ describe('TestbedHarnessEnvironment', () => {
expect(await counter.text()).toBe('3');
});

it('should be able to click at a specific position within an element', async () => {
const clickTest = await harness.clickTest();
const clickTestResult = await harness.clickTestResult();
await clickTest.click(50, 50);
expect(await clickTestResult.text()).toBe('50-50');
});

it('should be able to send key', async () => {
const input = await harness.input();
const value = await harness.value();
Expand All @@ -227,6 +234,11 @@ describe('TestbedHarnessEnvironment', () => {
expect(await input.getAttribute('id')).toBe(document.activeElement!.id);
});

it('should be able to retrieve dimensions', async () => {
const dimensions = await (await harness.title()).getDimensions();
expect(dimensions).toEqual(jasmine.objectContaining({height: 100, width: 200}));
});

it('should be able to hover', async () => {
const host = await harness.host();
let classAttr = await host.getAttribute('class');
Expand All @@ -248,7 +260,7 @@ describe('TestbedHarnessEnvironment', () => {

it('should be able to getCssValue', async () => {
const title = await harness.title();
expect(await title.getCssValue('height')).toBe('50px');
expect(await title.getCssValue('height')).toBe('100px');
});

it('should focus and blur element', async () => {
Expand Down
31 changes: 31 additions & 0 deletions src/material-experimental/mdc-slider/harness/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])

load("//tools:defaults.bzl", "ng_test_library", "ng_web_test_suite", "ts_library")

ts_library(
name = "harness",
srcs = glob(
["**/*.ts"],
exclude = ["**/*.spec.ts"],
),
deps = [
"//src/cdk-experimental/testing",
"//src/cdk/coercion",
],
)

ng_test_library(
name = "harness_tests",
srcs = glob(["**/*.spec.ts"]),
deps = [
":harness",
"//src/cdk-experimental/testing",
"//src/cdk-experimental/testing/testbed",
"//src/material/slider",
],
)

ng_web_test_suite(
name = "tests",
deps = [":harness_tests"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

export type SliderHarnessFilters = {
id?: string;
};
Loading