Optimize Component tests; Fix e2e execution
parent
704f426eea
commit
38a53b4001
|
@ -13,6 +13,7 @@ export class TaskEditPage extends AbstractHeaderPage {
|
||||||
assigneeName = element(by.id('assignee_name'));
|
assigneeName = element(by.id('assignee_name'));
|
||||||
assigneeEmail = element(by.id('assignee_email'));
|
assigneeEmail = element(by.id('assignee_email'));
|
||||||
saveButton = element(by.id('save'));
|
saveButton = element(by.id('save'));
|
||||||
|
cancelButton = element(by.id('cancel'));
|
||||||
|
|
||||||
constructor(newTask: boolean) {
|
constructor(newTask: boolean) {
|
||||||
super();
|
super();
|
||||||
|
@ -56,7 +57,12 @@ export class TaskEditPage extends AbstractHeaderPage {
|
||||||
return new TaskOverviewPage;
|
return new TaskOverviewPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
validateInput(elementId: string, value: string) {
|
cancelSubmitTask() : TaskOverviewPage {
|
||||||
|
this.cancelButton.click();
|
||||||
|
return new TaskOverviewPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
static validateInput(elementId: string, value: string) {
|
||||||
const input = element(by.id(elementId));
|
const input = element(by.id(elementId));
|
||||||
expect(input.getAttribute('value')).toBe(value);
|
expect(input.getAttribute('value')).toBe(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ describe('Edit Task Form', function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const newTitle = 'Ersten Prototyp mit Angular 4.0 entwickelt';
|
||||||
|
|
||||||
it('should load task with its values in edit form', () => {
|
it('should load task with its values in edit form', () => {
|
||||||
browser.get('/tasks');
|
browser.get('/tasks');
|
||||||
const taskOverviewPage = new TaskOverviewPage;
|
const taskOverviewPage = new TaskOverviewPage;
|
||||||
|
@ -23,16 +25,15 @@ describe('Edit Task Form', function () {
|
||||||
const taskEditPage = taskOverviewPage.clickTask(dbTask.title);
|
const taskEditPage = taskOverviewPage.clickTask(dbTask.title);
|
||||||
// check for correct url - test input field values
|
// check for correct url - test input field values
|
||||||
taskEditPage.validateCurrentUrl('tasks/edit/' + dbTask.id);
|
taskEditPage.validateCurrentUrl('tasks/edit/' + dbTask.id);
|
||||||
taskEditPage.validateInput('title', dbTask.title);
|
TaskEditPage.validateInput('title', dbTask.title);
|
||||||
taskEditPage.validateInput('description', dbTask.description);
|
TaskEditPage.validateInput('description', dbTask.description);
|
||||||
taskEditPage.validateInput('state', dbTask.state);
|
TaskEditPage.validateInput('state', dbTask.state);
|
||||||
taskEditPage.validateInput('assignee_name', dbTask.assignee['name'])
|
TaskEditPage.validateInput('assignee_name', dbTask.assignee['name'])
|
||||||
taskEditPage.validateInput('assignee_email', dbTask.assignee['email'])
|
TaskEditPage.validateInput('assignee_email', dbTask.assignee['email'])
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have updated title in overview after edit, but same task id as before', () => {
|
it('should have updated title in overview after edit, but same task id as before', () => {
|
||||||
browser.get('/tasks/edit/' + dbTask.id);
|
browser.get('/tasks/edit/' + dbTask.id);
|
||||||
const newTitle = 'Ersten Prototyp mit Angular 4.0 entwickelt';
|
|
||||||
const taskEditPage = new TaskEditPage(false);
|
const taskEditPage = new TaskEditPage(false);
|
||||||
taskEditPage.clearEnterTitle(newTitle);
|
taskEditPage.clearEnterTitle(newTitle);
|
||||||
let taskOverviewPage = taskEditPage.submitTaskForm();
|
let taskOverviewPage = taskEditPage.submitTaskForm();
|
||||||
|
@ -41,5 +42,12 @@ describe('Edit Task Form', function () {
|
||||||
taskOverviewPage.clickTask(newTitle).validateCurrentUrl('tasks/edit/' + dbTask.id);
|
taskOverviewPage.clickTask(newTitle).validateCurrentUrl('tasks/edit/' + dbTask.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have return to Overview after cancel button click', () => {
|
||||||
|
browser.get('/tasks/edit/' + dbTask.id);
|
||||||
|
const taskEditPage = new TaskEditPage(false);
|
||||||
|
const taskOverviewPage = taskEditPage.cancelSubmitTask();
|
||||||
|
taskOverviewPage.verifyNewTask(newTitle);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "concurrently \"node projects-server/server.js db=projects-server/db.json\" \"ng serve\" ",
|
"start": "concurrently \"node projects-server/server.js db=projects-server/db.json\" \"ng serve\" ",
|
||||||
"starte2e": "concurrently \"node projects-server/server.js db=projects-server/test.json\" \"ng serve --env=e2e\" ",
|
"starte2e": "cp ./projects-server/safe/test.json ./projects-server/test.json && concurrently \"node projects-server/server.js db=projects-server/test.json\" \"ng serve --env=e2e\" ",
|
||||||
"lint": "tslint \"src/**/*.ts\" --project src/tsconfig.json --type-check && tslint \"e2e/**/*.ts\" --project e2e/tsconfig.json --type-check",
|
"lint": "tslint \"src/**/*.ts\" --project src/tsconfig.json --type-check && tslint \"e2e/**/*.ts\" --project e2e/tsconfig.json --type-check",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"pree2e": "cp ./projects-server/safe/test.json ./projects-server/test.json && webdriver-manager update --standalone false --gecko false",
|
"pree2e": "webdriver-manager update --standalone false --gecko false",
|
||||||
"e2e": "concurrently \"node projects-server/server.js db=projects-server/test.json\" \"ng e2e --env=e2e\" ",
|
"e2e": "cp ./projects-server/safe/test.json ./projects-server/test.json && concurrently \"node projects-server/server.js db=projects-server/test.json\" \"ng e2e --env=e2e\" ",
|
||||||
"install-server": "npm install --prefix ./projects-server ./projects-server",
|
"install-server": "npm install --prefix ./projects-server ./projects-server",
|
||||||
"e2e-screenshots": "protractor ./protractor-html-reporter.conf.js",
|
"e2e-screenshots": "protractor ./protractor-html-reporter.conf.js",
|
||||||
"postinstall": "npm run install-server"
|
"postinstall": "npm run install-server"
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {BlogEntryComponent} from "./blog-entry.component";
|
||||||
import {BlogEntry} from "./blog-entry";
|
import {BlogEntry} from "./blog-entry";
|
||||||
import {BlogComponent} from "../blog.component";
|
import {BlogComponent} from "../blog.component";
|
||||||
import {RouterTestingModule} from "@angular/router/testing";
|
import {RouterTestingModule} from "@angular/router/testing";
|
||||||
import {Component} from "@angular/core";
|
import {MockBlogComponent} from "../../mocks/mock-blog.component";
|
||||||
|
|
||||||
describe('Blog Entry Isolated Test', () => {
|
describe('Blog Entry Isolated Test', () => {
|
||||||
|
|
||||||
|
@ -52,38 +52,12 @@ describe('Blog Entry Isolated Test', () => {
|
||||||
|
|
||||||
const blogDelete = element.querySelector('div /deep/ .blog-delete > button').textContent;
|
const blogDelete = element.querySelector('div /deep/ .blog-delete > button').textContent;
|
||||||
expect(blogDelete).toBe("Entfernen")
|
expect(blogDelete).toBe("Entfernen")
|
||||||
|
|
||||||
// keine Überprüfung der id, die lediglich im EventListener des Delete Button hinterlegt ist, möglich!
|
|
||||||
// nur durch click-Event auslösen, was jedoch BlogComponent vorraussetzt
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('BlogEntryComp -> BlogComp Dependent Test', () => {
|
describe('BlogEntryComp -> BlogComp Dependent Test', () => {
|
||||||
|
|
||||||
|
|
||||||
it('should remove entry from BlogComponent on "delete" button click', () => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [BlogEntryComponent, MockBlogComponent]
|
|
||||||
});
|
|
||||||
|
|
||||||
const entryFixture = TestBed.createComponent(BlogEntryComponent);
|
|
||||||
const entryInstance: BlogEntryComponent = entryFixture.componentInstance;
|
|
||||||
|
|
||||||
const blogFixture = TestBed.createComponent(MockBlogComponent);
|
|
||||||
|
|
||||||
const blogInstance: any = blogFixture.componentInstance;
|
|
||||||
|
|
||||||
const blogEntry: BlogEntry = blogInstance.entries[0];
|
|
||||||
entryInstance.entry = blogEntry;
|
|
||||||
entryInstance.blogComponent = blogInstance;
|
|
||||||
|
|
||||||
const oldLength = blogInstance.entries.length;
|
|
||||||
entryFixture.nativeElement.querySelector('div /deep/ .blog-delete > button').click();
|
|
||||||
expect(blogInstance.entries.length).toBe(oldLength - 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove entry from BlogComponent on "delete" button click : OVERRIDE BLOG TEMPLATE', () => {
|
it('should remove entry from BlogComponent on "delete" button click : OVERRIDE BLOG TEMPLATE', () => {
|
||||||
|
|
||||||
TestBed.overrideComponent(BlogComponent, {
|
TestBed.overrideComponent(BlogComponent, {
|
||||||
|
@ -103,34 +77,45 @@ describe('Blog Entry Isolated Test', () => {
|
||||||
const blogFixture = TestBed.createComponent(BlogComponent);
|
const blogFixture = TestBed.createComponent(BlogComponent);
|
||||||
const blogInstance: BlogComponent = blogFixture.componentInstance;
|
const blogInstance: BlogComponent = blogFixture.componentInstance;
|
||||||
|
|
||||||
const blogEntry: BlogEntry = blogInstance.entries[0];
|
entryInstance.entry = blogInstance.entries[0];
|
||||||
entryInstance.entry = blogEntry;
|
|
||||||
entryInstance.blogComponent = blogInstance;
|
entryInstance.blogComponent = blogInstance;
|
||||||
|
|
||||||
const oldLength = blogInstance.entries.length;
|
const oldLength = blogInstance.entries.length;
|
||||||
entryFixture.nativeElement.querySelector('div /deep/ .blog-delete > button').click();
|
entryFixture.nativeElement.querySelector('div /deep/ .blog-delete > button').click();
|
||||||
expect(blogInstance.entries.length).toBe(oldLength - 1);
|
expect(blogInstance.entries.length).toBe(oldLength - 1);
|
||||||
});
|
|
||||||
|
|
||||||
});
|
for (let entry in blogInstance.entries) {
|
||||||
|
expect(entry).not.toBe(entryInstance.entry);
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Mocked Blog Component
|
|
||||||
@Component({
|
|
||||||
selector: 'blog',
|
|
||||||
template: '<blog-entry></blog-entry>'
|
|
||||||
})
|
|
||||||
export class MockBlogComponent {
|
|
||||||
|
|
||||||
entries = [{}, {}];
|
|
||||||
|
|
||||||
deleteBlogEntry(id) {
|
|
||||||
this.entries.splice(0, 1);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove entry from BlogComponent on "delete" button click : MOCK BLOG COMPONENT', () => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [BlogEntryComponent, MockBlogComponent]
|
||||||
|
});
|
||||||
|
|
||||||
|
const entryFixture = TestBed.createComponent(BlogEntryComponent);
|
||||||
|
const entryInstance: BlogEntryComponent = entryFixture.componentInstance;
|
||||||
|
|
||||||
|
const blogFixture = TestBed.createComponent(MockBlogComponent);
|
||||||
|
const blogInstance: any = blogFixture.componentInstance;
|
||||||
|
|
||||||
|
entryInstance.entry = blogInstance.entries[0];
|
||||||
|
entryInstance.blogComponent = blogInstance;
|
||||||
|
|
||||||
|
const oldLength = blogInstance.entries.length;
|
||||||
|
entryFixture.nativeElement.querySelector('div /deep/ .blog-delete > button').click();
|
||||||
|
expect(blogInstance.entries.length).toBe(oldLength - 1);
|
||||||
|
for (let entry in blogInstance.entries) {
|
||||||
|
expect(entry).not.toBe(entryInstance.entry);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,10 @@ export class BlogComponent {
|
||||||
this.entries.push(entry);
|
this.entries.push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Löscht den Eintrag mit der gegebenen ID aus der Liste
|
||||||
|
* @param id - Objekt-ID des zu löschenden Eintrags
|
||||||
|
*/
|
||||||
deleteBlogEntry(id: number) {
|
deleteBlogEntry(id: number) {
|
||||||
let entryIndex = this.entries.findIndex(entry => entry.id === id);
|
let entryIndex = this.entries.findIndex(entry => entry.id === id);
|
||||||
if (entryIndex >= 0) {
|
if (entryIndex >= 0) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {LoginComponent} from "./login.component";
|
||||||
import {RouterTestingModule} from "@angular/router/testing";
|
import {RouterTestingModule} from "@angular/router/testing";
|
||||||
import {LoginService} from "../services/login-service/login-service";
|
import {LoginService} from "../services/login-service/login-service";
|
||||||
import {FormsModule} from "@angular/forms";
|
import {FormsModule} from "@angular/forms";
|
||||||
import {MockLoginService} from "../mocks/mock-login-service.spec";
|
import {MockEmptyClass} from "../mocks/mock-empty-class";
|
||||||
import Spy = jasmine.Spy;
|
import Spy = jasmine.Spy;
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,14 +14,13 @@ describe('Login Component Template Driven Form Test with Spy', () => {
|
||||||
imports: [FormsModule, RouterTestingModule.withRoutes([])],
|
imports: [FormsModule, RouterTestingModule.withRoutes([])],
|
||||||
declarations: [LoginComponent],
|
declarations: [LoginComponent],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: LoginService, useClass: MockLoginService}
|
{provide: LoginService, useClass: MockEmptyClass}
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should be possible to request login', () => {
|
it('should be possible to request login', () => {
|
||||||
|
|
||||||
const inputUser = 'testuser';
|
const inputUser = 'testuser';
|
||||||
const inputPass = 'testpass';
|
const inputPass = 'testpass';
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import {Component} from "@angular/core";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'blog',
|
||||||
|
template: '<blog-entry *ngFor="let entry of entries" [entry]="entry" [blogComponent]="this"></blog-entry>'
|
||||||
|
})
|
||||||
|
export class MockBlogComponent {
|
||||||
|
|
||||||
|
entries = [{id: 1}, {id: 2}];
|
||||||
|
|
||||||
|
deleteBlogEntry(id) {
|
||||||
|
this.entries.splice(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
export class MockEmptyClass {
|
||||||
|
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
export class MockLoginService {
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue