You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Behat和Goutte处理Drupal 8中的Ajax加载模态框?

这种Drupal Ajax自定义模态框的Behat测试问题我碰到过好几次,确实比原生alert麻烦不少——毕竟它是动态加载的DOM元素,Behat默认的步骤太急,赶不上元素渲染的速度。我给你几个实用的解决思路,应该能搞定:

1. 先解决「Ajax加载延迟」的问题

你点击“Select files”后,模态框是通过Ajax异步加载的,Behat默认会立刻执行下一步的「我应该看到XX」,这时候模态框还没渲染出来,自然会失败。所以必须加智能等待,而不是固定等待(当然固定等待可以先用来测试)。

可以写一个自定义等待步骤,专门等模态框容器出现:

/**
 * @Then I wait for the upload modal to load
 */
public function waitForUploadModal() {
  $page = $this->getSession()->getPage();
  // Drupal的Ajax模态框通常有固定ID #drupal-modal,你可以用开发者工具确认下
  $modal = $page->waitFor(10, function($page) {
    return $page->find('css', '#drupal-modal');
  });

  if (!$modal) {
    throw new \Exception('文件上传模态框加载超时');
  }
}

2. 修正元素定位的方式

你之前用的div:contains("%s")是jQuery的选择器,原生CSS不支持,Behat的CSS选择器遵循原生标准,所以肯定找不到元素。换用XPath来定位包含指定文本的元素,或者先定位模态框容器,再在里面找内容。

比如写一个通用的“在模态框中看到文本”的步骤:

/**
 * @Then I should see :text in the upload modal
 */
public function seeTextInUploadModal($text) {
  $this->waitForUploadModal(); // 先确保模态框加载完成
  $page = $this->getSession()->getPage();
  // 在模态框容器内查找包含指定文本的元素
  $element = $page->find('xpath', '//div[@id="drupal-modal"]//*[contains(text(), "' . $text . '")]');
  
  if (!$element) {
    throw new \Exception('模态框中未找到文本: ' . $text);
  }
}

3. 调整你的测试场景

把原来的步骤换成自定义的,确保流程正确:

Scenario: Creates a stage test with two sessions
Given I am on "/user/login"
And I fill in "user@user.com" for "name"
And I fill in "password" for "pass"
And I press "Log in"
Then I should get a "200" HTTP response
And I should see "User Name"
When I go to "/node/add/stage"
Then I should get a "200" HTTP response
And I should see "Add content CISIA Stage"
When I fill in "Test Cisia Stage" for "edit-title-0-value"
And I press "Select files"
And I wait for the upload modal to load
Then I should see "Upload files" in the upload modal
Then I should see "Click or drop files here to upload them" in the upload modal

额外提示:确认模态框的实际DOM结构

打开浏览器开发者工具,点击“Select files”后,查看模态框的HTML:

  • 确认容器的ID或类名是不是#drupal-modal(Drupal默认是这个,但如果是自定义模块可能有变化)
  • 查看文本所在的元素层级,比如是不是在.modal-body或者.ui-dialog-content里,调整XPath或CSS选择器

如果你的Behat环境用的是Selenium驱动,还可以用WebDriver的原生等待方法,稳定性更高:

$driver = $this->getSession()->getDriver();
if ($driver instanceof \Behat\Mink\Driver\Selenium2Driver) {
  $webDriver = $driver->getWebDriver();
  $webDriver->wait(10)->until(
    \Facebook\WebDriver\WebDriverExpectedCondition::visibilityOfElementLocated(
      \Facebook\WebDriver\WebDriverBy::id('drupal-modal')
    )
  );
}

这样调整后,应该就能正确识别到自定义模态框了。

内容的提问来源于stack exchange,提问作者Jaeger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:38:42