Skip to content

Commit

Permalink
fix(material/tooltip): handle touch devices in test harness (#21220)
Browse files Browse the repository at this point in the history
`MatTooltip` binds either a mouse or a touch event, depending on whether it's on a touch device
or not. In the harnesses we were limited to dispatching only mouse events which meant that
tests couldn't be run against touch devices.

Now that we can fake any sort of event, we're able to support touch devices too.

(cherry picked from commit 24cbe1d)
  • Loading branch information
crisbeto authored and annieyw committed Feb 9, 2021
1 parent 4b63cfe commit 6ae8f62
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 30 deletions.
1 change: 0 additions & 1 deletion src/material/tooltip/testing/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ ng_test_library(
srcs = ["shared.spec.ts"],
deps = [
":testing",
"//src/cdk/platform",
"//src/cdk/testing",
"//src/cdk/testing/testbed",
"//src/material/tooltip",
Expand Down
28 changes: 0 additions & 28 deletions src/material/tooltip/testing/shared.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@ import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatTooltipHarness} from '@angular/material/tooltip/testing/tooltip-harness';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {Platform} from '@angular/cdk/platform';

/** Shared tests to run on both the original and MDC-based tooltips. */
export function runHarnessTests(
tooltipModule: typeof MatTooltipModule, tooltipHarness: typeof MatTooltipHarness) {
// TODO(COMP-322): whether the current test device is supported by the harness. At the time of
// writing, we have to skip these tests on touch devices, because we don't have a way of
// simulating touch events. This variable should be removed once the issue is resolved.
let isSupported: boolean;
let fixture: ComponentFixture<TooltipHarnessTest>;
let loader: HarnessLoader;

Expand All @@ -26,36 +21,21 @@ export function runHarnessTests(
fixture = TestBed.createComponent(TooltipHarnessTest);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);

const platform = TestBed.inject(Platform);
isSupported = !platform.IOS && !platform.ANDROID;
});

it('should load all tooltip harnesses', async () => {
if (!isSupported) {
return;
}

const tooltips = await loader.getAllHarnesses(tooltipHarness);
expect(tooltips.length).toBe(2);
});

it('should be able to show a tooltip', async () => {
if (!isSupported) {
return;
}

const tooltip = await loader.getHarness(tooltipHarness.with({selector: '#one'}));
expect(await tooltip.isOpen()).toBe(false);
await tooltip.show();
expect(await tooltip.isOpen()).toBe(true);
});

it('should be able to hide a tooltip', async () => {
if (!isSupported) {
return;
}

const tooltip = await loader.getHarness(tooltipHarness.with({selector: '#one'}));
expect(await tooltip.isOpen()).toBe(false);
await tooltip.show();
Expand All @@ -65,20 +45,12 @@ export function runHarnessTests(
});

it('should be able to get the text of a tooltip', async () => {
if (!isSupported) {
return;
}

const tooltip = await loader.getHarness(tooltipHarness.with({selector: '#one'}));
await tooltip.show();
expect(await tooltip.getTooltipText()).toBe('Tooltip message');
});

it('should return empty when getting the tooltip text while closed', async () => {
if (!isSupported) {
return;
}

const tooltip = await loader.getHarness(tooltipHarness.with({selector: '#one'}));
expect(await tooltip.getTooltipText()).toBe('');
});
Expand Down
14 changes: 13 additions & 1 deletion src/material/tooltip/testing/tooltip-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,24 @@ export class MatTooltipHarness extends ComponentHarness {

/** Shows the tooltip. */
async show(): Promise<void> {
return (await this.host()).hover();
const host = await this.host();

// We need to dispatch both `touchstart` and a hover event, because the tooltip binds
// different events depending on the device. The `changedTouches` is there in case the
// element has ripples.
// @breaking-change 12.0.0 Remove null assertion from `dispatchEvent`.
await host.dispatchEvent?.('touchstart', {changedTouches: []});
await host.hover();
}

/** Hides the tooltip. */
async hide(): Promise<void> {
const host = await this.host();

// We need to dispatch both `touchstart` and a hover event, because
// the tooltip binds different events depending on the device.
// @breaking-change 12.0.0 Remove null assertion from `dispatchEvent`.
await host.dispatchEvent?.('touchend');
await host.mouseAway();
await this.forceStabilize(); // Needed in order to flush the `hide` animation.
}
Expand Down

0 comments on commit 6ae8f62

Please sign in to comment.