jhedstrom / drupalextension

An integration layer between Behat, Mink Extension, and Drupal.
GNU General Public License v2.0
209 stars 192 forks source link

How to change/set ajax_timeout #486

Closed miiimooo closed 5 years ago

miiimooo commented 6 years ago

I have found a problem that click/select steps don't wait long enough (or at all?)

Trying to debug it I got this output:

│
    ╳  Unable to complete AJAX request. {"name":"step.after","feature":"Terms","step":"I click the text \"Jag vill vara anonym\"","suite":"default","ajax_timeout":null} (RuntimeException)

You see I have added some debugging code to display the ajax_timeout. The reference in master is here https://github.com/jhedstrom/drupalextension/blob/master/src/Drupal/DrupalExtension/Context/MinkContext.php#L153

I can't work out where to set this. I tried in behat.yml

  extensions:
    Behat\MinkExtension:
      ajax_timeout: 5

I got

    In ArrayNode.php line 311:

  Unrecognized option "ajax_timeout" under "testwork.mink"  
jhedstrom commented 6 years ago

Since the ajax_timeout parameter is provided by this extension, you need to update your extension section to specify Drupal\MinkExtension rather than Behat\MinkExtension:

  extensions:
    Drupal\MinkExtension:
      ajax_timeout: 5

Note that 5 is the default behavior, so you may want to try 10 or 15.

miiimooo commented 6 years ago

Thanks @jhedstrom

Did you notice the error output above? It seems like the default was null there

miiimooo commented 6 years ago

I can see a default of 5 in vendor/drupal/drupal-extension/src/Drupal/MinkExtension/ServiceContainer/MinkExtension.php but I don't think that is used in this context

I have vendor/behat/mink-extension/src/Behat/MinkExtension/Context/RawMinkContext.php which provides the public function getMinkParameter($name) which is used by vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MinkContext.php:iWaitForAjaxToFinish

this is in version ^4 (beta1)

miiimooo commented 6 years ago

Found I had version spaghetti

jhedstrom commented 6 years ago

Glad you got it working :)

miiimooo commented 6 years ago

I realise this is still happening, independent of behat version.

Could someone confirm that in vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/MinkContext.php:153 they actually get a value for $this->getMinkParameter('ajax_timeout')?

I only get NULL and hence a "Unable to complete AJAX request. {"name":"step.after","feature":"XXXXXXXX","step":"XXXXXXXXXXXXX","suite":"default"} (RuntimeException)

When I set the ajax_timeout as you wrote then the first step in my scenario never runs and just sits there and waits.

In the meanwhile I use this workaround and set an ajax_timeout in the suite

  /**
   * Work around https://github.com/jhedstrom/drupalextension/issues/486
   *
   * @BeforeScenario
   */
  public function beforeJavascriptScenario(BeforeScenarioScope $scope) {
    $mink_context = $scope->getEnvironment()->getContext('Drupal\DrupalExtension\Context\MinkContext');
    if (!$mink_context) {
      return;
    }
    if (!$mink_context->getMinkParameter('ajax_timeout')) {
      $suite = $scope->getEnvironment()->getSuite();
      if ($suite->hasSetting('ajax_timeout')) {
        $mink_context->setMinkParameter('ajax_timeout', $suite->getSetting('ajax_timeout'));
      }
    }
  }
arosboro commented 6 years ago

Hi @miiimooo and @jhedstrom

I'm getting the same error for tests that had passed using selenium2 with chrome instead of selenium2 without chrome (I'm not sure which browser is currently configured as it's not in the config). I recently switched to a different platform and am re-configuring behat for javascript tests.

The wait timeout occurs at 12 seconds with the ajax_timeout value in my behat.yml, and with the beforeJavascriptScenario that you supplied, @miiimooo, so I went via the configuration route since it seems to work.

My step is using a custom context that uses $this->getSession()->executeScript() and it seems that the script is not being executed for some reason, although it works in a regular browser console.

arosboro commented 6 years ago

@miiimooo Are you using the Drupal API driver or the drush driver?

arosboro commented 6 years ago

It looks like this is due to using drush without a selenium2 browser, I switched back to configuring selenium2 with chrome, and made sure chrome was running as instructed here: https://packagist.org/packages/dmore/chrome-mink-driver and the behat features requiring javascript worked as usual.

leevh commented 5 years ago

I think some confusion here comes from it sounds like you only need to follow the instructions in https://github.com/jhedstrom/drupalextension/issues/486#issuecomment-385461668 if you want to specify a custom timeout. But if you don't use Drupal\MinkExtension rather than Behat\MinkExtension in your behat.yml, you will not have the timeout variable at all, and iWaitForAjaxToFinish depends on it being set. Seems like maybe the documentation should change to use only Drupal\MinkExtension, or iWaitForAjaxToFinish should provide a default if one is not present.

