ixis/codeception-drupal-content-types

此包已废弃,不再维护。未建议替代包。

一个用于提供Drupal内容类型支持的Codeception模块。

1.4.5 2016-06-16 10:16 UTC

README

这是一个 Codeception 模块,提供一系列封装Drupal内容类型的类。这使得测试与内容类型相关的标准Drupal功能变得更加容易,同时考虑到它们在你的网站上的存在。

它将测试许多事物,例如内容类型管理页面、每个内容类型的“管理字段”页面,并提供一个有用的createNode()方法,可以用来快速创建测试节点,你可以提供测试数据,使用特定值、随机值或一系列值(随机选择一个)。

安装

使用composer安装,如下所示

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/ixis/codeception-drupal-content-types.git"
        }
    ],
    "require": {
        "codeception/codeception": "2.*",
        "ixis/codeception-drupal-content-types": "~1.4",
    },
}

将模块添加到套件配置

modules:
    enabled:
        - DrupalContentTypeRegistry

配置

在测试根目录下放置一个 contentTypes.yml 文件(除非你为每个套件想要一个特定的contentTypes.yml,在这种情况下,请参阅下文)。

这是一个示例文件

GlobalFields:
    body:
        machineName:    body
        label:          Body
        type:           Long text and summary
        selector:       "#edit-body-und-0-value"
        widget:         Text area with a summary
        required:       true
    title:
        machineName:    title
        label:          Title
        type:           Node module element
        selector:       "#edit-title"
ContentTypes:
    news:
        humanName:    News
        machineName:  news
        fields:
            globals:
                - title
                - body
            field_image:
                machineName:    field_image
                label:          Image
                type:           Image
                selector:       "#edit-field-image"
                widget:         Media file selector
                required:       true
                testData:       "image1.png"
            field_icon:
                machineName:    field_icon
                label:          Icon
                type:           Text
                selector:       "#edit-field-icon"
                widget:         Text field
                skipRoles:
                    - editor
                    - publisher
                testData:
                    - smiley
                    - grumpy
                    - happy
                    - wacky
                preSteps:
                    - ["click", ["#button"]]
                    - ["fillField", ["#the-field", "the-value"]]
                postSteps:
                    - ["waitForJs", ["return jQuery.active == 0;"]]
        submit: "#edit-submit-me-please"

全局字段

在第一个部分中,您可以定义将在网站上的所有内容类型中使用的字段。这对于像标题和正文字段这样的东西很有用,这样您就不必在每种内容类型上重新定义完全相同的字段。

全局字段通过机器名(这应该是Drupal字段机器名的相同名称)进行索引,值与为内容类型的字段声明时的值相同(见下文)。

全局额外内容

与上面的全局字段类似,您可以为网站上的所有内容类型定义额外的内容。例如,如果您总是想要填写节点的发布状态,无论其类型如何,这很有用。有关更多信息,请参阅下面的“额外内容”部分。

内容类型

