2012-09-25 10 views
9

Escenario: Modificar y guardar un cambio incompleta a una campaña¿Cómo hacer que Behat espere una llamada AJAX?

Given I click on the Campaign section folder 
And I press Save in the selected Campaign 
Then I should see an error balloon informing the changes cannot be saved 

El punto es que este 'globo de error' en el paso final es una llamada ajax que luego poner un globo de color verde o rojo en función del éxito de la operacion. Actualmente lo que hago es después de 'Y presiono Guardar ...' Voy a hacer un sueño (3) para darle tiempo a que aparezca este globo. Esto no parece muy inteligente porque está perdiendo el tiempo y también porque algunas veces puede llevar más o menos tiempo procesar esta llamada.

¿Cómo pueden hacer que sus pruebas de behat esperen a que Ajax se haga en lugar de simplemente poner a las bestias a dormir?

¡muchas gracias por cualquier comentario!

+0

¿mostrar algún código? – StaticVariable

Respuesta

26

Esto se hace esperando que sus sobresalientes llamadas ajax lleguen a 0. jQuery.active comprobará solo eso para usted.

En su FeatureContext.php, puede hacer algo como;

public function iShouldSeeAnErrorBalloon($title) 
{ 
    $time = 5000; // time should be in milliseconds 
    $this->getSession()->wait($time, '(0 === jQuery.active)'); 
    // asserts below 
} 

Y asegúrese de que utiliza un controlador de visón que se ejecuta JavaScript y Ajax (el valor por defecto no lo hace).

1

En caso de que utilice PrototypeJS (por ejemplo Magento), el código equivalente es:

public function iShouldSeeAnErrorBalloon($title) 
{ 
    $this->getSession()->wait($duration, '(0 === Ajax.activeRequestCount)'); 
    // asserts below 
} 
+1

¿de dónde viene la variable de $ duration? –

+0

http://mink.behat.org/api/behat/mink/session.html#wait() 'público vacío esperar (tiempo entero, condición de cadena) Espera algún tiempo o hasta que la condición JS se vuelva verdadera. – Steff

+0

Solo estoy actualizando ese enlace, aunque como he usado los números de línea, sin duda estará desactualizado próximamente: https://github.com/Behat/Mink/blob/master/src/Behat/Mink/Session.php # L318-L329 – DanielM

2

lo hago por la espera de que el DOM para cambiar como resultado de la llamada Ajax. Hice una subclase de DocumentElement, llamándolo AsyncDocumentElement y reemplazando el método findAll:

public function findAll($selector, $locator, $waitms=5000) 
{ 
    $xpath = $this->getSession()->getSelectorsHandler()->selectorToXpath($selector, $locator); 

    // add parent xpath before element selector 
    if (0 === strpos($xpath, '/')) { 
     $xpath = $this->getXpath().$xpath; 
    } else { 
     $xpath = $this->getXpath().'/'.$xpath; 
    } 

    $page = $this->getSession()->getPage(); 

    // my code to wait until the xpath expression provides an element 
    if ($waitms && !($this->getSession()->getDriver() instanceof \Behat\Symfony2Extension\Driver\KernelDriver)) { 
     $templ = 'document.evaluate("%s", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength > 0;'; 

     $waitJs = sprintf($templ, $xpath); 

     $this->getSession()->wait($waitms, $waitJs); 
    } 

    return $this->getSession()->getDriver()->find($xpath); 
} 

Luego, en \ Behat \ Mink \ Sesión I cambió el constructor de usar esa clase.

public function __construct(DriverInterface $driver, SelectorsHandler $selectorsHandler = null) 
{ 
    $driver->setSession($this); 

    if (null === $selectorsHandler) { 
     $selectorsHandler = new SelectorsHandler(); 
    } 

    $this->driver   = $driver; 
    $this->page    = new AsyncDocumentElement($this); 
    $this->selectorsHandler = $selectorsHandler; 
} 

Una vez que hice esto, encontré que mis pruebas AngularJS estaban funcionando. Hasta ahora, solo he probado en Firefox.

Cuestiones relacionadas