Skip to content

Commit

Permalink
fix(search): fix tests some time not passing on search (#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
nnixaa committed Jan 31, 2018
1 parent 618cb01 commit 254ddd3
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 66 deletions.
14 changes: 12 additions & 2 deletions e2e/search.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { browser, element, by } from 'protractor';
import { hasClass } from './e2e-helper';
import { protractor } from 'protractor/built/ptor';

const EC = protractor.ExpectedConditions;

describe('nb-search', () => {

beforeEach((done) => {
Expand Down Expand Up @@ -76,7 +78,11 @@ describe('nb-search', () => {
it('should display default hint', () => {
element(by.css('.start-search')).click();
expect(element(by.css('.show .search span'))).toBeTruthy();
expect(element(by.css('.show .search span')).getText()).toContain('Hit enter to search');

const spanEl = element(by.css('.show .search span'));
const text = 'Hit enter to search';
browser.wait(EC.textToBePresentInElement(spanEl, text), 5000);
expect(spanEl.getText()).toContain(text);
});

it('should display default placeholder', () => {
Expand All @@ -94,7 +100,11 @@ describe('nb-search-customized', () => {
it('should display customised hint', () => {
element(by.css('.start-search')).click();
expect(element(by.css('.show .search span'))).toBeTruthy();
expect(element(by.css('.show .search span')).getText()).toContain('Custom hint');

const spanEl = element(by.css('.show .search span'));
const text = 'Custom hint';
browser.wait(EC.textToBePresentInElement(spanEl, text), 5000);
expect(spanEl.getText()).toContain(text);
});

it('should display customised placeholder', () => {
Expand Down
146 changes: 82 additions & 64 deletions src/framework/theme/components/search/search.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,27 @@
*/

import {
Component, ChangeDetectionStrategy, Input, HostBinding,
ComponentRef, Output, EventEmitter, ViewChild, ElementRef, AfterViewInit, ComponentFactoryResolver, ViewContainerRef,
OnDestroy, OnInit,
AfterViewInit,
ChangeDetectionStrategy,
Component,
ComponentRef,
ElementRef,
EventEmitter,
HostBinding,
Input,
OnDestroy,
OnInit,
Output,
ViewChild,
ViewContainerRef,
} from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { NavigationEnd, Router } from '@angular/router';

import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Subscription } from 'rxjs/Subscription';
import { filter } from 'rxjs/operators/filter';
import { of as observableOf } from 'rxjs/observable/of';
import { combineLatest } from 'rxjs/observable/combineLatest';
import { delay } from 'rxjs/operators/delay';

import { NbSearchService } from './search.service';
Expand All @@ -37,19 +48,19 @@ import { NbThemeService } from '../../services/theme.service';
'styles/search.component.modal-half.scss',
],
template: `
<div class="search" (keyup.esc)="closeSearch()" >
<div class="search" (keyup.esc)="closeSearch()">
<button (click)="closeSearch()">
<i class="nb-close-circled"></i>
</button>
<div class="form-wrapper">
<form class="form" (keyup.enter)="submitSearch(searchInput.value)">
<div class="form-content">
<input class="search-input"
#searchInput
autocomplete="off"
[attr.placeholder]="placeholder"
tabindex="-1"
(blur)="tabOut.next($event)"/>
#searchInput
autocomplete="off"
[attr.placeholder]="placeholder"
tabindex="-1"
(blur)="tabOut.next($event)"/>
</div>
<span class="info">{{ hint }}</span>
</form>
Expand Down Expand Up @@ -181,18 +192,18 @@ export class NbSearchComponent implements OnInit, AfterViewInit, OnDestroy {

@HostBinding('class.show') showSearch: boolean = false;

@ViewChild('attachedSearchContainer', { read: ViewContainerRef }) attachedSearchContainer: ViewContainerRef;
@ViewChild('attachedSearchContainer', {read: ViewContainerRef}) attachedSearchContainer: ViewContainerRef;

private searchFieldComponentRef: ComponentRef<any> = null;
private searchFieldComponentRef$ = new BehaviorSubject<ComponentRef<any>>(null);
private searchType: string = 'rotate-layout';
private activateSearchSubscription: Subscription;
private deactivateSearchSubscription: Subscription;
private routerSubscription: Subscription;

constructor(private searchService: NbSearchService,
private themeService: NbThemeService,
private componentFactoryResolver: ComponentFactoryResolver,
private router: Router) { }
private themeService: NbThemeService,
private router: Router) {
}

/**
* Search design type, available types are
Expand All @@ -204,70 +215,52 @@ export class NbSearchComponent implements OnInit, AfterViewInit, OnDestroy {
this.searchType = val;
}

openSearch() {
this.searchService.activateSearch(this.searchType, this.tag);
}

connectToSearchField(componentRef) {
this.searchFieldComponentRef = componentRef;
componentRef.instance.searchType = this.searchType;
componentRef.instance.placeholder = this.placeholder;
componentRef.instance.hint = this.hint;
componentRef.instance.searchClose.subscribe(() => {
this.searchService.deactivateSearch(this.searchType, this.tag);
});

componentRef.instance.search.subscribe(term => {
this.searchService.submitSearch(term, this.tag);
this.searchService.deactivateSearch(this.searchType, this.tag);
});

componentRef.instance.tabOut
.subscribe(() => this.showSearch && this.searchFieldComponentRef.instance.inputElement.nativeElement.focus());

componentRef.changeDetectorRef.detectChanges();
}

createAttachedSearch(component): Observable<any> {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
const componentRef = this.attachedSearchContainer.createComponent(componentFactory);

return observableOf(componentRef);
}

ngOnInit() {
this.routerSubscription = this.router.events
.pipe(
filter(event => event instanceof NavigationEnd),
)
.subscribe(event => this.searchService.deactivateSearch(this.searchType, this.tag));

this.activateSearchSubscription = this.searchService.onSearchActivate().subscribe((data) => {
if (!this.tag || data.tag === this.tag) {
combineLatest([
this.searchFieldComponentRef$,
this.searchService.onSearchActivate(),
])
.pipe(
filter(([componentRef, data]: [ComponentRef<any>, any]) => !this.tag || data.tag === this.tag),
)
.subscribe(([componentRef]: [ComponentRef<any>]) => {
this.showSearch = true;

this.themeService.appendLayoutClass(this.searchType);
observableOf(null).pipe(delay(0)).subscribe(() => {
this.themeService.appendLayoutClass('with-search');
});
this.searchFieldComponentRef.instance.showSearch = true;
this.searchFieldComponentRef.instance.inputElement.nativeElement.focus();
this.searchFieldComponentRef.changeDetectorRef.detectChanges();
}
});
componentRef.instance.showSearch = true;
componentRef.instance.inputElement.nativeElement.focus();
componentRef.changeDetectorRef.detectChanges();
});

this.deactivateSearchSubscription = this.searchService.onSearchDeactivate().subscribe((data) => {
if (!this.tag || data.tag === this.tag) {
combineLatest([
this.searchFieldComponentRef$,
this.searchService.onSearchDeactivate(),
])
.pipe(
filter(([componentRef, data]: [ComponentRef<any>, any]) => !this.tag || data.tag === this.tag),
)
.subscribe(([componentRef]: [ComponentRef<any>]) => {
this.showSearch = false;
this.searchFieldComponentRef.instance.showSearch = false;
this.searchFieldComponentRef.instance.inputElement.nativeElement.value = '';
this.searchFieldComponentRef.instance.inputElement.nativeElement.blur();
this.searchFieldComponentRef.changeDetectorRef.detectChanges();

componentRef.instance.showSearch = false;
componentRef.instance.inputElement.nativeElement.value = '';
componentRef.instance.inputElement.nativeElement.blur();
componentRef.changeDetectorRef.detectChanges();

this.themeService.removeLayoutClass('with-search');
observableOf(null).pipe(delay(500)).subscribe(() => {
this.themeService.removeLayoutClass(this.searchType);
});
}
});
});
}

ngAfterViewInit() {
Expand All @@ -277,12 +270,37 @@ export class NbSearchComponent implements OnInit, AfterViewInit, OnDestroy {
});
}

openSearch() {
this.searchService.activateSearch(this.searchType, this.tag);
}

connectToSearchField(componentRef) {
componentRef.instance.searchType = this.searchType;
componentRef.instance.placeholder = this.placeholder;
componentRef.instance.hint = this.hint;
componentRef.instance.searchClose.subscribe(() => {
this.searchService.deactivateSearch(this.searchType, this.tag);
});
componentRef.instance.search.subscribe(term => {
this.searchService.submitSearch(term, this.tag);
this.searchService.deactivateSearch(this.searchType, this.tag);
});
componentRef.instance.tabOut
.subscribe(() => this.showSearch && componentRef.instance.inputElement.nativeElement.focus());

componentRef.changeDetectorRef.detectChanges();

this.searchFieldComponentRef$.next(componentRef)
}

ngOnDestroy() {
this.activateSearchSubscription.unsubscribe();
this.deactivateSearchSubscription.unsubscribe();
this.routerSubscription.unsubscribe();
if (this.searchFieldComponentRef) {
this.searchFieldComponentRef.destroy();

const componentRef = this.searchFieldComponentRef$.getValue();
if (componentRef) {
componentRef.destroy();
}
}
}

0 comments on commit 254ddd3

Please sign in to comment.