使用 Sahi 驱动程序使 CSS 选择器(第一个孩子)在 Behat 3 中工作

Posted

技术标签:

【中文标题】使用 Sahi 驱动程序使 CSS 选择器(第一个孩子)在 Behat 3 中工作【英文标题】:Make CSS Selector (first-child) work in Behat 3 with Sahi Driver 【发布时间】:2015-01-25 01:34:20 【问题描述】:

我只是想知道您能否指出问题出在哪里,是 Behat、CSS 选择器还是 Sahi 驱动程序。

我们刚刚升级到 Behat 3 并且正在使用 Sahi 驱动程序(最新的开源版本)。我们发现,任何使用伪元素first-child 的 Behat 测试现在似乎都失败了。

例子:

步骤:

And I follow "#the-list tr:first-child .row-title"

(其中包含一个带有类行标题的锚元素,请参阅 html

错误:

未找到带有 id|title|alt|text "#the-list tr:first-child .row-title" 的链接。 (Behat\Mink\Exception\ElementNotFoundException)

HTML:

<tbody id="the-list">
    <tr id="post-162382" class="post-162382 type-post status-publish format-standard hentry category-uncategorized alternate iedit author-other level-0">
        <th class="check-column" scope="row"></th>
        <td class="post-title page-title column-title">
            <strong>
                <a class="row-title" title="Edit “Post Title”" href="https://domain.com"></a>
            </strong>
            <div class="locked-info"></div>
            <div class="row-actions"></div>
            <div id="inline_162382" class="hidden"></div>
        </td>

CSSSelector.php(我们在旧 Behat 中使用的覆盖,我们保留了这个文件)

/**
 * Makes all of the form field related steps allow CSS selectors.
 */
class CSSSelectorContext extends MinkContext

    /**
     * Finds an element via CSS or fails with a given error
     * 
     * @param $element string   A CSS selector string
     * @param $error Exception  An error to throw in case the element can not be found
     * @return object           An Element object
     */
    protected function findOrFail($element, $error)
        $element = $this->getSession()->getPage()->find('css', $element);
        if (!isset($element))     
            throw $error;
        
        return $element;
    

    public function clickLink($link) 
        try 
            parent::clickLink($link);
            return;
        catch (Exception $error)
            $link = $this->fixStepArgument($link);
            $link = $this->findOrFail($link, $error);
            $link->press();
        
    

在带有 jquery 的 Chrome 控制台中使用 css 选择器时,它会选择适当的元素。我浏览了代码并查看了 css -> xpath 翻译,然后根据我们正在测试的站点上生成的 html 验证了 xpath,它似​​乎也是有效的。 css 选择器也适用于 Goutte 驱动程序。

生成的 XPath:

    find(function()
        var count = 0;
        while (_sahi._byXPath("("+"\/\/html\/descendant-or-self::*[@id = 'the-list']\/descendant-or-self::*\/*[name() = 'tr' and (position() = 1)]\/descendant-or-self::*\/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' row-title ')]"+")["+(count+1)+"]")) count++;
        return count;
    )()

descendant-or-self::*[@id = 'the-list']/descendant-or-self::*/*[name() = 'tr' and (position() = 1)]/descendant-or-self::*/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' row-title ')]

//html/descendant-or-self::*[@id = 'the-list']/descendant-or-self::*/*[name() = 'tr' and (position() = 1)]/descendant-or-self::*/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' row-title ')]

当我将 CSS 更改为:

步骤:

And I follow "#the-list tr .row-title"

它之所以有效,是因为我相信无论如何它只是从它们的列表中选择第一个 tr,但我们当然希望能够使用 first-child。

感谢您的帮助!

【问题讨论】:

This github issue 似乎在谈论同样的事情。有帮助吗? 问题 github.com/symfony/symfony/issues/11803 是相关的,但它没有意义,因为 Symfony 生成的 Xpath 似乎是正确的。 你试过“#the-list tr:nth-child(1) .row-title”吗? 以这种方式进行并使用必要的 css 进行定位如何解决#the-list .row-title 对不起,如果是一个愚蠢/光顾的问题,但您是否通过 Firebug 检查了元素以排除任何其他覆盖规则的内容,并且您是否以任何方式处理 CSS - 导致,您是否仔细检查了输出除了您的开发副本之外的 CSS? 【参考方案1】:

抱歉迟到了

您的问题是 Minks 自己的步骤“我关注”/“clickLink”不接受以下内容:

    ID 的“#” ID、文本、标题或替代值以外的任何内容。

我建议使用“点击”步骤而不是“关注”,如下所示:

    /**
     * @Then /^(?:|I )click (?:|on )(?:|the )"([^"]*)"(?:|.*)$/
     */
    public
    function iClickOn($arg1)
    
        $findName = $this->getSession()->getPage()->find("css", $arg1);
        if (!$findName) 
            throw new Exception($arg1 . " could not be found");
         else 
            $findName->click();
        
    

您在此处使用 CSS,这将允许这样编写:

Then I click on the "#the-list tr:first-child .row-title" link

这是我也犯的错误,这是我们当时决定的解决方案,我们不必回头。

【讨论】:

以上是关于使用 Sahi 驱动程序使 CSS 选择器(第一个孩子)在 Behat 3 中工作的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用选择器 $(':dragged') 设置 css 会使拖动动作尴尬?

使用 Sahi 实现 Web 自动化测试

Sahi ---实现 Web 自动化测试

css选择器

css3选择器怎么选择第3个,第6个,第9个,第12个……元素??

css选择器的类型及作用