pfrenssen commented 5 years ago

Yes this is a very good point @leevh.

I propose we do a check and if the value of ajax_timeout is NULL then we throw an exception which explains that Drupal\MinkExtension should be used. This will clear up a lot of confusion I think.

miiimooo commented 5 years ago

Thanks @leevh and @pfrenssen . That was exactly the problem! We've changed this in a number of projects now and the problem is gone

stevenlafl commented 5 years ago

Since the ajax_timeout parameter is provided by this extension, you need to update your extension section to specify Drupal\MinkExtension rather than Behat\MinkExtension:

  extensions:
    Drupal\MinkExtension:
      ajax_timeout: 5

Note that 5 is the default behavior, so you may want to try 10 or 15.

Drupal\MinkExtension extension file or class could not be located.

However, when using Drupal\DrupalExtension, I get: Unrecognized option "ajax_timeout" under "testwork.drupal"

So where is it? I'm using "drupal/drupal-extension": "~3.0",

brooke-heaton commented 4 years ago

I'm equally confused by all of the above. I get the same error as @stevenlafl

jhedstrom commented 4 years ago

The Drupal\MinkExtension class was introduced only in version 4 of this library, so if you're running 3 or older, you will get the class not found error I think.

grasmash commented 4 years ago

I found this a bit tricky. To get it working, I had to split some configuration between Drupal\MinkExtension and Behat\MinkExtension:

    Drupal\MinkExtension:
      ajax_timeout: 5
      browser_name: chrome
      javascript_session: default
      # configure the base url for your site
      base_url: http://local.example.com
      # set default command for "Show last response" step.
      show_cmd: "open %s"
    Behat\MinkExtension:
      sessions:
        default:
          chrome:
            api_url: "http://localhost:9222"
            # Set the optimal Socket Timeout to avoid client-server connection problems in behat scripts.
            socket_timeout: 60
dmgig commented 4 years ago

Fwiw, I have come across this and can't seem to get around the issue. A simpler version of the code in miiimooo's post. But this isn't ideal (pt3). I had to remove the checks, as on mine the suite didn't contain the ajax_timeout config either.

I'm using Acquia BLT which is probably important here.

Using grasmash's answer didn't work for me - adding it as posted into my local.yml (only changing the base_url to mine) I first get a configuration error (see pt1). So I attempted to add the base_url property under Behat\MinkExtension but I still get the familiar AJAX timeout error (see pt2).

pt1

[warning] project.local.uri in blt.yml does not match local.extensions.Behat\MinkExtension.base_url in local.yml.
[warning] project.local.uri = https://teamleaders.ddev.site
[warning] local.extensions.Behat\MinkExtension.base_url =
[warning] Behat is not configured properly.

pt2

Exception: No AJAX timeout has been defined. Please verify that "Drupal\MinkExtension" is configured in behat.yml (and not "Behat\MinkExtension").

pt3

  /**
   * Work around https://github.com/jhedstrom/drupalextension/issues/486
   *
   * @BeforeScenario
   */
  public function beforeJavascriptScenario(BeforeScenarioScope $scope) {
    $mink_context = $scope->getEnvironment()->getContext('Drupal\DrupalExtension\Context\MinkContext');
    if (!$mink_context) {
      return;
    }
    $mink_context->setMinkParameter('ajax_timeout', 5);
  }
gamma613 commented 4 years ago

For myself, the issue seemed to be due to BLT using drupal-extension 4x rather than 3x. I tried a variety of things, including all of the suggestions in here. The only thing that worked, was the solution @dmgig posted in https://github.com/jhedstrom/drupalextension/issues/486#issuecomment-698077823

I modified this: /** @BeforeScenario */ public function gatherContexts(BeforeScenarioScope $scope) { $environment = $scope->getEnvironment(); $this->minkContext = $environment->getContext('Drupal\DrupalExtension\Context\MinkContext'); }

to this: /** @BeforeScenario */ public function gatherContexts(BeforeScenarioScope $scope) { $environment = $scope->getEnvironment(); $this->minkContext = $environment->getContext('Drupal\DrupalExtension\Context\MinkContext'); /* the following fixes an issue introduced after drupal-extension updated. see: https://github.com/jhedstrom/drupalextension/issues/486 */ $this->minkContext->setMinkParameter('ajax_timeout', 5); }

ericchenshine commented 3 years ago

For myself, I find the existing Behat\MinkExtension can be renamed as Drupal\MinkExtension. So the default value 5 of ajax_timeout will work. In order to work with blt ver 11, Behat\MinkExtension.base_url need to be present. Here is my settings:

    Behat\MinkExtension:
      base_url: ${project.local.uri}
    Drupal\MinkExtension:
      browser_name: chrome
      javascript_session: default
      # configure the base url for your site
      base_url: ${project.local.uri}
      # set default command for "Show last response" step.
      show_cmd: "open %s"