Skip to content

Commit

Permalink
replace getSelectorForContent with getHarnessLoaderForContent
Browse files Browse the repository at this point in the history
  • Loading branch information
mmalerba committed Oct 16, 2019
1 parent 72bceae commit 497e7eb
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 14 deletions.
23 changes: 23 additions & 0 deletions src/cdk/testing/component-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,29 @@ export interface LocatorFactory {
locatorForAll<T extends ComponentHarness>(
harnessType: ComponentHarnessConstructor<T> | HarnessPredicate<T>): AsyncFactoryFn<T[]>;

/**
* Gets a `HarnessLoader` instance for an element under the root of this `LocatorFactory`.
* @param selector The selector for the root element.
* @return A `HarnessLoader` rooted at the first element matching the given selector.
* @throws If no matching element is found for the given selector.
*/
harnessLoaderFor(selector: string): Promise<HarnessLoader>;

/**
* Gets a `HarnessLoader` instance for an element under the root of this `LocatorFactory`
* @param selector The selector for the root element.
* @return A `HarnessLoader` rooted at the first element matching the given selector, or null if
* no matching element is found.
*/
harnessLoaderForOptional(selector: string): Promise<HarnessLoader | null>;

/**
* Gets a list of `HarnessLoader` instances, one for each matching element.
* @param selector The selector for the root element.
* @return A list of `HarnessLoader`, one rooted at each element matching the given selector.
*/
harnessLoaderForAll(selector: string): Promise<HarnessLoader[]>;

/**
* Flushes change detection and async tasks.
* In most cases it should not be necessary to call this manually. However, there may be some edge
Expand Down
17 changes: 17 additions & 0 deletions src/cdk/testing/harness-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ export abstract class HarnessEnvironment<E> implements HarnessLoader, LocatorFac
};
}

// Implemented as part of the `LocatorFactory` interface.
async harnessLoaderFor(selector: string): Promise<HarnessLoader> {
return this.createEnvironment(await this._assertElementFound(selector));
}

// Implemented as part of the `LocatorFactory` interface.
async harnessLoaderForOptional(selector: string): Promise<HarnessLoader | null> {
const elements = await this.getAllRawElements(selector);
return elements[0] && this.createEnvironment(elements[0]);
}

// Implemented as part of the `LocatorFactory` interface.
async harnessLoaderForAll(selector: string): Promise<HarnessLoader[]> {
const elements = await this.getAllRawElements(selector);
return elements.map(element => this.createEnvironment(element));
}

// Implemented as part of the `HarnessLoader` interface.
getHarness<T extends ComponentHarness>(
harnessType: ComponentHarnessConstructor<T> | HarnessPredicate<T>): Promise<T> {
Expand Down
24 changes: 16 additions & 8 deletions src/material/tabs/testing/shared.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {expectAsyncError} from '@angular/cdk/private/testing';
import {HarnessLoader} from '@angular/cdk/testing';
import {ComponentHarness, HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {Component} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
Expand Down Expand Up @@ -96,12 +96,12 @@ export function runHarnessTests(
expect(await tabs[2].getAriaLabelledby()).toBe('tabLabelId');
});

it('should be able to get content element of active tab', async () => {
it('should be able to get harness loader for content element of active tab', async () => {
const tabGroup = await loader.getHarness(tabGroupHarness);
const tabs = await tabGroup.getTabs();
const contentSelector = await tabs[0].getSelectorForContent();
const contentEl = document.querySelector(contentSelector) as HTMLElement;
expect(contentEl.innerText.trim()).toBe('Content 1');
const tabContentLoader = await tabs[0].getHarnessLoaderForContent();
const tabContentHarness = await tabContentLoader.getHarness(TestTabContentHarness);
expect(await (await tabContentHarness.host()).text()).toBe('Content 1');
});

it('should be able to get disabled state of tab', async () => {
Expand Down Expand Up @@ -153,15 +153,23 @@ export function runHarnessTests(
@Component({
template: `
<mat-tab-group>
<mat-tab label="First" aria-label="First tab">Content 1</mat-tab>
<mat-tab label="Second" aria-label="Second tab">Content 2</mat-tab>
<mat-tab label="First" aria-label="First tab">
<span class="test-tab-content">Content 1</span>
</mat-tab>
<mat-tab label="Second" aria-label="Second tab">
<span class="test-tab-content">Content 2</span>
</mat-tab>
<mat-tab label="Third" aria-labelledby="tabLabelId" [disabled]="isDisabled">
<ng-template matTabLabel>Third</ng-template>
Content 3
<span class="test-tab-content">Content 3</span>
</mat-tab>
</mat-tab-group>
`
})
class TabGroupHarnessTest {
isDisabled = false;
}

class TestTabContentHarness extends ComponentHarness {
static hostSelector = '.test-tab-content';
}
15 changes: 9 additions & 6 deletions src/material/tabs/testing/tab-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {ComponentHarness, HarnessPredicate, TestElement} from '@angular/cdk/testing';
import {ComponentHarness, HarnessLoader, HarnessPredicate} from '@angular/cdk/testing';
import {TabHarnessFilters} from './tab-harness-filters';

/**
Expand All @@ -25,8 +25,6 @@ export class MatTabHarness extends ComponentHarness {
(harness, label) => HarnessPredicate.stringMatches(harness.getLabel(), label));
}

private _rootLocatorFactory = this.documentRootLocatorFactory();

/** Gets the label of the tab. */
async getLabel(): Promise<string> {
return (await this.host()).text();
Expand Down Expand Up @@ -62,10 +60,15 @@ export class MatTabHarness extends ComponentHarness {
await (await this.host()).click();
}

/** Gets a selector that can be used to locate the tab's content element. */
async getSelectorForContent(): Promise<string> {
async getHarnessLoaderForContent(): Promise<HarnessLoader> {
const contentId = await this._getContentId();
return this.documentRootLocatorFactory().harnessLoaderFor(`#${contentId}`);
}

/** Gets the element id for the content of the current tab. */
private async _getContentId(): Promise<string> {
const hostEl = await this.host();
// Tabs never have an empty "aria-controls" attribute.
return '#' + await hostEl.getAttribute('aria-controls');
return (await hostEl.getAttribute('aria-controls'))!;
}
}

0 comments on commit 497e7eb

Please sign in to comment.