量角器交互(elementExplorer)无论是否找到元素都显示结果

Protractor interactive (elementExplorer) shows result regardless of whether element is found

我的页面上有一个带有 id 的元素,即 <p id="blabla">The Text</p>

当我 运行 量角器的 elementExplorer,即 protractor ./config/protractor-conf.js --elementExplorer http://localhost:9001,我输入 element(by.id('blabla')) 我得到一个元素结果(复制在下面)。

然而,我意识到如果我给出任何愚蠢的 id(即 foo),我会得到看似相同的结果。我原以为会收到错误消息或 "Not Found" 消息。如何判断元素是否实际存在?

每个element(by.id())调用的结果:

> element(by.id('foo'))
ElementFinder {
  ptor_:
   Protractor {
     getProcessedConfig: [Function],
     forkNewDriverInstance: [Function],
     restart: [Function],
     controlFlow: [Function],
     schedule: [Function],
     setFileDetector: [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:
      WebDriver {
        session_: [Object],
        executor_: [Object],
        flow_: [Object],
        fileDetector_: null },
     element: { [Function] all: [Function] },
     '$': [Function],
     '$$': [Function],
     baseUrl: 'http://localhost:9001',
     rootEl: 'body',
     ignoreSynchronization: false,
     getPageTimeout: 10000,
     params: {},
     ready:
      Promise {
        flow_: [Object],
        stack_: null,
        parent_: null,
        callbacks_: null,
        state_: 'fulfilled',
        handled_: true,
        value_: null,
        queue_: null },
     plugins_:
      Plugins {
        setup: [Function],
        teardown: [Function],
        postResults: [Function],
        postTest: [Function],
        onPageLoad: [Function],
        onPageStable: [Function],
        waitForPromise: [Function],
        waitForCondition: [Function],
        pluginObjs: [],
        assertions: {},
        resultsReported: false },
     resetUrl: 'data:text/html,<html></html>',
     trackOutstandingTimeouts_: true,
     mockModules_: [ [Object] ],
     allScriptsTimeout: 11000,
     dbgCodeExecutor_:
      { execPromise_: [Object],
        execPromiseResult_: undefined,
        execPromiseError_: undefined,
        replServer_: [Object],
        execute_: [Function],
        execute: [Function],
        complete: [Function],
        resultReady: [Function],
        getResult: [Function] } },
  then: null,
  parentElementArrayFinder:
   ElementArrayFinder {
     ptor_:
      Protractor {
        getProcessedConfig: [Function],
        forkNewDriverInstance: [Function],
        restart: [Function],
        controlFlow: [Function],
        schedule: [Function],
        setFileDetector: [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: [Object],
        element: [Object],
        '$': [Function],
        '$$': [Function],
        baseUrl: 'http://localhost:9001',
        rootEl: 'body',
        ignoreSynchronization: false,
        getPageTimeout: 10000,
        params: {},
        ready: [Object],
        plugins_: [Object],
        resetUrl: 'data:text/html,<html></html>',
        trackOutstandingTimeouts_: true,
        mockModules_: [Object],
        allScriptsTimeout: 11000,
        dbgCodeExecutor_: [Object] },
     locator_:
      name(name) {
          return By.css('*[name="' + escapeCss(name) + '"]');
        } { using: 'css selector', value: '*[id="blabla"]' },
     actionResults_: null,
     getWebElements: [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],
     getOuterHtml: [Function],
     getInnerHtml: [Function],
     getId: [Function],
     getRawId: [Function],
     serialize: [Function],
     takeScreenshot: [Function] },
  elementArrayFinder_:
   ElementArrayFinder {
     ptor_:
      Protractor {
        getProcessedConfig: [Function],
        forkNewDriverInstance: [Function],
        restart: [Function],
        controlFlow: [Function],
        schedule: [Function],
        setFileDetector: [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: [Object],
        element: [Object],
        '$': [Function],
        '$$': [Function],
        baseUrl: 'http://localhost:9001',
        rootEl: 'body',
        ignoreSynchronization: false,
        getPageTimeout: 10000,
        params: {},
        ready: [Object],
        plugins_: [Object],
        resetUrl: 'data:text/html,<html></html>',
        trackOutstandingTimeouts_: true,
        mockModules_: [Object],
        allScriptsTimeout: 11000,
        dbgCodeExecutor_: [Object] },
     locator_:
      name(name) {
          return By.css('*[name="' + escapeCss(name) + '"]');
        } { using: 'css selector', value: '*[id="blabla"]' },
     actionResults_: null,
     getWebElements: [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],
     getOuterHtml: [Function],
     getInnerHtml: [Function],
     getId: [Function],
     getRawId: [Function],
     serialize: [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],
  getOuterHtml: [Function],
  getInnerHtml: [Function],
  getId: [Function],
  getRawId: [Function],
  serialize: [Function],
  takeScreenshot: [Function] }

这是 Protractor 设计的工作方式 - 在您开始使用元素 之前,您不会收到 "Element not Found" 错误 。例如,尝试调用:

> element(by.id('something_that_does_not_exist')).getText()

这里是 reference in the documentation 来支持:

The element() function returns an ElementFinder object. The ElementFinder knows how to locate the DOM element using the locator you passed in as a parameter, but it has not actually done so yet. It will not contact the browser until an action method has been called.