diff --git a/e2e/process-services-cloud/form-field/task-visibility-condition.e2e.ts b/e2e/process-services-cloud/form-field/task-visibility-condition.e2e.ts index 49ef7e58b1..1f64fc1cd9 100644 --- a/e2e/process-services-cloud/form-field/task-visibility-condition.e2e.ts +++ b/e2e/process-services-cloud/form-field/task-visibility-condition.e2e.ts @@ -24,7 +24,7 @@ import { StringUtil, StartTasksCloudPage, TaskFormCloudComponent, - StartProcessPage + StartProcessCloudPage } from '@alfresco/adf-testing'; import { browser, by } from 'protractor'; @@ -39,7 +39,7 @@ describe('Task cloud visibility', async () => { const tasksCloudDemoPage = new TasksCloudDemoPage(); const startTask = new StartTasksCloudPage(); const taskFormCloudComponent = new TaskFormCloudComponent(); - const startProcessPage = new StartProcessPage(); + const startProcessPage = new StartProcessCloudPage(); const processCloudDemoPage = new ProcessCloudDemoPage(); const loginSSOPage = new LoginSSOPage(); @@ -103,7 +103,7 @@ describe('Task cloud visibility', async () => { await startProcessPage.selectFromProcessDropdown(browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.processes.numbervisibilityprocess); await startProcessPage.enterProcessName(processName); - await browser.sleep(400); + await startProcessPage.checkStartProcessButtonIsEnabled(); await startProcessPage.clickStartProcessButton(); await processCloudDemoPage.editProcessFilterCloudComponent().setFilter({ processName }); diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html index 3ff8222087..5c78f2b76f 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html @@ -78,7 +78,7 @@ - diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts index ab2bd83df1..7dab7f524d 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.spec.ts @@ -27,7 +27,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { TranslateModule, TranslateStore } from '@ngx-translate/core'; import { MatCardModule, MatOptionModule, MatAutocompleteModule, MatIconModule, MatButtonModule, MatFormFieldModule, MatInputModule, MatRippleModule, MatCommonModule } from '@angular/material'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { FormCloudModule } from 'process-services-cloud/src/lib/form/form-cloud.module'; +import { FormCloudModule } from '../../../form/form-cloud.module'; import { fakeProcessDefinitions, fakeStartForm, fakeStartFormNotValid, fakeProcessInstance, fakeNoNameProcessDefinitions, @@ -124,16 +124,18 @@ describe('StartProcessCloudComponent', () => { typeValueInto('#processName', 'OLE'); typeValueInto('#processDefinitionName', 'processwithoutform2'); fixture.detectChanges(); - fixture.whenStable(); tick(450); - const startBtn = fixture.nativeElement.querySelector('#button-start'); - expect(startBtn.disabled).toBe(false); - expect(component.isProcessFormValid()).toBe(true); - expect(createProcessSpy).toHaveBeenCalledWith('MyApp', new ProcessPayloadCloud({name: 'OLE', - processDefinitionKey: fakeProcessDefinitions[1].key})); - expect(component.currentCreatedProcess.status).toBe('CREATED'); - expect(component.currentCreatedProcess.startDate).toBeNull(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + const startBtn = fixture.nativeElement.querySelector('#button-start'); + expect(startBtn.disabled).toBe(false); + expect(component.isProcessFormValid()).toBe(true); + expect(createProcessSpy).toHaveBeenCalledWith('MyApp', new ProcessPayloadCloud({name: 'OLE', + processDefinitionKey: fakeProcessDefinitions[1].key})); + expect(component.currentCreatedProcess.status).toBe('CREATED'); + expect(component.currentCreatedProcess.startDate).toBeNull(); + }); })); it('should be able to start a process with a valid process name and process definition', async(() => { @@ -152,6 +154,28 @@ describe('StartProcessCloudComponent', () => { }); })); + it('should have start button disabled if create operation failed', fakeAsync(() => { + createProcessSpy.and.returnValue(throwError('fake error')); + const change = new SimpleChange(null, 'MyApp', true); + fixture.detectChanges(); + + component.ngOnChanges({ 'appName': change }); + fixture.detectChanges(); + tick(); + typeValueInto('#processName', 'OLE'); + typeValueInto('#processDefinitionName', 'processwithoutform2'); + fixture.detectChanges(); + tick(450); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + const startBtn = fixture.nativeElement.querySelector('#button-start'); + expect(startBtn.disabled).toBe(true); + expect(component.isProcessFormValid()).toBe(false); + expect(createProcessSpy).toHaveBeenCalledWith('MyApp', component.processPayloadCloud); + }); + })); + it('should have start button disabled when no process is selected', async(() => { component.name = ''; component.processDefinitionName = ''; @@ -191,7 +215,7 @@ describe('StartProcessCloudComponent', () => { component.name = 'My new process with form'; }); - it('should be able to start a process with a valid form', async(() => { + it('should be able to start a process with a valid form', fakeAsync(() => { component.processDefinitionName = 'processwithform'; getDefinitionsSpy.and.returnValue(of(fakeSingleProcessDefinition(component.processDefinitionName))); fixture.detectChanges(); @@ -200,8 +224,14 @@ describe('StartProcessCloudComponent', () => { const change = new SimpleChange(null, 'MyApp', true); component.ngOnChanges({ 'appName': change }); fixture.detectChanges(); + tick(); + typeValueInto('#processName', 'My new process with form'); + typeValueInto('#processDefinitionName', 'processwithform'); + fixture.detectChanges(); + tick(450); fixture.whenStable().then(() => { + fixture.detectChanges(); const firstNameEl = fixture.nativeElement.querySelector('#firstName'); expect(firstNameEl).toBeDefined(); const lastNameEl = fixture.nativeElement.querySelector('#lastName'); @@ -212,8 +242,7 @@ describe('StartProcessCloudComponent', () => { }); })); - it('should NOT be able to start a process with a form NOT valid', async(() => { - component.processDefinitionName = 'processwithform'; + it('should NOT be able to start a process with a form NOT valid', fakeAsync(() => { getDefinitionsSpy.and.returnValue(of(fakeSingleProcessDefinition(component.processDefinitionName))); fixture.detectChanges(); formDefinitionSpy = spyOn(formCloudService, 'getForm').and.returnValue(of(fakeStartFormNotValid)); @@ -222,7 +251,14 @@ describe('StartProcessCloudComponent', () => { component.ngOnChanges({ 'appName': change }); fixture.detectChanges(); + tick(); + typeValueInto('#processName', 'My new process with form'); + typeValueInto('#processDefinitionName', 'processwithform'); + fixture.detectChanges(); + tick(450); + fixture.whenStable().then(() => { + fixture.detectChanges(); const firstNameEl = fixture.nativeElement.querySelector('#firstName'); expect(firstNameEl).toBeDefined(); const lastNameEl = fixture.nativeElement.querySelector('#lastName'); @@ -233,7 +269,7 @@ describe('StartProcessCloudComponent', () => { }); })); - it('should be able to start a process with a prefilled valid form', async(() => { + it('should be able to start a process with a prefilled valid form', fakeAsync(() => { component.processDefinitionName = 'processwithform'; getDefinitionsSpy.and.returnValue(of(fakeSingleProcessDefinition(component.processDefinitionName))); component.values = [{'name': 'firstName', 'value': 'FakeName'}, {'name': 'lastName', 'value': 'FakeLastName'}]; @@ -244,7 +280,14 @@ describe('StartProcessCloudComponent', () => { component.ngOnChanges({ 'appName': change }); fixture.detectChanges(); + tick(); + typeValueInto('#processName', 'My new process with form'); + typeValueInto('#processDefinitionName', 'processwithform'); + fixture.detectChanges(); + tick(450); + fixture.whenStable().then(() => { + fixture.detectChanges(); const firstNameEl = fixture.nativeElement.querySelector('#firstName'); expect(firstNameEl).toBeDefined(); expect(firstNameEl.value).toEqual('FakeName'); @@ -293,17 +336,19 @@ describe('StartProcessCloudComponent', () => { const change = new SimpleChange(null, 'MyApp', true); component.ngOnChanges({ 'appName': change }); fixture.detectChanges(); - fixture.whenStable(); tick(450); - const startBtn = fixture.nativeElement.querySelector('#button-start'); - expect(startBtn.disabled).toBe(false); - expect(component.formCloud.isValid).toBe(true); - expect(component.isProcessFormValid()).toBe(true); - expect(createProcessSpy).toHaveBeenCalledWith('MyApp', new ProcessPayloadCloud({name: 'testFormWithProcess', - processDefinitionKey: fakeProcessDefinitions[1].key})); - expect(component.currentCreatedProcess.status).toBe('CREATED'); - expect(component.currentCreatedProcess.startDate).toBeNull(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + const startBtn = fixture.nativeElement.querySelector('#button-start'); + expect(startBtn.disabled).toBe(false); + expect(component.formCloud.isValid).toBe(true); + expect(component.isProcessFormValid()).toBe(true); + expect(createProcessSpy).toHaveBeenCalledWith('MyApp', new ProcessPayloadCloud({name: 'testFormWithProcess', + processDefinitionKey: fakeProcessDefinitions[1].key})); + expect(component.currentCreatedProcess.status).toBe('CREATED'); + expect(component.currentCreatedProcess.startDate).toBeNull(); + }); })); }); diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts index c565518252..41bda8fab4 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts @@ -26,7 +26,7 @@ import { FormControl, Validators, FormGroup, AbstractControl, FormBuilder, Valid import { FormModel, ContentLinkModel } from '@alfresco/adf-core'; import { MatAutocompleteTrigger } from '@angular/material'; import { ProcessPayloadCloud } from '../models/process-payload-cloud.model'; -import { debounceTime, takeUntil, switchMap, filter, distinctUntilChanged } from 'rxjs/operators'; +import { debounceTime, takeUntil, switchMap, filter, distinctUntilChanged, tap } from 'rxjs/operators'; import { ProcessDefinitionCloud } from '../models/process-definition-cloud.model'; import { Subject, Observable, concat } from 'rxjs'; import { TaskVariableCloud } from '../../../form/models/task-variable-cloud.model'; @@ -122,6 +122,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit, OnDestroy this.processForm.valueChanges .pipe( + tap(() => this.currentCreatedProcess = undefined), debounceTime(400), distinctUntilChanged(), filter(() => this.isProcessSelectionValid()), diff --git a/lib/testing/src/lib/process-services-cloud/pages/group-cloud-component.page.ts b/lib/testing/src/lib/process-services-cloud/pages/group-cloud-component.page.ts index 3876dee1d2..0b789794d5 100644 --- a/lib/testing/src/lib/process-services-cloud/pages/group-cloud-component.page.ts +++ b/lib/testing/src/lib/process-services-cloud/pages/group-cloud-component.page.ts @@ -39,19 +39,19 @@ export class GroupCloudComponentPage { } async selectGroupFromList(name: string): Promise { - const groupRow = element.all(by.cssContainingText('mat-option span', name)).first(); + const groupRow = element.all(by.css(`mat-option[data-automation-id="adf-cloud-group-chip-${name}"]`)).first(); await BrowserActions.click(groupRow); await BrowserVisibility.waitUntilElementIsNotVisible(groupRow); } async checkGroupIsDisplayed(name: string): Promise { - const groupRow = element.all(by.cssContainingText('mat-option span', name)).first(); + const groupRow = element.all(by.css(`mat-option[data-automation-id="adf-cloud-group-chip-${name}"]`)).first(); await BrowserVisibility.waitUntilElementIsVisible(groupRow); } async checkGroupIsNotDisplayed(name: string): Promise { - const groupRow = element.all(by.cssContainingText('mat-option span', name)).first(); + const groupRow = element.all(by.css(`mat-option[data-automation-id="adf-cloud-group-chip-${name}"]`)).first(); await BrowserVisibility.waitUntilElementIsNotVisible(groupRow); } diff --git a/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts b/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts index 3b04693dee..40863833a7 100644 --- a/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts +++ b/lib/testing/src/lib/process-services-cloud/pages/start-process-cloud-component.page.ts @@ -87,6 +87,7 @@ export class StartProcessCloudPage { } async checkStartProcessButtonIsEnabled(): Promise { + await browser.sleep(1000); // waiting for API response await BrowserVisibility.waitUntilElementIsPresent(this.startProcessButton); return this.startProcessButton.isEnabled(); } @@ -114,7 +115,6 @@ export class StartProcessCloudPage { await this.clearField(this.processNameInput); await this.enterProcessName(processName); await this.selectFromProcessDropdown(processDefinition); - await browser.sleep(4000); // remove this once AAE-2505 is fixed await this.checkStartProcessButtonIsEnabled(); await this.clickStartProcessButton(); }