Skip to content

Commit 83f2609

Browse files
committed
Refactored button clicking, added tests for full coverage
1 parent f56afe3 commit 83f2609

File tree

3 files changed

+75
-28
lines changed

3 files changed

+75
-28
lines changed

src/Codeception/Lib/InnerBrowser.php

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -439,41 +439,47 @@ protected function clickByLocator($link)
439439
*/
440440
private function clickButton(\DOMNode $node)
441441
{
442-
$formParams = [];
443-
$buttonName = (string)$node->getAttribute('name');
444-
$buttonValue = $node->getAttribute('value');
445-
446-
if ($buttonName !== '' && $buttonValue !== null) {
447-
$formParams = [$buttonName => $buttonValue];
442+
/**
443+
* First we check if the button is associated to a form.
444+
* It is associated to a form when it has a nonempty form
445+
*/
446+
$formAttribute = $node->attributes->getNamedItem('form');
447+
if (isset($formAttribute)) {
448+
$form = empty($formAttribute->nodeValue) ? null : $this->filterByCSS('#' . $formAttribute->nodeValue)->getNode(0);
449+
} else {
450+
// Check parents
451+
$currentNode = $node;
452+
$form = null;
453+
while ($currentNode->parentNode !== null) {
454+
$currentNode = $currentNode->parentNode;
455+
if ($currentNode->nodeName === 'form') {
456+
$form = $node;
457+
break;
458+
}
459+
}
448460
}
449461

450-
if (!empty($node->getAttribute('form'))) {
451-
$formCrawler = $this->filterByCSS('#' . $node->getAttribute('form'));
452-
if ($formCrawler->count() !== 1) {
453-
throw new TestRuntimeException("Found form with id {$node->getAttribute('form')} {$formCrawler->count()} times, expected exactly 1");
462+
if (isset($form)) {
463+
$buttonName = $node->getAttribute('name');
464+
if ($buttonName !== '') {
465+
$formParams = [$buttonName => $node->getAttribute('value')];
466+
} else {
467+
$formParams = [];
454468
}
455469
$this->proceedSubmitForm(
456-
new Crawler($formCrawler->getNode(0), $this->getAbsoluteUrlFor($this->_getCurrentUri()), $this->getBaseUrl()),
470+
new Crawler($form, $this->getAbsoluteUrlFor($this->_getCurrentUri()), $this->getBaseUrl()),
457471
$formParams
458472
);
459473
return true;
460-
}
461-
462-
while ($node->parentNode !== null) {
463-
$node = $node->parentNode;
464-
if (!isset($node->tagName)) {
465-
// this is the top most node, it has no parent either
466-
break;
467-
}
468-
if ($node->tagName === 'a') {
469-
$this->openHrefFromDomNode($node);
470-
return true;
471-
} elseif ($node->tagName === 'form') {
472-
$this->proceedSubmitForm(
473-
new Crawler($node, $this->getAbsoluteUrlFor($this->_getCurrentUri()), $this->getBaseUrl()),
474-
$formParams
475-
);
476-
return true;
474+
} else {
475+
// Check if the button is inside an anchor.
476+
$currentNode = $node;
477+
while ($currentNode->parentNode !== null) {
478+
$currentNode = $currentNode->parentNode;
479+
if ($currentNode->nodeName === 'a') {
480+
$this->openHrefFromDomNode($currentNode);
481+
return true;
482+
}
477483
}
478484
}
479485
throw new TestRuntimeException('Button is not inside a link or a form');

tests/data/app/view/form/button-not-in-form.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
<form action="/form/button" method="POST" id="form-id">
66
<input type="hidden" name="text" value="val" />
77
<button type="submit" name="btn0">Submit</button>
8+
<input id="button2" type="submit" form="form-nonexistent" value="Invalid form2" />
9+
<input type="submit" value="Should not submit" form="" />
810
</form>
911
</div>
1012

1113
<div>
1214
<input type="submit" form="form-id" value="Submit 2" />
15+
<input type="submit" value="Outside submit" />
16+
17+
<input id="button2" type="submit" form="form-nonexistent" value="Invalid form" />
1318
</div>
1419
</body>
1520
</html>

tests/unit/Codeception/Module/TestsForWeb.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,42 @@ public function testClickHashButton()
16481648
$this->module->seeCurrentUrlEquals('/form/anchor');
16491649
}
16501650

1651+
public function testClickButtonWithForm()
1652+
{
1653+
$this->module->amOnPage('/form/button-not-in-form');
1654+
$this->module->click('Submit 2');
1655+
$this->module->seeCurrentUrlEquals('/form/button');
1656+
}
1657+
1658+
public function testClickButtonWithEmptyForm()
1659+
{
1660+
$this->module->amOnPage('/form/button-not-in-form');
1661+
$this->expectException(\Codeception\Exception\TestRuntimeException::class);
1662+
$this->module->click('Should not submit');
1663+
$this->module->seeCurrentUrlEquals('/form/button-not-in-form');
1664+
}
1665+
1666+
public function testClickButtonNotInForm()
1667+
{
1668+
$this->module->amOnPage('/form/button-not-in-form');
1669+
$this->expectException(\Codeception\Exception\TestRuntimeException::class);
1670+
$this->module->click('Outside submit');
1671+
}
1672+
1673+
public function testClickButtonWithFormInvalidIdInside()
1674+
{
1675+
$this->module->amOnPage('/form/button-not-in-form');
1676+
$this->expectException(\Codeception\Exception\TestRuntimeException::class);
1677+
$this->module->click('Invalid form2');
1678+
}
1679+
1680+
public function testClickButtonWithFormInvalidIdOutside()
1681+
{
1682+
$this->module->amOnPage('/form/button-not-in-form');
1683+
$this->expectException(\Codeception\Exception\TestRuntimeException::class);
1684+
$this->module->click('Invalid form');
1685+
}
1686+
16511687
public function testSubmitHashForm()
16521688
{
16531689
$this->module->amOnPage('/form/anchor');

0 commit comments

Comments
 (0)