/**
* Returns a crawler Form object for the form pointed to by the
* passed Crawler.
*
* The returned form is an independent Crawler created to take care
* of the following issues currently experienced by Crawler's form
* object:
* - input fields disabled at a higher level (e.g. by a surrounding
* fieldset) still return values
* - Codeception expects an empty value to match an unselected
* select box.
*
* The function clones the crawler's node and creates a new crawler
* because it destroys or adds to the DOM for the form to achieve
* the desired functionality. Other functions simply querying the
* DOM wouldn't expect them.
*
* @param Crawler $form the form
* @param string $action the form's absolute URL action
* @return Form
*/
private function getFormFromCrawler(Crawler $form, $action)
{
$fakeDom = new \DOMDocument();
$fakeDom->appendChild($fakeDom->importNode($form->getNode(0), true));
$node = $fakeDom->documentElement;
$cloned = new Crawler($node, $action);
$shouldDisable = $cloned->filter('input:disabled:not([disabled]),select option:disabled,select optgroup:disabled option:not([disabled])');
foreach ($shouldDisable as $field) {
$field->parentNode->removeChild($field);
}
$selectNonMulti = $cloned->filterXPath('//select[not(@multiple) and not(option[@value=""])]');
$opt = new \DOMElement('option');
foreach ($selectNonMulti as $field) {
$node = $field->insertBefore($opt, $field->firstChild);
$node->setAttribute('value', '');
}
return $cloned->form();
}