Skip to content

Commit

Permalink
bug #10841 [DomCrawler] Fixed image input case sensitive (geoffrey-br…
Browse files Browse the repository at this point in the history
…ier)

This PR was submitted for the master branch but it was merged into the 2.3 branch instead (closes #10841).

Discussion
----------

[DomCrawler] Fixed image input case sensitive

| Q             | A
| ------------- | ---
| Bug fix?      | [yes]
| New feature?  | [no]
| BC breaks?    | [no]
| Deprecations? | [no]
| Tests pass?   |
| Fixed tickets |
| License       | MIT
| Doc PR        |

I'm currently testing the payment workflow in a project. The problem is that when I reach the credit card type selection (CB, VISA ...) I cannot submit the desired one because its name is in uppercase (take a look at the screenshot).

![](http://s22.postimg.org/oz5cm3fwh/example.png)

Commits
-------

ab1198f [DomCrawler] Fixed image input case sensitive
  • Loading branch information
fabpot committed May 12, 2014
2 parents d9fec70 + ab1198f commit 792b956
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 13 deletions.
5 changes: 3 additions & 2 deletions src/Symfony/Component/DomCrawler/Crawler.php
Expand Up @@ -651,8 +651,9 @@ public function selectLink($value)
*/
public function selectButton($value)
{
$xpath = sprintf('//input[((@type="submit" or @type="button") and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', static::xpathLiteral(' '.$value.' ')).
sprintf('or (@type="image" and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', static::xpathLiteral(' '.$value.' '), $value, $value).
$translate = 'translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")';
$xpath = sprintf('//input[((contains(%s, "submit") or contains(%s, "button")) and contains(concat(\' \', normalize-space(string(@value)), \' \'), %s)) ', $translate, $translate, static::xpathLiteral(' '.$value.' ')).
sprintf('or (contains(%s, "image") and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %s)) or @id="%s" or @name="%s"] ', $translate, static::xpathLiteral(' '.$value.' '), $value, $value).
sprintf('| //button[contains(concat(\' \', normalize-space(string(.)), \' \'), %s) or @id="%s" or @name="%s"]', static::xpathLiteral(' '.$value.' '), $value, $value);

return $this->filterXPath($xpath);
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php
Expand Up @@ -206,7 +206,7 @@ protected function initialize()
throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName));
}

if ('input' == $this->node->nodeName && 'checkbox' != $this->node->getAttribute('type') && 'radio' != $this->node->getAttribute('type')) {
if ('input' == $this->node->nodeName && 'checkbox' != strtolower($this->node->getAttribute('type')) && 'radio' != strtolower($this->node->getAttribute('type'))) {
throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $this->node->getAttribute('type')));
}

Expand All @@ -215,7 +215,7 @@ protected function initialize()
$this->multiple = false;

if ('input' == $this->node->nodeName) {
$this->type = $this->node->getAttribute('type');
$this->type = strtolower($this->node->getAttribute('type'));
$optionValue = $this->buildOptionValue($this->node);
$this->options[] = $optionValue;

Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/DomCrawler/Field/FileFormField.php
Expand Up @@ -103,7 +103,7 @@ protected function initialize()
throw new \LogicException(sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName));
}

if ('file' != $this->node->getAttribute('type')) {
if ('file' != strtolower($this->node->getAttribute('type'))) {
throw new \LogicException(sprintf('A FileFormField can only be created from an input tag with a type of file (given type is %s).', $this->node->getAttribute('type')));
}

Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/DomCrawler/Field/InputFormField.php
Expand Up @@ -34,11 +34,11 @@ protected function initialize()
throw new \LogicException(sprintf('An InputFormField can only be created from an input or button tag (%s given).', $this->node->nodeName));
}

if ('checkbox' == $this->node->getAttribute('type')) {
if ('checkbox' == strtolower($this->node->getAttribute('type'))) {
throw new \LogicException('Checkboxes should be instances of ChoiceFormField.');
}

if ('file' == $this->node->getAttribute('type')) {
if ('file' == strtolower($this->node->getAttribute('type'))) {
throw new \LogicException('File inputs should be instances of FileFormField.');
}

Expand Down
12 changes: 6 additions & 6 deletions src/Symfony/Component/DomCrawler/Form.php
Expand Up @@ -352,7 +352,7 @@ public function offsetUnset($name)
protected function setNode(\DOMNode $node)
{
$this->button = $node;
if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) {
if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array(strtolower($node->getAttribute('type')), array('submit', 'button', 'image')))) {
if ($node->hasAttribute('form')) {
// if the node has the HTML5-compliant 'form' attribute, use it
$formId = $node->getAttribute('form');
Expand Down Expand Up @@ -394,7 +394,7 @@ private function initialize()

// add submitted button if it has a valid name
if ('form' !== $this->button->nodeName && $this->button->hasAttribute('name') && $this->button->getAttribute('name')) {
if ('input' == $this->button->nodeName && 'image' == $this->button->getAttribute('type')) {
if ('input' == $this->button->nodeName && 'image' == strtolower($this->button->getAttribute('type'))) {
$name = $this->button->getAttribute('name');
$this->button->setAttribute('value', '0');

Expand Down Expand Up @@ -445,17 +445,17 @@ private function addField(\DOMNode $node)
}

$nodeName = $node->nodeName;
if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == $node->getAttribute('type')) {
if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == strtolower($node->getAttribute('type'))) {
$this->set(new Field\ChoiceFormField($node));
} elseif ('input' == $nodeName && 'radio' == $node->getAttribute('type')) {
} elseif ('input' == $nodeName && 'radio' == strtolower($node->getAttribute('type'))) {
if ($this->has($node->getAttribute('name'))) {
$this->get($node->getAttribute('name'))->addChoice($node);
} else {
$this->set(new Field\ChoiceFormField($node));
}
} elseif ('input' == $nodeName && 'file' == $node->getAttribute('type')) {
} elseif ('input' == $nodeName && 'file' == strtolower($node->getAttribute('type'))) {
$this->set(new Field\FileFormField($node));
} elseif ('input' == $nodeName && !in_array($node->getAttribute('type'), array('submit', 'button', 'image'))) {
} elseif ('input' == $nodeName && !in_array(strtolower($node->getAttribute('type')), array('submit', 'button', 'image'))) {
$this->set(new Field\InputFormField($node));
} elseif ('textarea' == $nodeName) {
$this->set(new Field\TextareaFormField($node));
Expand Down
7 changes: 7 additions & 0 deletions src/Symfony/Component/DomCrawler/Tests/FormTest.php
Expand Up @@ -631,6 +631,13 @@ public function testSubmitWithoutAFormButton()
$this->assertSame($nodes->item(0), $form->getFormNode(), '->getFormNode() returns the form node associated with this form');
}

public function testTypeAttributeIsCaseInsensitive()
{
$form = $this->createForm('<form method="post"><input type="IMAGE" name="example" /></form>');
$this->assertTrue($form->has('example.x'), '->has() returns true if the image input was correctly turned into an x and a y fields');
$this->assertTrue($form->has('example.y'), '->has() returns true if the image input was correctly turned into an x and a y fields');
}

/**
* @expectedException \InvalidArgumentException
*/
Expand Down

0 comments on commit 792b956

Please sign in to comment.