使用Behat测试Drupal自动补全表单时遇到焦点丢失问题
解决Behat测试Drupal自动补全表单时字段失焦的问题
我之前测试Drupal的自动补全表单时也碰到过一模一样的问题——用fillField()填充后字段莫名失焦,自动补全的下拉列表根本弹不出来,就像被按了Tab键一样。下面是我试过的几个靠谱解决方案:
1. 模拟真实用户的逐字符输入
fillField()是一次性把内容塞进字段,这种“非人类”操作很容易触发Drupal自动补全的事件异常。换成type()方法逐字符输入,同时先确保字段获得焦点,完美贴合真实用户操作:
$field = $this->getSession()->getPage()->findField('你的字段名称'); // 先让字段获得焦点 $field->focus(); // 逐字符输入文本,触发自动补全的keyup/input事件 $field->type('要搜索的文章标题');
2. 手动触发自动补全所需的JS事件
如果还是想用fillField(),那填充后手动触发Drupal自动补全依赖的JavaScript事件就行。Drupal的自动补全一般监听input或keyup事件,直接通过JS触发:
$page = $this->getSession()->getPage(); $fieldName = '你的字段名称'; $page->fillField($fieldName, '要搜索的文章标题'); // 触发input事件(适合新版本Drupal) $this->getSession()->executeScript(" const field = document.querySelector('[name=\"{$fieldName}\"]'); field.dispatchEvent(new Event('input', { bubbles: true })); "); // 如果上面的不行,试试keyup事件(旧版Drupal常用) $this->getSession()->executeScript(" const field = document.querySelector('[name=\"{$fieldName}\"]'); field.dispatchEvent(new Event('keyup', { bubbles: true })); ");
要是担心填充后字段已经失焦,可以先focus()再填充,再触发事件。
3. 等待自动补全列表出现后再选择选项
有时候问题不在填充,而是没等自动补全列表加载出来就执行下一步。一定要加上等待逻辑,确保下拉列表出现后再点击选项:
$field = $this->getSession()->getPage()->findField('你的字段名称'); $field->focus(); $field->type('Actualités'); // 等待自动补全下拉框出现(这里选择器根据Drupal版本调整,jQuery UI的是.ui-autocomplete) $autocompleteDropdown = $this->getSession()->getPage()->waitFor(5, function() { return $this->getSession()->getPage()->find('css', '.ui-autocomplete'); }); if ($autocompleteDropdown) { // 选择目标选项,比如包含特定文本的第一个选项 $targetOption = $autocompleteDropdown->find('css', 'li:contains("目标文章标题")'); $targetOption->click(); }
额外注意事项
- 确保你的Behat驱动(比如Selenium)启用了JavaScript支持,Drupal的自动补全完全依赖JS;
- 检查页面上自动补全元素的选择器,不同Drupal版本的自动补全HTML结构可能有差异,比如有些用
autocomplete-dropdown类; - 如果是多字段的情况,处理完一个字段后,记得手动把焦点移到下一个字段,避免自动失焦影响后续操作。
内容的提问来源于stack exchange,提问作者Jaeger
相关产品推荐
相关产品推荐

