Protractor Extension of ElementFinder

僤鯓⒐⒋嵵緔 提交于 2021-01-29 13:54:35

问题


I am trying to extend the ElementFinder of Protractor with a few additional methods. I am doing this exactly the same way I also extended other classes, where it works without any problem. In a separate file called 'protractor-extension.ts', both the module declaration and the method implementation is contained:

declare module 'protractor/built/element' {
  export interface ElementFinder {
      safeClick() : Promise<void>;
  }
}

(protractor.ElementFinderas any).safeClick= function () {
  const _self = this as protractor.ElementFinderas ;
   return await browser.wait(ExpectedConditions.elementToBeClickable(self), 5000)
      .then(function() {
          return self.click(); //if found
      }, function() {
          console.error(`Element is not clickable`); //error
      });
}

This file is then imported in the .spec file where the safeClick() is used, with "import './extensions/protractor-extension.ts';"

The function is recognized, and I immediately get it in code-completion when using it on any ElementFinder.

The problem: During runtime I always get "Failed: myButton.safeClick is not a function"

As I said, if I replace the whole example 1:1 with the moment.js example, it works. So it seems to be related to the ElementFinder in protractor? All existing posts related to this topic also suggest to do exactly what I have done, but most of them are outdated (<2 years old).

I appreciate any hint that leads me to the right solution.

EDIT: Here is how the extension methods are used:

1) In the page object, the elements are declared

export class AdminPage {

  /*  ELEMENTS  */
  public userTable =   element(by.id('userTable'));
  public unlockBtn = element(by.id('unlockBtn'));    
}

2) In the test (.spec file), the extension method is used

it('unlock button should disappear after click', async () => {
  await this.adminPage.unlockBtn.safeClick();
  expect(this.unlockBtn.isPresent()).toBeFalsy();
});

-> .safeClick() is autocompleted when writing "this.adminPage.unlockBtn.." -> .safeClick() is not recognized during runtime and throws an error


回答1:


I guess you use element() and element.all() in your script to declare web element on page.

element or all is instance of class ElementFinder, and both are created at very beginning of running test case.

If your above code executed behind of the creation of element and all, element and all won't includes the safeClick()

Following is protractor init procedure:

lib/cli.ts https://github.com/angular/protractor/blob/master/lib/cli.ts#L242

 --> lib/launcher.ts initFn()

  --> lib/launcher.ts createNextTaskRunner()

   --> lib/taskRunner.ts run()  https://github.com/angular/protractor/blob/master/lib/launcher.ts#L222

    --> lib/runner.ts run()    https://github.com/angular/protractor/blob/master/lib/runner.ts#L334

     --> lib/runner.ts createBrowser()       https://github.com/angular/protractor/blob/master/lib/browser.ts#L316

      --> lib/brower.ts ProtractorBrowser()  https://github.com/angular/protractor/blob/master/lib/runner.ts#L237
          // element created in this method

     --> lib/runner.ts setupGlobals_()     https://github.com/angular/protractor/blob/master/lib/runner.ts#L335
          // setup element, all, $$, browser in global space

As I learned, protractor did not provide something like hooks to enable user to do something prior to lib/runner.ts createBrowser(). If have, you can add your code in the hook.



来源:https://stackoverflow.com/questions/59239852/protractor-extension-of-elementfinder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!