Skip to content

Commit

Permalink
feat(Breadcrumb): implementa componente Breadcrumb
Browse files Browse the repository at this point in the history
ref #46
  • Loading branch information
Mario Traetta authored and ciccio86 committed Aug 31, 2018
1 parent eab2898 commit 829d5bc
Show file tree
Hide file tree
Showing 27 changed files with 823 additions and 2 deletions.
99 changes: 99 additions & 0 deletions e2e/src/breadcrumb/breadcrumb.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { ElementFinder } from 'protractor';
import { BreadcrumbPage } from './breadcrumb.po';

describe('Breadcrumb', () => {
let page: BreadcrumbPage;

beforeEach(async() => {
page = new BreadcrumbPage();
await page.go();
});

it('dovrebbe iniziare con uno sfondo scuro per poi essere cambiato ad uno chiaro', async () => {
expect(await page.hasDarkBackground()).toBeTruthy();

await page.clickBackgroundCheckbox();

expect(await page.hasDarkBackground()).toBeFalsy();

await page.clickBackgroundCheckbox();

expect(await page.hasDarkBackground()).toBeTruthy();
});

it('dovrebbe avere un ultimo elemento con relative classe active', async () => {
const breadcrumbItems: ElementFinder[] = await page.getBreadcrumbItems();
expect(breadcrumbItems.length).toBe(3);

let lastItem: ElementFinder;
breadcrumbItems.forEach(async(item, i, array) => {
const isLastItem = page.isLastItem(item);
if (i === array.length - 1) {
expect(isLastItem).toBeTruthy();
} else {
expect(isLastItem).toBeFalsy();
}
});

lastItem = breadcrumbItems[breadcrumbItems.length - 1];

page.clickAddButton();

let isLast = page.isLastItem(lastItem);
expect(isLast).toBeFalsy();

page.clickRemoveButton();

isLast = page.isLastItem(lastItem);
expect(isLast).toBeTruthy();
});

it('dovrebbe poter cambiare il separatore per tutti i suoi elementi', async () => {
const breadcrumbItems: ElementFinder[] = await page.getBreadcrumbItems();
const breadcrumbItemsSeparators: ElementFinder[] = await page.getBreadcrumbItemsSeparator();
expect(breadcrumbItemsSeparators.length).toBe(breadcrumbItems.length - 1);

const SLASH_SEPARATOR = '/';
breadcrumbItemsSeparators.forEach(item => {
expect(item.getText()).toBe(SLASH_SEPARATOR);
});

page.clickGthanSeparator();

const GTHAN_SEPARATOR = '>';
breadcrumbItemsSeparators.forEach(item => {
expect(item.getText()).toBe(GTHAN_SEPARATOR);
});

page.clickTildeSeparator();

const TILDE_SEPARATOR = '~';
breadcrumbItemsSeparators.forEach(item => {
expect(item.getText()).toBe(TILDE_SEPARATOR);
});
});

it('dovrebbe poter cambiare l\'icona o disattivarla per tutti i suoi elementi', async () => {
const breadcrumbItemsIcons: ElementFinder[] = await page.getBreadcrumbItemsIcon();

const FAVORITE_ICON = 'it-favorite';
breadcrumbItemsIcons.forEach(item => {
expect(item.getAttribute('class')).toBe(FAVORITE_ICON);
});

page.clickFacebookIcon();

const LINK_ICON = 'it-link';
breadcrumbItemsIcons.forEach(item => {
expect(item.getAttribute('class')).toBe(LINK_ICON);
});

page.clickFlickrIcon();

const ICON_NONE = '';
breadcrumbItemsIcons.forEach(item => {
expect(item.getAttribute('class')).toBe(ICON_NONE);
});
});

});
118 changes: 118 additions & 0 deletions e2e/src/breadcrumb/breadcrumb.po.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { browser, by, element, ElementFinder } from 'protractor';

