0

I am writing a test with Angular11/Protractor which fills a registration form and then submits it to the backend server. The test expects that the server will respond with an HTTP 400 Bad Request error "Email already exists". (and this is the correct behavior of the backend)

However the test will always fail because angular will throw an error from zone-evergreen.js that I can't seem to catch:

zone-evergreen.js:2845 POST http://localhost:3000/users/register 400 (Bad Request)

How can I catch that error or prevent it from disturbing this end-to-end test?

Here is the Protractor code:

  it('it should not allow the user to register with same email address', async () => {
    // navigate to registration page by clicking on the "sign up" button
    element(by.css('a[routerLink="/auth/registration"]')).click();
    await browser.wait(EC.urlContains('http://localhost:4200/auth/registration'))
    expect(browser.getCurrentUrl()).toEqual('http://localhost:4200/auth/registration');

    // fill up the form again
    page.getRegisterFullNameInput().sendKeys(accountFullName)
    page.getRegisterEmailInput().sendKeys(accountEmail)
    page.getRegisterPasswordInput().sendKeys(accountPassword)
    page.getRegisterRepeatPasswordInput().sendKeys(accountPassword)
    page.getTermsAndConditionsCheckBox().click()

    // submit the form
    page.getRegisterSubmitButton().click()

    // wait for toastr, should throw an error
    await browser.wait(EC.visibilityOf(element(by.css('.toast-message'))));
    expect(page.getToastrMessage()).toContain('Email already registered')
  })

Full Stack Trace in Chrome:

scheduleTask    @   zone-evergreen.js:2845
scheduleTask    @   zone-evergreen.js:385
onScheduleTask  @   zone-evergreen.js:272
scheduleTask    @   zone-evergreen.js:378
scheduleTask    @   zone-evergreen.js:210
scheduleMacroTask   @   zone-evergreen.js:233
scheduleMacroTaskWithCurrentZone    @   zone-evergreen.js:1134
(anonymous) @   zone-evergreen.js:2878
proto.<computed>    @   zone-evergreen.js:1449
(anonymous) @   http.js:1785
_trySubscribe   @   Observable.js:42
subscribe   @   Observable.js:28
call    @   tap.js:16
subscribe   @   Observable.js:23
call    @   catchError.js:14
subscribe   @   Observable.js:23
innerSubscribe  @   innerSubscribe.js:67
_innerSub   @   mergeMap.js:57
_tryNext    @   mergeMap.js:51
_next   @   mergeMap.js:34
next    @   Subscriber.js:49
(anonymous) @   subscribeToArray.js:3
_trySubscribe   @   Observable.js:42
subscribe   @   Observable.js:28
call    @   mergeMap.js:19
subscribe   @   Observable.js:23
call    @   filter.js:13
subscribe   @   Observable.js:23
call    @   map.js:16
subscribe   @   Observable.js:23
call    @   map.js:16
subscribe   @   Observable.js:23
call    @   switchMap.js:15
subscribe   @   Observable.js:23
call    @   catchError.js:14
subscribe   @   Observable.js:23
call    @   finalize.js:11
subscribe   @   Observable.js:23
call    @   take.js:22
subscribe   @   Observable.js:23
call    @   throwIfEmpty.js:13
subscribe   @   Observable.js:23
submit  @   registration.component.ts:118
RegistrationComponent_Template_form_ngSubmit_1_listener @   registration.component.html:9
executeListenerWithErrorHandling    @   core.js:14994
wrapListenerIn_markDirtyAndPreventDefault   @   core.js:15029
schedulerFn @   core.js:25687
__tryOrUnsub    @   Subscriber.js:183
next    @   Subscriber.js:122
_next   @   Subscriber.js:72
next    @   Subscriber.js:49
next    @   Subject.js:39
emit    @   core.js:25656
onSubmit    @   forms.js:5719
FormGroupDirective_submit_HostBindingHandler    @   forms.js:5774
executeListenerWithErrorHandling    @   core.js:14994
wrapListenerIn_markDirtyAndPreventDefault   @   core.js:15029
(anonymous) @   platform-browser.js:582
invokeTask  @   zone-evergreen.js:399
onInvokeTask    @   core.js:28289
invokeTask  @   zone-evergreen.js:398
runTask @   zone-evergreen.js:167
invokeTask  @   zone-evergreen.js:480
invokeTask  @   zone-evergreen.js:1621
globalZoneAwareCallback @   zone-evergreen.js:1647
edrakali
  • 155
  • 1
  • 5
  • Recommendation is to avoid tests that have multiple paths. Here's what I would do: 1. Bring up a full test environment including the account service to register users. This will allow every new registration to always work. 2. Not have this specific e2e test. You can test if the button works for an existing account. You could have a unit test that mocks out calls to registering a new account or attempting to register an already existing account. – cnishina Aug 15 '21 at 09:17
  • Also looking at your test, you are using async / await which is great. I'm confused with the `page.getRegisterFullNameInput().sendKeys(accountFullName)` calls (and other page.foo calls) and how these are not awaited? – cnishina Aug 15 '21 at 09:18
  • They seem to work just fine without the async/await myself. I am not 100% sure why. The example that comes with a fresh Angular project also does not await for element() calls – edrakali Aug 15 '21 at 12:41
  • Hmmm.... possibly you are very lucky that your calls are returning in order. If they start to flake, it might be good to await some of these calls. – cnishina Aug 16 '21 at 09:12

0 Answers0