/** * 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(); }
/** * Returns form field from XPath query. * * @param string $xpath * * @return Symfony\Component\DomCrawler\Field\FormField */ private function getField($xpath) { if (!count($crawler = $this->getCrawler()->filterXPath($xpath))) { throw new ElementNotFoundException($this->session, 'form field', 'xpath', $xpath); } $fieldNode = $this->getCrawlerNode($crawler); $formNode = $fieldNode; do { // use the ancestor form element if (null === ($formNode = $formNode->parentNode)) { throw new ElementNotFoundException($this->session, 'the form field with xpath "' . $xpath . '" was found, but no form element surrounding that field could be found'); } } while ('form' != $formNode->nodeName); // check if form already exists foreach ($this->forms as $form) { if ($formNode->getLineNo() === $form->getFormNode()->getLineNo()) { return $form[$fieldNode->getAttribute('name')]; } } // find form button $buttonNode = $this->findFormButton($formNode); if (null === $buttonNode) { throw new ElementNotFoundException($this->session, 'form submit button for field with xpath "' . $xpath . '"'); } $base = $this->client->getCrawler()->filter('base')->extract(array('href')); if (count($base)) { $base = current($base); } else { $base = NULL; } // init form $button = new Crawler($buttonNode, $this->client->getRequest()->getUri(), $base); $this->forms[] = $form = $button->form(); return $form[$fieldNode->getAttribute('name')]; }