Behat: Backport improved dropdown step handler

This commit is contained in:
Ingo Schommer 2013-06-05 14:59:01 +02:00
parent 1d01347fd3
commit d3a4161a94

View File

@ -273,32 +273,65 @@ class CmsUiContext extends BehatContext
{ {
$field = $this->fixStepArgument($field); $field = $this->fixStepArgument($field);
$value = $this->fixStepArgument($value); $value = $this->fixStepArgument($value);
$nativeField = $this->getSession()->getPage()->findField($field); $nativeField = $this->getSession()->getPage()->findField($field);
if($nativeField) { if($nativeField) {
$nativeField->selectOption($value); $nativeField->selectOption($value);
} else { return;
// TODO Allow searching by label }
$inputField = $this->getSession()->getPage()->find('xpath', "//*[@name='$field']");
if(null === $inputField) { // Given the fuzzy matching, we might get more than one matching field.
throw new \InvalidArgumentException(sprintf( $formFields = array();
// Find by label
$formField = $this->getSession()->getPage()->findField($field);
if($formField) $formFields[] = $formField;
// Fall back to finding by title (for dropdowns without a label)
if(!$formFields) {
$formFields = $this->getSession()->getPage()->findAll(
'xpath',
sprintf(
'//*[self::select][(./@title="%s")]',
$field
)
);
}
// Find by name (incl. hidden fields)
if(!$formFields) {
$formFields = $this->getSession()->getPage()->findAll('xpath', "//*[@name='$field']");
}
assertGreaterThan(0, count($formFields), sprintf(
'Chosen.js dropdown named "%s" not found', 'Chosen.js dropdown named "%s" not found',
$field $field
)); ));
}
// Traverse up to field holder
$containers = array();
foreach($formFields as $formField) {
do { do {
$container = $inputField->getParent(); $container = $formField->getParent();
$containerClasses = explode(' ', $container->getAttribute('class')); $containerClasses = explode(' ', $container->getAttribute('class'));
$containers[] = $container;
} while( } while(
$container $container
&& in_array('field', $containerClasses) && in_array('field', $containerClasses)
&& $container->getTagName() != 'form' && $container->getTagName() != 'form'
); );
if(null === $container) throw new \InvalidArgumentException('Chosen.js field container not found'); }
$triggerEl = $container->find('xpath', './/a'); assertGreaterThan(0, count($containers), 'Chosen.js field container not found');
if(null === $triggerEl) throw new \InvalidArgumentException('Chosen.js link element not found');
$triggerEl->click(); // Default to first visible container
$container = $containers[0];
// Click on newly expanded list element, indirectly setting the dropdown value
$linkEl = $container->find('xpath', './/a[./@href]');
assertNotNull($linkEl, 'Chosen.js link element not found');
$this->getSession()->wait(100); // wait for dropdown overlay to appear
$linkEl->click();
if(in_array('treedropdown', $containerClasses)) { if(in_array('treedropdown', $containerClasses)) {
// wait for ajax dropdown to load // wait for ajax dropdown to load
@ -307,10 +340,11 @@ class CmsUiContext extends BehatContext
"jQuery('#" . $container->getAttribute('id') . " .treedropdownfield-panel li').length > 0" "jQuery('#" . $container->getAttribute('id') . " .treedropdownfield-panel li').length > 0"
); );
} else { } else {
// wait for dropdown overlay to appear // wait for dropdown overlay to appear (might be animated)
$this->getSession()->wait(100); $this->getSession()->wait(300);
} }
$listEl = $container->find('xpath', sprintf('.//li[contains(normalize-space(string(.)), \'%s\')]', $value)); $listEl = $container->find('xpath', sprintf('.//li[contains(normalize-space(string(.)), \'%s\')]', $value));
if(null === $listEl) { if(null === $listEl) {
throw new \InvalidArgumentException(sprintf( throw new \InvalidArgumentException(sprintf(
@ -318,12 +352,10 @@ class CmsUiContext extends BehatContext
$value $value
)); ));
} }
$listEl->find('xpath', './/a')->click(); $listEl->find('xpath', './/a')->click();
} }
}
/** /**
* Returns fixed step argument (with \\" replaced back to "). * Returns fixed step argument (with \\" replaced back to ").
* *