export class BreadcrumbPage {
private readonly BREADCRUMB_URL = '/#/componenti/breadcrumb';
private readonly ID_EXAMPLE_TAB = 'breadcrumb-examples-tab';

private readonly ID_BREADCRUMB = 'it-breadcrumb-0';

private readonly ID_CHECKBOX_BG = 'checkbox-0';

private readonly ID_BUTTON_ADD = 'add-button';
private readonly ID_BUTTON_REMOVE = 'remove-button';

private readonly ID_RADIO_SEPARATOR_SLASH = 'radio-1';
private readonly ID_RADIO_SEPARATOR_GTHAN = 'radio-2';
private readonly ID_RADIO_SEPARATOR_TILDE = 'radio-3';

private readonly ID_RADIO_ICON_IT_FAVORITE = 'radio-4';
private readonly ID_RADIO_ICON_IT_FACEBOOK = 'radio-5';
private readonly ID_RADIO_ICON_IT_FLICKR = 'radio-6';

private readonly CSS_SELECTOR_LABEL_DARK_BG = this.getLabelForAttribute(this.ID_CHECKBOX_BG);

private readonly CSS_SELECTOR_LABEL_SLASH = this.getLabelForAttribute(this.ID_RADIO_SEPARATOR_SLASH);

private readonly CSS_SELECTOR_LABEL_GTHAN = this.getLabelForAttribute(this.ID_RADIO_SEPARATOR_GTHAN);

private readonly CSS_SELECTOR_LABEL_TILDE = this.getLabelForAttribute(this.ID_RADIO_SEPARATOR_TILDE);

private readonly CSS_SELECTOR_LABEL_FAVORITE = this.getLabelForAttribute(this.ID_RADIO_ICON_IT_FAVORITE);

private readonly CSS_SELECTOR_LABEL_FACEBOOK = this.getLabelForAttribute(this.ID_RADIO_ICON_IT_FACEBOOK);

private readonly CSS_SELECTOR_LABEL_FLICKR = this.getLabelForAttribute(this.ID_RADIO_ICON_IT_FLICKR);

async go() {
await browser.get(this.BREADCRUMB_URL);
await element(by.id(this.ID_EXAMPLE_TAB)).click();
return await browser.sleep(500);
}

async isLastItem(el: ElementFinder) {
const classes = await this.getBreadcrumbItemClasses(el);
return classes.indexOf('active') > -1;
}

async getBreadcrumbClasses() {
const classes = await element(by.css('.breadcrumb')).getAttribute('class');
return classes.split(' ');
}

async getBreadcrumbItems() {
return await this.getElementById(this.ID_BREADCRUMB).all(by.css('.breadcrumb-item'));
}

async getBreadcrumbItemClasses(item: ElementFinder) {
const classes = await item.getAttribute('class');
return classes.split(' ');
}

async getBreadcrumbItemsSeparator() {
return await this.getElementById(this.ID_BREADCRUMB).all(by.css('.separator'));
}

async getBreadcrumbItemsIcon() {
return await this.getElementById(this.ID_BREADCRUMB).all(by.css('.icon'));
}

async clickAddButton() {
await this.getElementById(this.ID_BUTTON_ADD).click();
}

async clickRemoveButton() {
await this.getElementById(this.ID_BUTTON_REMOVE).click();
}

async clickBackgroundCheckbox() {
await element(by.css(this.CSS_SELECTOR_LABEL_DARK_BG)).click();
}

async clickSlashSeparator() {
await element(by.css(this.CSS_SELECTOR_LABEL_SLASH)).click();
}

async clickGthanSeparator() {
await element(by.css(this.CSS_SELECTOR_LABEL_GTHAN)).click();
}

async clickTildeSeparator() {
await element(by.css(this.CSS_SELECTOR_LABEL_TILDE)).click();
}

async clickFavoriteIcon() {
await element(by.css(this.CSS_SELECTOR_LABEL_FAVORITE)).click();
}

async clickFacebookIcon() {
await element(by.css(this.CSS_SELECTOR_LABEL_FACEBOOK)).click();
}

async clickFlickrIcon() {
await element(by.css(this.CSS_SELECTOR_LABEL_FLICKR)).click();
}

async hasDarkBackground() {
const classes = await this.getBreadcrumbClasses();
return classes.indexOf('dark') > -1;
}

private getElementById(id) {
return element(by.id(id));
}

private getLabelForAttribute(attr: string) {
return `[for="${attr}"]`;
}

}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<li [class]="breadcrumbClass" [id]="id">
<i [class]="icon" *ngIf="icon"></i>
<a [href]="link">
<ng-content></ng-content>
</a> <span class="separator" *ngIf="!isLast">{{separator}}</span>
</li>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Component, OnInit, Input, ElementRef, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';

let identifier = 0;

@Component({
selector: 'it-breadcrumb-item',
templateUrl: './breadcrumb-item.component.html',
styleUrls: ['./breadcrumb-item.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class BreadcrumbItemComponent {
id = `it-breadcrumb-item-${identifier++}`;

constructor(private _cdRef: ChangeDetectorRef, private _elemRef: ElementRef) { }

/**
* Il link alla pagina verso cui andare al click di questo elemento del breadcrumb
*/
@Input()
get link(): string { return this._link; }
set link(value: string) { this._link = value; }
private _link: string;

/**
* La classe dell'icona da usare prima del testo dell'elemento del breadcrumb
*/
@Input()
get icon(): string { return this._icon; }
set icon(value: string) { this._icon = value; }
private _icon: string;

get separator(): string { return this._separator; }
set separator(value: string) { this._separator = value; }
private _separator: string;

get isLast(): boolean { return this._isLast; }
set isLast(value: boolean) {
this._isLast = value;
const breadcrumbItem = this._elemRef.nativeElement.querySelector('.breadcrumb-item');
if (this._isLast) {
breadcrumbItem.setAttribute('aria-current', 'page');
} else {
if (breadcrumbItem.hasAttribute('aria-current')) {
breadcrumbItem.removeAttribute('aria-current');
}
}
this._cdRef.detectChanges();
}
private _isLast = false;

get breadcrumbClass() {
return 'breadcrumb-item' + (this.isLast ? ' active' : '');
}

}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<nav class="breadcrumb-container" aria-label="breadcrumb" [id]="id">
<ol [ngClass]="breadcrumbClass">
<ng-content></ng-content>
</ol>
</nav>
Loading

0 comments on commit 829d5bc

Please sign in to comment.