【问题标题】:Protractor: How do I create a function that receives an HTML element as a parameter?量角器:如何创建一个接收 HTML 元素作为参数的函数?
【发布时间】:2020-04-30 21:04:05
【问题描述】:

我是 Protractor 的新手。

我正在尝试根据按钮标题选择一个按钮。我想把它变成一个函数,并将按钮标题作为参数传入。

这是有效的硬编码版本:

    it('I click on a button based on the button title', async function() {
        let button = element(by.css('button[title=example_button_title]'));
        await button.click();
    });

我创建了一个全局变量和一个函数来尝试替换它,其中“buttonTitle”是我传递给函数的参数:

变量:

    let dynamicButton = buttonTitle => { return element(by.css("'button[title=" + buttonTitle + "]'")) };

功能:

    this.selectDynamicButton = async function(buttonTitle) {
        await browser.waitForAngularEnabled(false);
        await dynamicButton(buttonTitle).click();
    };

当我尝试这个时,我得到以下错误:

失败:无效选择器:指定了无效或非法的选择器

如果这里似乎存在基本错误,我深表歉意,我仍在学习。我感谢任何人可以给我的任何帮助。谢谢。

【问题讨论】:

    标签: protractor


    【解决方案1】:

    您可以使用量角器addLocator 功能添加自定义定位器。 (这实际上是与链接中列出的示例非常相似的用例)

    如下所示:

    onPrepare: function () {
    
        by.addLocator('buttonTitle', function (titleText, opt_parentElement) {
            // This function will be serialized as a string and will execute in the
            // browser. The first argument is the text for the button. The second
            // argument is the parent element, if any.
            const using = opt_parentElement || document;
            const matchingButtons = using.querySelectorAll(`button[title="${titleText}"]`);
            let result = undefined;
    
            if (matchingButtons.length === 0) {
                result = null;
            } else if (matchingButtons.length === 1) {
                result = matchingButtons[0];
            } else {
                result = matchingButtons;
            }
    
            return result;
        });
    }
    

    这样叫

    const firstMatchingButton = element(by.buttonTitle('example_button_title'));
    const allMatchingButtons = element.all(by.buttonTitle('example_button_title'));
    

    我必须在发布之前编辑此代码,所以如果这不起作用,请告诉我。我在这里的工作主要基于this previous answer

    【讨论】:

    • 非常感谢!我必须做两个小的调整: 1. 删除 onPrepare: function () 部分,并在我的规范文件顶部声明它。我不确定我需要将 onPrepare 部分放在哪个文件中才能工作,所以我可能需要做更多的研究。 2. 我使用定位器的量角器文档中的示例调用它: element(by.buttonTitle('button_title_example')).click();进行这些更改使我的测试开始工作。再次,非常感谢:)
    • 很高兴它有帮助!作为记录,onPrepare 进入 conf.js 文件,你把它放在那里,你就可以在项目中的任何其他文件中调用该定位器。您可以在 conf here 中查看可以设置的示例,这真的值得一读!我在开始使用 Protractor 时一直引用它
    • 太好了。我会尝试将其放入 conf.js 文件中。我还将通过您提供的链接进行适当的阅读。再次感谢您的帮助。
    【解决方案2】:

    Protractor 已经有一个内置的定位器,可让您使用文本获取按钮。我想你正在看类似的东西。请参阅element(by.buttonText('text of button')) 定位器。

    更多参考请参见here

    【讨论】:

    • 感谢您的建议。我有一个不寻常的情况,所有按钮的按钮文本都相同,但每个按钮的工具提示都是唯一的,所以我想我必须尝试上面的自定义定位器建议。
    • 您可以使用此定位器获取多个元素并将它们保存在数组或列表中,然后使用索引从那里选择元素。如果你能给我一个例子,或者HTML sn-p,我可以试着想出一个解决方案。
    • 值得一提的是,其他两个建议都有助于解决我的问题,但我想提供一个 HTML sn-p,以防您有另一个您认为可行的建议(您知道的越多!)。这是 sn-p:
    【解决方案3】:
    let dynamicButton = buttonTitle => { return element(by.css('button[title=${buttonTitle} ]')) };
    

    使用模板文字而不是使用 + 连接字符串。

    【讨论】:

    • 感谢您的回复。这给了我解决问题所需的一半解决方案。在查看了模板文字 (flaviocopes.com/javascript-template-literals) 之后,我发现我还需要用反引号替换我的单引号才能使其正常工作: let dynamicButton = buttonTitle => { return element(by.css(button[title=${buttonTitle} ])) } ;进行此更改导致我的测试开始工作。非常感谢您的解决方案。
    猜你喜欢
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    相关资源
    最近更新 更多