Spectron / WebdriverIO第n个孩子使用$$ [n]而不是选择器

时间:2017-12-05 23:43:44

标签: javascript typescript electron webdriver-io spectron

我正在尝试使用Spectron来测试我的Electron应用程序。文档说,在尝试查找第n个子节点时,您可以使用第n个子选择器,或者使用$$获取与选择器匹配的所有子节点,然后使用索引运算符,即$$ ("foo")[0]获取第一个foo。 DOCS

有了这些知识,我希望输出以下代码:BAR 我无法解决这个问题,我尝试以下方法:

const foo = ".foo";
const fooElements = app.client.$$ (foo);
console.log ("FOOELEMENTS", await TP (app.client.getHTML (foo)));
console.log ("BAR", fooElements[0].getText (".bar"));

获得以下输出:

console.log components\pages\analysis\__test__\Analysis.spectron.ts:44
    FOOELEMENTS [ '<div class="foo"><div class="bar">BAR</div><div class="baz">BAZ</div></div>',
    '<div class="foo"><div class="bar">BAR2</div><div class="baz">BAZ2</div></div>',
    '<div class="foo"><div class="bar">BAR3</div><div class="baz">BAZ3</div></div>'
    '<div class="foo"><div class="bar">BAR4</div><div class="baz">BAZ4</div></div>' ]

console.log components\pages\analysis\__test__\Analysis.spectron.ts:50
    EXCEPTION TypeError: Cannot read property 'getText' of undefined
        at components\pages\analysis\__test__\Analysis.spectron.ts:45:44
        at Generator.next (<anonymous>)
        at fulfilled (components\pages\analysis\__test__\Analysis.spectron.ts:4:58)
        at <anonymous>
        at process._tickDomainCallback (internal/process/next_tick.js:228:7)

正如您所看到的,输出HTML确实有几个.foo div,但当我尝试访问第一个时,它表示fooElements[0]undefined

sideNote(不应该相关):TP是我写的一个名为toPromise的函数的别名,它让我等待webdriver的承诺,因为TypeScript被实现的方式搞糊涂了:

export async function toPromise<T> (client: Webdriver.Client<T>)
{
    return client as any as Promise<T>;
}

// Promise
    interface Client<T> {
        finally(callback: (...args: any[]) => void): Client<T>;

        then<P>(
            onFulfilled?: (value: T) => P | Client<P>,
            onRejected?: (error: any) => P | Client<P>
        ): Client<P>;

        catch<P>(
            onRejected?: (error: any) => P | Client<P>
        ): Client<P>;

        inspect(): {
            state: "fulfilled" | "rejected" | "pending";
            value?: T;
            reason?: any;
        };
    }

知道我做错了什么吗?或建议的替代方案?如果可能的话,我更愿意避免使用nth-child选择器。

编辑:改为上课

2 个答案:

答案 0 :(得分:1)

实际上,webdriver窗口索引和元素将[1]称为第一个元素。

这对我来说很好。

var button = ('//*[contains(@class,"popper")]')[1];

返回this.app.client.click(button);

示例:

class Clix {

    constructor() {

        this.clix_search = '(//input[contains(@class,"clix-search")])[1]';

    }

    clix_input_search(app) {
        return help.setValue(app, this.clix_search, "pack");
    }

}

在帮助程序类中

setValue(app, element, text) {

        return app.client.waitForVisible(element, 60000)
            .waitForEnabled(element, 60000)
            .clearElement(element)
            .setValue(element, text)
            .getValue(element)
            .should.eventually.equal(text)

    }

答案 1 :(得分:0)

首先,你的例子很有趣。我不知道你是如何得到那条<html>的。 id值必须是唯一的:

  

id属性指定HTML元素的唯一ID(值   在HTML文档中必须是唯一的。)

您的代码应在稍作更改后才能生效,只需删除#bar选择器即可。您正在将选择器传递给ELEMENT对象,但它已通过selector键的值包含该信息。

let locator = 'span[connectqa-device="installed"]'

browser.debug()

输出( debug-mode 中的阻止测试):

> let elems = $$(locator)
[18:10:22]  COMMAND     POST     "/wd/hub/session/775b024e-0b6a-4a60-a5b2-26d4df961d0a/elements"
[18:10:22]  DATA                {"using":"css selector","value":"span[connectqa-device=\"installed\"]"}
[18:10:22]  RESULT              [{"element-6066-11e4-a52e-4f735466cecf":"c6719646-30da-43ff-9b17-40c074b4988a"},{"element-6066-11e4-a52e-4f735466cecf":"d5f8acf2-8f4f-4554-9fe6-7f863555f5b5"},{"element-6066-11e4-a52e-4f735466cecf":"53ff9b0a-2a88-4b13-9e54-9c54411c03c5"}]

> elems[0]
{ ELEMENT: 'c6719646-30da-43ff-9b17-40c074b4988a',
  'element-6066-11e4-a52e-4f735466cecf': 'c6719646-30da-43ff-9b17-40c074b4988a',
  selector: 'span[connectqa-device="installed"]',
  value: { ELEMENT: 'c6719646-30da-43ff-9b17-40c074b4988a' },
  index: 0 }
>
> elems[0].selector
'span[connectqa-device="installed"]'
>
> elems[0].getText()
[18:10:54]  COMMAND     GET      "/wd/hub/session/775b024e-0b6a-4a60-a5b2-26d4df961d0a/element/c6719646-30da-43ff-9b17-40c074b4988a/text"
[18:10:54]  DATA                {}
[18:10:54]  RESULT              "Installed"
'Installed'

或者,您可以这样做:let retText2 = browser.getText('span[connectqa-device="installed"]') > let retText2 = browser.getText(elems[0].selector)。第二个例子当然只是出于教学目的,因为你可能永远不会想那样。

希望它有所帮助。干杯!