每个内容类型应根据其机器名进行索引(尽管这只是一个提示,因为machineName负责实际命名,所以您可以给内容类型任何键)。

  • humanName 是在UI中命名内容类型的方式(并且是区分大小写的)。
  • machineName 是在Drupal中命名内容类型的方式,应与Drupal中设置的内容相同。
  • fields 是内容类型上所有字段及其属性的列表。
    • globalFields 是此类型中“重复使用”字段的简单列表。如果您的内容类型有一个简单地重复另一个内容类型中的字段,请在全局字段(上面)中设置它,并在这里引用它。一个例外是,如果您设置了一个标题,但将其标签从“标题”更改为其他名称,则它不能是一个全局字段。
    • 属性:字段可以有以下属性...
      • machineName 是 Drupal 看到的字段名称。通常,这些名称以 field_ 开头,但可能存在例外,如标题和正文字段。
      • label 是此字段的用户名(标签),应与 UI 中设置的内容完全匹配,包括大小写敏感性。
      • type 是在 Drupal UI 的“管理字段”页面中设置的字段类型。大小写敏感。
      • selector 是用于在节点创建或编辑页面上选取此字段元素的 CSS 或 XPath 选择器。请注意,这通常是可选的,如果省略,将根据字段名称推导,这通常足够。
      • widget 是在 Drupal UI 的“管理字段”页面中设置的此字段小部件的名称。大小写敏感。某些字段没有小部件(如标题),因此只需省略即可。有一个字段类型列表被豁免使用小部件,因此 ContentTypeRegistry 将知道这一点。
      • required 如果字段是必填项,则可以将其设置为“true”。如果不是,则完全可以省略。
      • pre 可用于指定在填充字段之前应点击的元素的 XPath 选择器。如果设置了此值,则将点击此元素,然后填充字段。如果没有设置,则在填充字段之前不会点击任何内容。这对于位于垂直标签后面的元素很有用,这些元素在用户未先选择垂直标签时是不可见的。
      • skippedRoles 是一个角色名称数组,将无法看到此字段,也不应尝试填充它。
      • testData 应包含用于测试此字段的示例数据。可以指示每个字段自行填充测试数据,这里将使用这些数据。请注意,除非字段是必填项且 Drupal 为字段未提供默认值,否则可以将 testData 从 yaml 中省略。如果提供了一个值数组,Field 类可以选择随机的一个。也可以在这里使用特殊值。请参阅下面的“特殊值”。
      • preSteps 是在填充字段之前运行的可选步骤。这是对 pre 选项的扩展,但可以运行任何方法,而不仅仅是点击。格式是一个两个元素的数组。第一个元素是方法名称,第二个元素是传递给方法的参数数组。例如,["checkOption", ["#checkbox-name"]] 将在填充字段之前调用 $I->checkOption("#checkbox-name")
      • postSteps 是在填充字段之后运行的可选步骤。例如,["waitForJs", ["return jQuery.active == 0;"]] 将在字段填充后等待ajax调用完成,然后再继续。
  • extras 是一个所有额外元素(节点编辑表单上的交互元素)的列表,这些元素不是自己的字段。请参阅以下内容以获取更多信息。
    • globalExtras 是此类型上的“重用”额外元素列表。这与 globalFields 的工作方式相同,但对于节点表单上的非字段元素。
  • submit 是用于找到此内容类型的节点添加或编辑表单上的提交按钮的 CSS 或 XPath。Drupal 的默认值是 "#edit-submit",如果您的网站上使用的是默认值,则可以省略。

特殊值

您可以使用特殊值,该值将在创建字段时进行替换,以进行测试。例如,如果您想插入一个随机值,这很有用。所有特殊值都以标识符 special:: 开头,然后跟特殊值的类型。类型如下列出

  • randomText 使用八个随机的字母数字字符。

示例

testData: "special::randomText"

特定小部件类型

AddressWidget

将此小部件的选择器设置为小部件内每个单独地址字段选择器的第一部分。例如,如果机器名称是 field_address,则您应将选择器设置如下

selector:   "#edit-field-address-und-0"

您需要定义地址小部件中包含的各个元素,因为这些元素可以根据每个小部件进行不同的定义。

您可以使用 elements 键来完成此操作。数组键是每个字段的标签,值是用于上述选择器的选择器末尾,这些选择器将连接到上述描述的选择器。

elements:
    Company:        "-organisation"
    Address 1:      "-thoroughfare"
    Address 2:      "-locality"
    "Town/City":    "-locality"

如果您需要为此字段设置 testData,则需要将每个测试元素组包裹如下

testData:
    address1:
        Company:        Test location
        Address 1:      Test location thoroughfare
        Address 2:      Test location locality
        "Town/City":    Test location city
        County:         Test location county
        Postcode:       Test location postal code
    # Then, if necessary:
    address2:
        Company:        Test location 2
        Address 1:      Test location thoroughfare 2
        Address 2:      Test location locality 2
        "Town/City":    Test location city 2
        County:         Test location county 2
        Postcode:       Test location postal code 2

CheckboxesWidget

