使用Sahi Driver在Behat 3中使CSS Selector(第一个孩子)工作

sug*_*fle 9 xpath css-selectors sahi behat mink

我只是想知道你是否可以指出问题在哪里,如果它是Behat,CSS选择器或Sahi驱动程序.

我们刚刚升级到Behat 3并使用Sahi Driver(最新的开源版本).我们发现任何使用伪元素的Behat测试first-child现在似乎都破解了.

例:

步:

And I follow "#the-list tr:first-child .row-title"
Run Code Online (Sandbox Code Playgroud)

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

错误:

链接id | title | alt | text"#the-list tr:first-child .row-title"未找到.(贝哈特\水貂\异常\ 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>
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

使用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 ')]
Run Code Online (Sandbox Code Playgroud)

当我将CSS更改为:

步:

And I follow "#the-list tr .row-title"
Run Code Online (Sandbox Code Playgroud)

它的工作原理是因为我认为它只是从它们的列表中选择第一个tr,但我们希望能够使用第一个孩子.

谢谢你的帮助!

Kyl*_*rns 0

很抱歉参加聚会迟到了

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

  1. “#”代表 ID
  2. 除 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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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