【问题标题】:Protractor using Expected Condition as parameter in TypeScript callback functions在 TypeScript 回调函数中使用预期条件作为参数的量角器
【发布时间】:2019-02-21 18:48:22
【问题描述】:

我正在尝试将 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,则会出现错误。

对解决方法或提示我做错了什么有任何建议吗?

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"
  }

【问题讨论】:

标签: javascript typescript protractor


【解决方案1】:

您的问题来自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 的所有功能,因此无需在脚本中混合使用。

【讨论】:

  • 谢谢!您的解决方案很有魅力!我有一个想法,它必须与 apply/bind/call 做一些事情,但我是 TS 的初学者,所以我无法弄清楚。
  • /selenium-webdriver/lib/until.js 块的原因是提供一个示例,它以某种方式在没有 bind() 的情况下工作
【解决方案2】:

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

【讨论】:

  • 不,直到来自基本的 webdriver-js 模块。导入是:import { browser, by, element, ElementFinder, ExpectedConditions, until } from 'protractor';(我也编辑了问题。)
猜你喜欢
  • 2015-02-28
  • 2020-10-26
  • 2018-01-19
  • 2022-07-06
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-08
相关资源
最近更新 更多