请记住,您只需要设置 testData,如果每个或任何复选框的值需要更改。

如果您需要为 CheckboxesWidget 设置 testData,请确保将每个盒子组放入其自己的包装器中,如下所示

testData:
    values1:
        Grapefruit: true
        Melon:      false
        Avocado:    true
    values2:
        "Big Hairy Kiwi Fruit/Kiwi Fruits": true

WysiwygWidget

用于 WYSIWYG 字段。选择器应该是此字段文本区域元素的 ID,但不包括末尾的 "-value" 部分。例如,对于正文字段,您可能使用

selector: "#edit-body-und-0"

目前小部件将切换到纯文本格式以输入数据。

特定套件 contentTypes.yml

如果愿意,您可以在每个套件文件夹中放置单独的 contentTypes.yml,这些文件可以覆盖主 contentTypes.yml(或者在测试根文件夹中不创建主的一个)。

如果您这样做,您需要在您的 套件 的 _bootstrap.php 中添加以下内容

\Codeception\Module\Drupal\ContentTypeRegistry\SuiteSettings::$suiteName = 'mysuite';

套件名称应与套件所在的目录名称匹配。这是因为 Codeception 没有其他方法知道在尝试找到 contentTypes.yml 文件时要查找哪个目录。它知道根测试目录的位置,并且有一个要运行的套件列表,但不能确定当前套件运行的目录。如果将来在 Codeception 中开发了执行此操作的方法,则可以删除此额外步骤。

附加内容

有时,您可能希望模拟用户在节点编辑表单上点击不是实际字段的元素。这就是附加内容发挥作用的地方。您可以设置节点粘滞状态或发布状态等方式。以下是一个示例

ContentTypes:
    news:
        humanName:    News
        machineName:  news
        fields:
            globals:
                - title
                - body
            field_image:
                machineName:    field_image
                label:          Image
                type:           Image
                selector:       "#edit-field-image"
                widget:         Media file selector
                required:       true
                testData:       "image1.png"
        extras:
            published:
                machineName:    published
                label:          Published
                type:           List (text)
                selector:       "#edit-published"
                widget:         Select list
                testData:       Published
        submit: "#edit-submit-me-please"

如您所见,这些与字段并列。通常您必须手动为这些设置选择器,因为适用于字段的命名约定不适用于此处。您仍然可以使用小部件属性来告诉此模块正在使用哪种类型的表单小部件。

节点创建/删除

在 createNode/deleteNode 期间,通过在元素中查找标准 Drupal 消息来检查成功状态,例如 .messages

某些主题可能有不同的选择器,或者根本不会显示这些消息。如果是这样,您可以在套件辅助程序中实现 seeCreateNodeWasSuccessful() 和/或 seeDeleteNodeWasSuccessful()

例如。


class AcceptanceHelper extends \Codeception\Module
{
    /**
     * Check a node creation was successful.
     *
     * This overrides the default since the css selectors are different in
     * this site's theme.
     *
     * @see DrupalContentTypeRegistry::seeCreateNodeWasSuccessful()
     *
     * @param WebInterface $I
     *   A reference to the Actor being used.
     * @param string $msg
     *   The success message that should be displayed by Drupal.
     * @param int $nid
     *   The created nid.
     */
    public function seeCreateNodeWasSuccessful($I, $msg, $nid)
    {
        $I->see($msg, ".messages");
        $I->dontSee(" ", ".messages.error");
    }

    /**
     * Check a node deletion was successful.
     *
     * This overrides the default since this site redirects to the
     * homepage on node deletion and does not show a message. We
     * therefore do a check by editing the node and make sure it's
     * not found.
     *
     * @see DrupalContentTypeRegistry::seeDeleteNodeWasSuccessful()
     *
     * @param AuthenticatedSteps $I
     *   A reference to the Actor being used.
     * @param int $nid
     *   The deleted nid.
     */
    public function seeDeleteNodeWasSuccessful($I, $nid)
    {
        $I->amOnPage(NodePage::route($nid, true));
        $I->see("we can't find this page", "h1");
    }
}