const DEFAULT_LINK: string = '/';
const EMAIL: string = 'blablabla';
const PASSWORD: string = 'blablabla';
export class Auth {
constructor() {
browser.driver.manage().window().maximize();
browser.get(DEFAULT_LINK);
this.login();
}
login() {
browser.sleep(1000);
const email = element(by.css('input[formControlName=email]'));
const pass = element(by.css('input[formControlName=password]'));
const button = element(by.id('login'));
email.sendKeys(EMAIL);
pass.sendKeys(PASSWORD);
button.click();
browser.ignoreSynchronization = true;
browser.sleep(1000);
}
logout() {
browser.sleep(1000);
const buttonLogin = element(by.xpath('путь до кнопки выхода'));
const buttonConfirm = element(by.xpath('путь до кнопки подтверждения выхода'));
buttonLogout.click();
buttonConfirm.click();
browser.ignoreSynchronization = true;
browser.sleep(1000);
}
}
// imports
describe('Page test1', () => {
let auth: Auth;
let page: Page1;
beforeEach(() => {
auth = new Auth();
page = new Page1();
});
afterEach(() => {
auth.logout(); // Проверяем каждую страницу отдельно, поэтому после завершения теста страницы - разлогиниваемся
});
it('Test 1...', () => {
// некие тесты
});
});
<div>
<app-component><!-- Внутри флекс элементы --></app-component>
</div>
...
@Component({
selector: 'app-component',
templateUrl: '...',
host: {
'class': 'app-flex-style'
}
})
export class AppComponent {
....
}
{
"/api": {
"target": "http://НужныйАдрес:НужныйПротокол",
"secure": false
}
}
...
{path: '', component: Test1Component, canActivate: [AuthGuard], canActivateChild: [AuthGuard],
children: [
{path: 'test2', component: Test2Component, data: {title: 'Тест 2', roles: ['admin', 'user']}},
{path: 'test3', component: Test3Component, data: {title: 'Тест 3', roles: ['admin']}},
{path: 'test4', component: Test4Component, data: {title: 'Тест 4'}},
]
},
...
...
// canActivate единожды проверяет авторизован или нет
canActivateChild(route: ActivatedRouteSnapshot): Promise<boolean>|boolean {
let myRole = 'user'; // Получаем роль при инициализации приложения запросом на backend либо по своему усмотрению
let roles = route.data['roles'] as Array<string>;
if (!roles || roles.indexOf(myRole) != -1) return true;
else {
this.router.navigate(['']);
return false;
}
}
...
import { Component, Input } from "@angular/core";
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "@angular/forms";
@Component({
selector: 'test-input',
template: `<input type="text" [(ngModel)]="value" (blur)="onBlur()">`,
providers: [{provide: NG_VALUE_ACCESSOR, useExisting:TestInputComponent, multi: true}],
})
export class TestInputComponent implements ControlValueAccessor {
private innerValue: any = '';
private onTouchedCallback: () => void = () => {};
private onChangeCallback: (_: any) => void = () => {};
get value(): any { return this.innerValue; };
set value(v: any) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
onBlur() { this.onTouchedCallback(); }
writeValue(value: any) {
if (value !== this.innerValue)
this.innerValue = value;
}
registerOnChange(fn: any) { this.onChangeCallback = fn; }
registerOnTouched(fn: any) { this.onTouchedCallback = fn; }
// ... Другие любые действия которые нам нужны
}
<form [formGroup]="form">
<test-input formControlName="test"></test-input>
</form>
public onSubmit(value: any) {
let params = new FormData();
params.append('file', value.file);
// +другие необходимые параметры
this.testService.testRequest(params).subscribe(res => ...);
}
узнал про не меньшую востребованность первой версии
<div [@visibilityChanged]="visibility">
<router-outlet></router-outlet>
</div>
@Component({
selector: 'app-main-layout',
templateUrl: './main-layout.component.html',
animations: [
trigger('visibilityChanged', [
state('shown', style({opacity: 1, transform: 'translateY(0)'})),
state('hidden', style({opacity: 0, transform: 'translateY(10px)'})),
transition('hidden => shown', animate('.3s ease-out')),
]),
],
})
export class MainLayoutComponent {
visibility: string = 'hidden';
constructor(private router: Router) {
let el = this;
router.events.subscribe(event => {
if (event instanceof NavigationStart)
if (event.url != router.url)
el.visibility = 'hidden';
if (event instanceof NavigationEnd)
setTimeout(() => el.visibility = 'shown', 10);
});
}
}
interface IModuleMenuItem {
getName(): string;
}
class ModuleMenuItem implements IModuleMenuItem {
private name;
public getName() {
return name;
}
protected setName(newName : string) {
name = newName;
}
}
Есть ли подобные CLI?
Также интересно какой стиль иерархии приложения Angular 2 вы применяете?(где храните сервисы, компоненты, модели и тд)