Closed josegamboa closed 4 years ago
It's hard to tell without knowing your project and what's in those helpers, but the generic message means you're addressing a form element on a page that is not part of a form
Hi @ciaranmcnulty, Thanks a lot for helping me. I am still doing some investigation about it and this is what I have so far:
I just did a basic test:
` namespace Drupal\Tests\PhpUnit\ExistingSiteJavascript;
use weitzman\DrupalTestTraits\ExistingSiteWebDriverTestBase;
class ExampleWebDriverTest extends ExistingSiteWebDriverTestBase {
public function testContentCreation() { $web_assert = $this->assertSession(); $this->drupalLogin($this->createUser([], NULL, TRUE)); $this->drupalGet('/admin/content'); $web_assert->statusCodeEquals(200); }
}
` This issue seems to be happening when calling $this->drupalLogin ():
file: /core/tests/Drupal/Tests/UiHelperTrait.php
` protected function drupalLogin(AccountInterface $account) { if ($this->loggedInUser) { $this->drupalLogout(); }
$this->drupalGet(Url::fromRoute('user.login'));
$this->submitForm([
'name' => $account->getAccountName(),
'pass' => $account->passRaw,
], t('Log in'));
// @see ::drupalUserIsLoggedIn()
$account->sessionId = $this->getSession()->getCookie(\Drupal::service('session_configuration')->getOptions(\Drupal::request())['name']);
$this->assertTrue($this->drupalUserIsLoggedIn($account), new FormattableMarkup('User %name successfully logged in.', ['%name' => $account->getAccountName()]));
$this->loggedInUser = $account;
$this->container->get('current_user')->setAccount($account);
} `
Then submit form is doing the login process:
` protected function submitForm(array $edit, $submit, $form_html_id = NULL) { $assert_session = $this->assertSession();
// Get the form.
if (isset($form_html_id)) {
$form = $assert_session->elementExists('xpath', "//form[@id='$form_html_id']");
$submit_button = $assert_session->buttonExists($submit, $form);
$action = $form->getAttribute('action');
}
else {
$submit_button = $assert_session->buttonExists($submit);
$form = $assert_session->elementExists('xpath', './ancestor::form', $submit_button);
$action = $form->getAttribute('action');
}
// Edit the form values.
foreach ($edit as $name => $value) {
$field = $assert_session->fieldExists($name, $form);
// Provide support for the values '1' and '0' for checkboxes instead of
// TRUE and FALSE.
// @todo Get rid of supporting 1/0 by converting all tests cases using
// this to boolean values.
$field_type = $field->getAttribute('type');
if ($field_type === 'checkbox') {
$value = (bool) $value;
}
$field->setValue($value);
}
// Submit form.
$this->prepareRequest();
$submit_button->press();
// Ensure that any changes to variables in the other thread are picked up.
$this->refreshVariables();
// Check if there are any meta refresh redirects (like Batch API pages).
if ($this->checkForMetaRefresh()) {
// We are finished with all meta refresh redirects, so reset the counter.
$this->metaRefreshCount = 0;
}
// Log only for JavascriptTestBase tests because for Goutte we log with
// ::getResponseLogHandler.
if ($this->htmlOutputEnabled && !($this->getSession()->getDriver() instanceof GoutteDriver)) {
$out = $this->getSession()->getPage()->getContent();
$html_output = 'POST request to: ' . $action .
'<hr />Ending URL: ' . $this->getSession()->getCurrentUrl();
$html_output .= '<hr />' . $out;
$html_output .= $this->getHtmlOutputHeaders();
$this->htmlOutput($html_output);
}
} `
It seems like somehow the login process is not able to find the button (Log in), even though the button is there and the value is: "Log in", but, if I do hard-code the id of the form in $form_html_id = NULL param, it just works, I did some debugging and the login form seems to be fine and it has the button too, I am not sure how is this happening.
`
$submit_button = $assert_session->buttonExists($submit);
$form = $assert_session->elementExists('xpath', './ancestor::form', $submit_button);
`
Thanks...
Is the button inside the form in the markup?
Hi @ciaranmcnulty ,
Yes, it is: `
this is the logic for file: /core/tests/Drupal/Tests/UiHelperTrait.php
` public function buttonExists($button, TraversableElement $container = NULL) { $container = $container ?: $this->session->getPage(); $node = $container->findButton($button);
if ($node === NULL) {
throw new ElementNotFoundException($this->session->getDriver(), 'button', 'id|name|label|value', $button);
}
return $node;
}
`
Not sure I can offer much more help; the error seems to be coming from inside UiHelperTrait which isn't part of this project
@ciaranmcnulty , Thanks a lot for your help, after digging a little bit more it was a Drupal core issue when authenticating admin users. if the page has two elements with the value Log in, it takes the first one to find the login form, it explains the error above, I have created a patch for fixing it in case someone is having the same issue: https://www.drupal.org/project/drupal/issues/3169604#comment-13816168
Hi Guys,
I am having an issue at the moment:
Drupal\Tests\PhpUnit\ExistingSiteJavascript\TestingTest::testPage Behat\Mink\Exception\ElementNotFoundException: Element matching xpath "./ancestor::form" not found.
/var/www/site/vendor/behat/mink/src/WebAssert.php:418 /var/www/site/docroot/core/tests/Drupal/Tests/UiHelperTrait.php:78 /var/www/site/docroot/core/tests/Drupal/Tests/UiHelperTrait.php:250 /var/www/site/tests/phpunit/src/ExistingSiteJavascript/JavascriptTestBase.php:23
Any ideas?