mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
@@ -0,0 +1,97 @@
|
||||
import ElementArrayFinder = protractor.ElementArrayFinder;
|
||||
import ElementFinder = protractor.ElementFinder;
|
||||
|
||||
describe('tabs', () => {
|
||||
describe('basic behavior', () => {
|
||||
let tabGroup: ElementFinder;
|
||||
let tabLabels: ElementArrayFinder;
|
||||
let tabBodies: ElementArrayFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/tabs');
|
||||
tabGroup = element(by.css('md-tab-group'));
|
||||
tabLabels = element.all(by.css('.md-tab-label'));
|
||||
tabBodies = element.all(by.css('.md-tab-body'));
|
||||
});
|
||||
|
||||
it('should change tabs when the label is clicked', () => {
|
||||
tabLabels.get(1).click();
|
||||
expect(getActiveStates(tabLabels)).toEqual([false, true, false]);
|
||||
expect(getActiveStates(tabBodies)).toEqual([false, true, false]);
|
||||
|
||||
tabLabels.get(0).click();
|
||||
expect(getActiveStates(tabLabels)).toEqual([true, false, false]);
|
||||
expect(getActiveStates(tabBodies)).toEqual([true, false, false]);
|
||||
});
|
||||
|
||||
it('should change focus with keyboard interaction', () => {
|
||||
tabLabels.get(0).click();
|
||||
expect(getFocusStates(tabLabels)).toEqual([true, false, false]);
|
||||
|
||||
pressKey(protractor.Key.RIGHT);
|
||||
expect(getFocusStates(tabLabels)).toEqual([false, true, false]);
|
||||
|
||||
pressKey(protractor.Key.RIGHT);
|
||||
expect(getFocusStates(tabLabels)).toEqual([false, false, true]);
|
||||
|
||||
pressKey(protractor.Key.RIGHT);
|
||||
expect(getFocusStates(tabLabels)).toEqual([false, false, true]);
|
||||
|
||||
pressKey(protractor.Key.LEFT);
|
||||
expect(getFocusStates(tabLabels)).toEqual([false, true, false]);
|
||||
|
||||
pressKey(protractor.Key.LEFT);
|
||||
expect(getFocusStates(tabLabels)).toEqual([true, false, false]);
|
||||
|
||||
pressKey(protractor.Key.LEFT);
|
||||
expect(getFocusStates(tabLabels)).toEqual([true, false, false]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* A helper function to perform the sendKey action
|
||||
* @param key
|
||||
*/
|
||||
function pressKey(key: string) {
|
||||
browser.actions().sendKeys(key).perform();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of true/false that represents the focus states of the provided elements
|
||||
* @param elements
|
||||
* @returns {webdriver.promise.Promise<Promise<boolean>[]>|webdriver.promise.Promise<T[]>}
|
||||
*/
|
||||
function getFocusStates(elements: ElementArrayFinder) {
|
||||
return elements.map(element => {
|
||||
return element.getText().then(elementText => {
|
||||
return browser.driver.switchTo().activeElement().getText().then(activeText => {
|
||||
return activeText === elementText;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of true/false that represents the active states for the provided elements
|
||||
* @param elements
|
||||
* @returns {webdriver.promise.Promise<Promise<boolean>[]>|webdriver.promise.Promise<T[]>}
|
||||
*/
|
||||
function getActiveStates(elements: ElementArrayFinder) {
|
||||
return getClassStates(elements, 'md-active');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of true/false values that represents whether the provided className is on
|
||||
* each element
|
||||
* @param elements
|
||||
* @param className
|
||||
* @returns {webdriver.promise.Promise<Promise<boolean>[]>|webdriver.promise.Promise<T[]>}
|
||||
*/
|
||||
function getClassStates(elements: ElementArrayFinder, className: string) {
|
||||
return elements.map(element => {
|
||||
return element.getAttribute('class').then(classes => {
|
||||
return classes.split(/ +/g).indexOf(className) >= 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
<div class="md-tab-header" role="tablist"
|
||||
(keydown.arrowRight)="focusNextTab()"
|
||||
(keydown.arrowLeft)="focusPreviousTab()"
|
||||
(keydown.enter)="selectedIndex = focusIndex">
|
||||
(keydown)="handleKeydown($event)">
|
||||
<div class="md-tab-label" role="tab" md-tab-label-wrapper
|
||||
*ngFor="let tab of _tabs; let i = index"
|
||||
[id]="_getTabLabelId(i)"
|
||||
@@ -16,10 +14,13 @@
|
||||
</div>
|
||||
<div class="md-tab-body-wrapper">
|
||||
<div class="md-tab-body"
|
||||
*ngFor="let tab of tabs; let i = index"
|
||||
[id]="getTabContentId(i)"
|
||||
role="tabpanel"
|
||||
*ngFor="let tab of _tabs; let i = index"
|
||||
[id]="_getTabContentId(i)"
|
||||
[class.md-active]="selectedIndex == i"
|
||||
[attr.aria-labelledby]="getTabLabelId(i)">
|
||||
<template role="tabpanel" [portalHost]="tab.content" [ngIf]="selectedIndex == i"></template>
|
||||
[attr.aria-labelledby]="_getTabLabelId(i)">
|
||||
<template [ngIf]="selectedIndex == i">
|
||||
<template [portalHost]="tab.content"></template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,14 @@ import {MdInkBar} from './ink-bar';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
// Due to a bug in the ChromeDriver, Angular 2 keyboard events are not triggered by `sendKeys`
|
||||
// during E2E tests when using dot notation such as `(keydown.rightArrow)`. To get around this,
|
||||
// we are temporarily using a single (keydown) handler.
|
||||
// See: https://github.com/angular/angular/issues/9419
|
||||
const RIGHT_ARROW = 39;
|
||||
const LEFT_ARROW = 37;
|
||||
const ENTER = 13;
|
||||
|
||||
/** Used to generate unique ID's for each tab component */
|
||||
let nextId = 0;
|
||||
|
||||
@@ -159,6 +167,20 @@ export class MdTabGroup {
|
||||
return `md-tab-content-${this._groupId}-${i}`;
|
||||
}
|
||||
|
||||
handleKeydown(event: KeyboardEvent) {
|
||||
switch (event.keyCode) {
|
||||
case RIGHT_ARROW:
|
||||
this.focusNextTab();
|
||||
break;
|
||||
case LEFT_ARROW:
|
||||
this.focusPreviousTab();
|
||||
break;
|
||||
case ENTER:
|
||||
this.selectedIndex = this.focusIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Increment the focus index by 1; prevent going over the number of tabs */
|
||||
focusNextTab(): void {
|
||||
if (this._labelWrappers && this.focusIndex < this._labelWrappers.length - 1) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<a md-list-item [routerLink]="['button']">Button</a>
|
||||
<a md-list-item [routerLink]="['tabs']">Tabs</a>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {ROUTER_DIRECTIVES} from '@angular/router';
|
||||
|
||||
import {Dir} from '@angular2-material/core/rtl/dir';
|
||||
import {MdButton} from '@angular2-material/button/button';
|
||||
import {MD_SIDENAV_DIRECTIVES} from '@angular2-material/sidenav/sidenav';
|
||||
import {MD_LIST_DIRECTIVES} from '@angular2-material/list/list';
|
||||
import {MdIcon} from '@angular2-material/icon/icon';
|
||||
import {MdToolbar} from '@angular2-material/toolbar/toolbar';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'home',
|
||||
template: `
|
||||
@@ -24,12 +16,6 @@ export class Home {}
|
||||
templateUrl: 'e2e-app.html',
|
||||
directives: [
|
||||
ROUTER_DIRECTIVES,
|
||||
Dir,
|
||||
MdButton,
|
||||
MdIcon,
|
||||
MD_SIDENAV_DIRECTIVES,
|
||||
MD_LIST_DIRECTIVES,
|
||||
MdToolbar
|
||||
],
|
||||
pipes: []
|
||||
})
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {provideRouter, RouterConfig} from '@angular/router';
|
||||
import {Home} from './e2e-app';
|
||||
import {ButtonE2E} from '../button/button-e2e';
|
||||
import {BasicTabs} from '../tabs/tabs-e2e';
|
||||
|
||||
|
||||
export const routes: RouterConfig = [
|
||||
{path: '', component: Home},
|
||||
{path: 'button', component: ButtonE2E},
|
||||
{path: 'tabs', component: BasicTabs},
|
||||
];
|
||||
|
||||
export const E2E_APP_ROUTE_PROVIDER = provideRouter(routes);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<section>
|
||||
<md-tab-group>
|
||||
<md-tab>
|
||||
<template md-tab-label>One</template>
|
||||
<template md-tab-content>First tab's content</template>
|
||||
</md-tab>
|
||||
<md-tab>
|
||||
<template md-tab-label>Two</template>
|
||||
<template md-tab-content>Second tab's content</template>
|
||||
</md-tab>
|
||||
<md-tab>
|
||||
<template md-tab-label>Three</template>
|
||||
<template md-tab-content>Third tab's content</template>
|
||||
</md-tab>
|
||||
</md-tab-group>
|
||||
</section>
|
||||
@@ -0,0 +1,10 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {MD_TABS_DIRECTIVES} from '@angular2-material/tabs/tabs';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'tabs-e2e',
|
||||
templateUrl: 'tabs-e2e.html',
|
||||
directives: [MD_TABS_DIRECTIVES]
|
||||
})
|
||||
export class BasicTabs {}
|
||||
Reference in New Issue
Block a user