首页 > 解决方案 > 无法使用 Behat + Drupal 8 在 chrome 浏览器上执行登录功能

问题描述

只需将 Behat 与 drupal 8 一起使用,并面临登录 behat 脚本运行的问题。以下是我的代码:

behat.yml

default:
  suites:
    default:
      contexts:
        - FeatureContext
        - Drupal\DrupalExtension\Context\DrupalContext
        - Drupal\DrupalExtension\Context\MinkContext
        - Drupal\DrupalExtension\Context\MessageContext
        - Drupal\DrupalExtension\Context\DrushContext
  extensions:
    Behat\MinkExtension:
      goutte: ~
      base_url: http://localhost:8080/drupal-dev/web
      javascript_session: selenium2
      browser_name: 'chrome'
      selenium2: ~
    Drupal\DrupalExtension:
      blackbox: ~
      api_driver: drupal
      drupal:
        drupal_root: web/
      region_map:
        navigation: ".navbar-header"
        navigation_collapsible: "#navbar-collapse"
        header: ".region-header"
        highlighted: ".highlighted"
        help: ".region-help"
        content: ".region-content"
        sidebar_first: ".region-sidebar-first"
        sidebar_second: ".region-sidebar-second"
        footer: ".footer"

登录功能

@javascript
Feature: login check

Scenario: user login is working
  Given I am on "/user"
  When I fill in "john" for "edit-name"
  And I fill in "john for "edit-pass"
  And I press "Log in"
  Then I should see "Add content"

当我执行 vendor\bin\behat 时,它将打开 chrome 浏览器并重定向到用户登录页面,但从第二步失败。请参阅以下错误消息:

@javascript
Feature: login check

  Scenario: user login is working             # features\bootstrap\login.feature:4
    Given I am on "/user"                     # Drupal\DrupalExtension\Context\MinkContext::visit()
    When I fill in "john" for "edit-name"   # Drupal\DrupalExtension\Context\MinkContext::fillField()
      Form field with id|name|label|value|placeholder "edit-name" not found. (Behat\Mink\Exception\ElementNotFoundException)
    And I fill in "john" for "edit-pass" # Drupal\DrupalExtension\Context\MinkContext::fillField()
    And I press "Log in"                      # Drupal\DrupalExtension\Context\MinkContext::pressButton()
    Then I should see "Add content"           # Drupal\DrupalExtension\Context\MinkContext::assertPageContainsText()

--- Failed scenarios:

    features\bootstrap\login.feature:4

1 scenario (1 failed)
5 steps (1 passed, 1 failed, 3 skipped)
0m15.30s (17.82Mb)

如果我从@javasript 替换为@api,相同的功能文件工作正常并且所有步骤都通过了。

标签: seleniumselenium-webdriverselenium-chromedriverdrupal-8behat

解决方案


如果我从@javasript 替换为@api,相同的功能文件工作正常并且所有步骤都通过了。

Selenium 的一个常见问题是自动浏览器比无头浏览器(在您的情况下为 @api,Symfony 中的 @goutte)需要更多时间来呈现页面,因此当 Behat 尝试在 DOM 中查找元素时返回错误尚未渲染。

解决方案是在尝试填充该字段之前添加一个 wait() 。您甚至可以在上下文中查询驱动程序类型,并仅在类型为 Selenium 时触发等待。

您需要创建自己的上下文文件来添加您的方法。创建“MyFeatureContext”(或其他),使其继承 MinkContext 类,将其添加到您的 behat.yml 文件中的上下文中(而不是 MinkContext,因为您仍然从它继承),并添加以下方法:

public function wait(int $ms)
{
    if ($this->getDriver() instanceof Selenium2Driver) {
        return $this->getSession()->wait($ms);
    }
}

/**
 * Fills in form field with specified id|name|label|value
 * Example: When I fill in "username" with: "bwayne"
 * Example: And I fill in "bwayne" for "username"
 *
 * @When /^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)"$/
 * @When /^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with:$/
 * @When /^(?:|I )fill in "(?P<value>(?:[^"]|\\")*)" for "(?P<field>(?:[^"]|\\")*)"$/
 */
public function fillField($field, $value)
{
    $this->wait(1000); # 1000ms or 1sec
    parent::fillField($field, $value);
}

请注意,注释是从 MinkContext::fillField() 复制而来的。


推荐阅读