typescriptprotractorangular-e2e

When should element.all(locator).then(thenFunction) or element.all(locator) be used?


In protractor, what's the difference between (source):

Example 1

const allOptions = element.all(by.options('fruit for fruit in fruits'));
expect(await allOptions.count()).toEqual(4);

and (source):

Example 2

const arr = await element.all(by.model('color'));
expect(arr.length).toEqual(3);

Why if I do...

Example 3

let allOptions = await element.all(by.css('.mat-option-text > span'));
let firstOption = allOptions.first();

...I get this static typescript error?

Property 'first' does not exist on type 'any[] | ElementFinder[]'. Property 'first' does not exist on type 'any[]'.ts(2339)


What is the correct usage of element.all(locator).then(thenFunction) and element.all(locator)?


Solution

  • Essentially, element.all returns an ElementArrayFinder object but await element.all will return an array of ElementFinder objects.

    An awaited ElementArrayFinder is simple an array of ElementFinder objects and therefore can call all existing array methods (such as length). An unawaited ElementArrayFinder is a special object defined withing protractor and has special methods available to it (such as count(), get() and first()).

    The methods available to ElementArrayFinder are listed in the protractor api.

    Example

    For this example go to the page https://angular.io/. $([class="button hero-cta"]) only finds one element on this page

    console.log(element.all('[class="button hero-cta"]')) will return the following ElementArrayFinder object

    ElementArrayFinder {
      browser_: ProtractorBrowser {
        controlFlow: [Function],
        schedule: [Function],
        setFileDetector: [Function],
        getExecutor: [Function],
        getSession: [Function],
        getCapabilities: [Function],
        quit: [Function],
        actions: [Function],
        touchActions: [Function],
        executeScript: [Function],
        executeAsyncScript: [Function],
        call: [Function],
        wait: [Function],
        sleep: [Function],
        getWindowHandle: [Function],
        getAllWindowHandles: [Function],
        getPageSource: [Function],
        close: [Function],
        getCurrentUrl: [Function],
        getTitle: [Function],
        findElementInternal_: [Function],
        findElementsInternal_: [Function],
        takeScreenshot: [Function],
        manage: [Function],
        switchTo: [Function],
        driver: thenableWebDriverProxy {
          flow_: [ControlFlow],
          session_: [ManagedPromise],
          executor_: [Executor],
          fileDetector_: null,
          onQuit_: undefined,
          cancel: [Function],
          then: [Function: bound then],
          catch: [Function: bound then],
          getNetworkConnection: [Function],
          setNetworkConnection: [Function],
          toggleAirplaneMode: [Function],
          toggleWiFi: [Function],
          toggleData: [Function],
          toggleLocationServices: [Function],
          getGeolocation: [Function],
          setGeolocation: [Function],
          getCurrentDeviceActivity: [Function],
          startDeviceActivity: [Function],
          getAppiumSettings: [Function],
          setAppiumSettings: [Function],
          getCurrentContext: [Function],
          selectContext: [Function],
          getScreenOrientation: [Function],
          setScreenOrientation: [Function],
          isDeviceLocked: [Function],
          lockDevice: [Function],
          unlockDevice: [Function],
          installApp: [Function],
          isAppInstalled: [Function],
          removeApp: [Function],
          pullFileFromDevice: [Function],
          pullFolderFromDevice: [Function],
          pushFileToDevice: [Function],
          listContexts: [Function],
          uploadFile: [Function],
          switchToParentFrame: [Function],
          fullscreen: [Function],
          sendAppToBackground: [Function],
          closeApp: [Function],
          getAppStrings: [Function],
          launchSession: [Function],
          resetApp: [Function],
          hideSoftKeyboard: [Function],
          getDeviceTime: [Function],
          openDeviceNotifications: [Function],
          rotationGesture: [Function],
          shakeDevice: [Function],
          sendChromiumCommand: [Function],
          sendChromiumCommandAndGetResult: [Function]
        },
        element: [Function: element] { all: [Function] },
        '$': [Function],
        '$$': [Function],
        baseUrl: '',
        getPageTimeout: 10000,
        params: {},
        resetUrl: 'data:text/html,<html></html>',
        debugHelper: DebugHelper { browserUnderDebug_: [Circular] },
        ready: ManagedPromise {
          flow_: [ControlFlow],
          stack_: null,
          parent_: null,
          callbacks_: null,
          state_: 'fulfilled',
          handled_: true,
          value_: [Circular],
          queue_: null
        },
        trackOutstandingTimeouts_: true,
        mockModules_: [ [Object] ],
        ExpectedConditions: ProtractorExpectedConditions { browser: [Circular] },
        plugins_: Plugins {
          setup: [Function],
          onPrepare: [Function],
          teardown: [Function],
          postResults: [Function],
          postTest: [Function],
          onPageLoad: [Function],
          onPageStable: [Function],
          waitForPromise: [Function],
          waitForCondition: [Function],
          pluginObjs: [],
          assertions: {},
          resultsReported: false
        },
        allScriptsTimeout: 11000,
        getProcessedConfig: [Function],
        forkNewDriverInstance: [Function],
        restart: [Function],
        restartSync: [Function],
        internalRootEl: '',
        internalIgnoreSynchronization: true
      },
      getWebElements: [Function: getWebElements],
      locator_: name(name) {
        return By.css('*[name="' + escapeCss(name) + '"]');
      } {
        using: 'css selector',
        value: '[class="button hero-cta"]'
      },
      actionResults_: null,
      click: [Function],
      sendKeys: [Function],
      getTagName: [Function],
      getCssValue: [Function],
      getAttribute: [Function],
      getText: [Function],
      getSize: [Function],
      getLocation: [Function],
      isEnabled: [Function],
      isSelected: [Function],
      submit: [Function],
      clear: [Function],
      isDisplayed: [Function],
      getId: [Function],
      takeScreenshot: [Function]
    }
    

    console.log(await element.all('[class="button hero-cta"]')) will return an array of ElementFinder Objects

    [
      ElementFinder {
        browser_: ProtractorBrowser {
          controlFlow: [Function],
          schedule: [Function],
          setFileDetector: [Function],
          getExecutor: [Function],
          getSession: [Function],
          getCapabilities: [Function],
          quit: [Function],
          actions: [Function],
          touchActions: [Function],
          executeScript: [Function],
          executeAsyncScript: [Function],
          call: [Function],
          wait: [Function],
          sleep: [Function],
          getWindowHandle: [Function],
          getAllWindowHandles: [Function],
          getPageSource: [Function],
          close: [Function],
          getCurrentUrl: [Function],
          getTitle: [Function],
          findElementInternal_: [Function],
          findElementsInternal_: [Function],
          takeScreenshot: [Function],
          manage: [Function],
          switchTo: [Function],
          driver: [thenableWebDriverProxy],
          element: [Function],
          '$': [Function],
          '$$': [Function],
          baseUrl: '',
          getPageTimeout: 10000,
          params: {},
          resetUrl: 'data:text/html,<html></html>',
          debugHelper: [DebugHelper],
          ready: [ManagedPromise],
          trackOutstandingTimeouts_: true,
          mockModules_: [Array],
          ExpectedConditions: [ProtractorExpectedConditions],
          plugins_: [Plugins],
          allScriptsTimeout: 11000,
          getProcessedConfig: [Function],
          forkNewDriverInstance: [Function],
          restart: [Function],
          restartSync: [Function],
          internalRootEl: '',
          internalIgnoreSynchronization: true
        },
        then: null,
        parentElementArrayFinder: ElementArrayFinder {
          browser_: [ProtractorBrowser],
          getWebElements: [Function: getWebElements],
          locator_: [name(name) {
        return By.css('*[name="' + escapeCss(name) + '"]');
      }],
          actionResults_: null,
          click: [Function],
          sendKeys: [Function],
          getTagName: [Function],
          getCssValue: [Function],
          getAttribute: [Function],
          getText: [Function],
          getSize: [Function],
          getLocation: [Function],
          isEnabled: [Function],
          isSelected: [Function],
          submit: [Function],
          clear: [Function],
          isDisplayed: [Function],
          getId: [Function],
          takeScreenshot: [Function]
        },
        elementArrayFinder_: ElementArrayFinder {
          browser_: [ProtractorBrowser],
          getWebElements: [Function: getWebElements],
          locator_: [name(name) {
        return By.css('*[name="' + escapeCss(name) + '"]');
      }],
          actionResults_: null,
          click: [Function],
          sendKeys: [Function],
          getTagName: [Function],
          getCssValue: [Function],
          getAttribute: [Function],
          getText: [Function],
          getSize: [Function],
          getLocation: [Function],
          isEnabled: [Function],
          isSelected: [Function],
          submit: [Function],
          clear: [Function],
          isDisplayed: [Function],
          getId: [Function],
          takeScreenshot: [Function]
        },
        click: [Function],
        sendKeys: [Function],
        getTagName: [Function],
        getCssValue: [Function],
        getAttribute: [Function],
        getText: [Function],
        getSize: [Function],
        getLocation: [Function],
        isEnabled: [Function],
        isSelected: [Function],
        submit: [Function],
        clear: [Function],
        isDisplayed: [Function],
        getId: [Function],
        takeScreenshot: [Function]
      }
    ]
    .
    
    
    1 spec, 0 failures
    Finished in 3.881 seconds
    
    [13:33:25] I/local - Shutting down selenium standalone server.
    [13:33:25] I/launcher - 0 instance(s) of WebDriver still running
    [13:33:25] I/launcher - chrome #01 passed
    
    C:\ProtractorProjects\ddg>