量角器在TypeScript回调函数中使用Expected Condition作为参数

时间:2019-02-20 15:14:47

标签: javascript typescript protractor

我正在尝试将ExpectedConditions函数作为参数传递给函数。

这样,我可以互换不同的条件,而不必为每个条件创建函数以方便使用。

问题是,量角器抛出错误:

  

失败:无法读取未定义的属性“和”

,它指向ExpectedConditions实现。

可以重现该问题并显示我意图的代码:

import { browser, by, element, ElementFinder, ExpectedConditions, until } from 'protractor';

describe('wait on google page', () => {

    const searchBtn = element.all(by.name('btnK')).last()

    beforeEach(() => {
        browser.get('https://www.google.com');
    });

    it('should work with until callback', () => {
        callbackWait(until.elementIsVisible, searchBtn)
    });

    it('should work with ExpectedConditions', () => {
        browser.wait(ExpectedConditions.visibilityOf(searchBtn), 1_000)
    });

    it('should work with EC callback', () => {
        callbackWait(ExpectedConditions.visibilityOf, searchBtn)
    });

});

function callbackWait(condition, element: ElementFinder) {
    browser.wait(condition(element.getWebElement()), 1_000)
}

使用until.elementIsVisible时,代码按预期工作,如果我在browser.wait()中使用ExpectedCondition,则代码相同,如果我像使用until.elementIsVisible一样使用ExpectedCondition,则会发生错误。 / p>

关于变通方法的任何建议或关于我做错了什么的提示?

npm package.json依赖项:

  "devDependencies": {
    "@types/jasmine": "^3.3.0",
    "@types/jasminewd2": "^2.0.6",
    "jasmine": "^3.3.0",
    "protractor": "^5.4.2",
    "ts-node": "^7.0.1",
    "typescript": "^3.1.6"
  }

2 个答案:

答案 0 :(得分:0)

我假设您的定义类似于
import {ExpectedConditions as until} from 'protractor' 这意味着ExpectedConditions.stuffuntil.stuff基本上是完全相同的。
但是,elementIsVisible不是ExpectedCondition。您正确使用visibilityOf
查看Expected Conditions Documentation

答案 1 :(得分:0)

您的问题来自this,请查看以下的visibilityOf定义或来自github

  visibilityOf(elementFinder: ElementFinder): Function {
    return this.and(this.presenceOf(elementFinder), () => {
      return elementFinder.isDisplayed().then(passBoolean, falseIfMissing);
    });
  }

您看到的是this.and

ExpectedConditions.visibilityOf(searchBtn)
//if you call visibilityOf() in one line, the `this` is not null/undefined
//`this` has value, it's `ExpectedConditions` itself.

// but if you do as following

function callbackWait(condition, ele) {
    browser.wait(condition(ele), 1000)
}

var btn = element(by.css('#id'))
var cond1 = ExpectedConditions.visibilityOf
callbackWait(cond1, btn)

// after you assign function `visibilityOf` to cond1
// the `this` value missed, it will becomes undefined.
// thus when you call cond1(ele) inside callbackWait, 
// this.and reports: Cannot read property 'and' of undefined

要解决this缺少值的问题,您需要使用bind()将值绑定到'this'。

it('should work with EC callback', () => {
    let cond = ExpectedConditions.visibilityOf.bind(ExpectedConditions);
    // assign ExpectedConditions back to `this` via bind()
    callbackWait(cond, searchBtn)
});

除了this问题外,您的callbackWait()也存在问题。

// for ExpectedConditions.xxxx, it's only accept ElementFinder type
// if parameter: condition value like ExpectedConditions.visibilityOf
function callbackWait(condition, element: any) {
    browser.wait(condition(element), 1000)
}

// but for webdirver.util.xxxx, it's only accept WebEelment type
// if parameter: condition value like util.elementIsVisible
function callbackWait(condition, element: any) {
    browser.wait(condition(element.getWebElement()), 1000)
}

实际上,ExpectedConditions提供了/selenium-webdriver/lib/until.js的所有功能,因此无需混合使用它们即可在脚本中使用。