3

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

有了这些知识,我希望输出以下代码: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 确实有几个.foodiv,但是当我尝试访问第一个时,它说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 选择器。

编辑:更改为类

4

2 回答 2

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)

    }
于 2018-07-04T02:45:22.210 回答
0

首先,你的例子很有趣。我不知道你是怎么弄到那块的<html>。该id值必须是唯一的:

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

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

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

browser.debug()

输出(调试模式下的阻塞测试):

> 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). 当然,第二个示例仅用于教学目的,因为您可能永远不想那样做。

希望能帮助到你。干杯!

于 2017-12-06T16:36:47.720 回答