Webdriver executeAsyncScript vs executeScript

Quelle est la différence entre executeAsyncScript et executeScript? Comment puis-je utiliser l'événement comme la fenêtre.onload? J'ai essayé quelque chose comme ceci

((JavascriptExecutor) driver).executeAsyncScript("window.onload = function() {alert('Hello')}"); 

mais bien sûr, cela n'a pas fonctionné... Donc si quelqu'un sait comment il fonctionne s'il vous plaît écrire un exemple

29
demandé sur vispart 2012-11-19 15:27:11

5 réponses

j'utilise executeScript. Exemple:

String cssSelector="...blablabla...";
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("document.getElementById(\'"+cssSelector +"\').click();");
js.executeScript(stringBuilder.toString());

en ce qui concerne les détails des signalements, il y a un problème connu. vous pouvez obtenir plus de détails ici

selon la documentation, la différence est:

executeScript

public java.lang.Object executeScript(java.lang.String script,
                             java.lang.Object... args)

description copiée de l'interface: JavascriptExecutor exécute JavaScript dans le contexte du cadre ou de la fenêtre actuellement sélectionné. Le fragment de script fourni: être exécuté comme le corps de une fonction anonyme. Dans le script, utilisez le document pour faire référence à document en cours. Notez que les variables locales ne seront pas disponibles une fois le script a terminé l'exécution, bien que les variables globales persister. Si le script a une valeur de retour (i.e. si le script contient une instruction de retour), puis les mesures suivantes seront prises:

  • pour un élément HTML, cette méthode renvoie un élément WebElement
  • Pour un virgule, un Double est renvoyé
  • pour un nombre Non décimal, un Long est retourné
  • pour un booléen, un booléen est retourné
  • Pour tous les autres cas, une Chaîne est renvoyée.
  • pour un tableau, retournez une liste avec chaque objet suivant les règles ci-dessus. Nous soutenons les listes imbriquées.
  • sauf si la valeur est nulle ou s'il n'y a pas de valeur de retour, dans laquelle null est retourné

les Arguments doivent être un nombre, un booléen, une chaîne, WebElement, ou une liste de toute combinaison de ce qui précède. Une exception sera faite si le les arguments ne répondent pas à ces critères. Les arguments seront présentés disponible en JavaScript via la variable magique" arguments", comme si la fonction a été appelée par la Fonction".appliquer"

spécifié par: executesccript dans l'interface JavascriptExecutor Paramètres: script-le JavaScript pour exécuter args-les arguments pour script. Peut être vide Retourne: Une des Booléen, Long, String, List ou WebElement. Ou null.

executeAsyncScript

public java.lang.Object executeAsyncScript(java.lang.String script,
                                  java.lang.Object... args)

description copiée de l'interface: JavascriptExecutor exécutez un morceau asynchrone de JavaScript dans le contexte du cadre ou de la fenêtre actuellement sélectionné. Contrairement à l'exécution synchrone JavaScript, les scripts exécutés avec cette méthode doivent signaler explicitement ils sont terminés en invoquant le rappel fourni. Ce rappel est toujours injecté dans la fonction exécutée comme dernier argument. le le premier argument passé à la fonction callback sera utilisé comme script de résultat. Cette valeur sera traitée de la même manière que le cas synchrone.

exemple #1: effectuer un sommeil dans le navigateur sous test.

 long start = System.currentTimeMillis();
   ((JavascriptExecutor) driver).executeAsyncScript(
       "window.setTimeout(arguments[arguments.length - 1], 500);");
   System.out.println(
       "Elapsed time: " + (System.currentTimeMillis() - start));  

exemple 2: synchronisation d'un test avec une application AJAX:

 WebElement composeButton = driver.findElement(By.id("compose-button"));
   composeButton.click();
   ((JavascriptExecutor) driver).executeAsyncScript(
       "var callback = arguments[arguments.length - 1];" +
       "mailClient.getComposeWindowWidget().onload(callback);");
   driver.switchTo().frame("composeWidget");
   driver.findElement(By.id("to")).sendKeys("bog@example.com");

exemple n ° 3: injection d'un XMLHttpRequest, et en attendant le résultat:

 Object response = ((JavascriptExecutor) driver).executeAsyncScript(
       "var callback = arguments[arguments.length - 1];" +
       "var xhr = new XMLHttpRequest();" +
       "xhr.open('GET', '/resource/data.json', true);" +
       "xhr.onreadystatechange = function() {" +
       "  if (xhr.readyState == 4) {" +
       "    callback(xhr.responseText);" +
       "  }" +
       "}" +
       "xhr.send();");
   JSONObject json = new JSONObject((String) response);
   assertEquals("cheese", json.getString("food"));

les arguments Script doivent être un nombre, un booléen, une chaîne, WebElement, ou une Liste de toute combinaison de ce qui précède. Une exception sera faite si les arguments ne répondent pas à ces critères. Les arguments seront mis à disposition du JavaScript via la variable "arguments".

spécifié par: executeAsyncScript dans l'interface JavascriptExecutor Paramètres: script-le JavaScript à exécuter. args - Argument pour le script. Peut-être vide. Retourne: un de booléen, long, String, Liste, WebElement, ou la valeur null.

la documentation détaillée est ici

22
répondu eugene.polschikov 2016-09-23 09:12:58

(en Gardant simple et correct.)

La différence pertinente entre execteScript et executeAsyncScript c'est:

la fonction invoquée avec executeAsyncScript prend un 'callback fait' comme dernier argument, qui être appelé pour signaler que le script est exécuté.

cela permet de l'utiliser avec du code qui ne 'finit' que lorsqu'un callback est utilisé - par exemple. setTimeout ou asynchrone XHR. Si le 'callback' n'est pas convoquée dans les limites de délai retournés promesse sera rejetée.

contrairement à l'exécution de JavaScript synchrone avec # executeScript, les scripts exécutés avec [#executeAsyncScript] doit signaler explicitement qu'ils sont terminés en invoquant le callback fourni. Ce callback sera toujours injecté dans la fonction exécutée comme dernier argument..

Qui est les deux fonctions bloquent le contrôle du WebDriver flux jusqu'à ce qu'ils aient terminé - soit la fin du code pour executeScript ou en appelant le 'callback terminé' avec executeAsyncScript: "async" dans le nom signifie le mécanisme de signal utilisé et ne signifie pas/n'implique pas que le code JavaScript est réellement exécuté asynchrone par rapport au WebDriver.

18
répondu user2864740 2017-03-19 19:31:53

la principale différence entre ceux-ci est que les scripts exécutés avec async doivent signaler explicitement qu'ils sont terminés en invoquant le callback fourni. Ce callback est toujours injecté dans la fonction exécutée comme dernier argument.

5
répondu sphair 2014-05-30 07:57:08
((JavascriptExecutor) driver).executeScript("alert('Hello');"); 

afficher l'alerte:

(pilote(JavascriptExecutor)).executeAsyncScript () est utilisé lorsque le JS prend du temps à exécuter E. G. dans un appel de Service Web.

window.onload s'assure que le JS est exécuté lorsque la page est chargée complètement.

2
répondu Ishank Dubey 2016-08-29 20:19:44

j'ai passé beaucoup de temps à comprendre cette fonction et finalement je l'ai eue. follwing code, ce sera beaucoup plus:

/**
 * executeAsyncScript document mentioned callback is a browser intrinsic function for returning deferred value (e.g 123 in example) from
 * js environment to Java environment
 * 
 */
@Test
public void testAsyncScript() {
    webDriver.manage().timeouts().setScriptTimeout(1, TimeUnit.SECONDS);
    Integer a = 23;
    TestUtil.elapse("first", () -> {
        Object value = getJsExecutor().executeAsyncScript("window.setTimeout(arguments[arguments.length - 1](123), 500);", a);
        // following code should be executed after 500ms timeout
        System.out.println("a is " + a); // a has nothing to do with the documented "callback"
        assertEquals(123, value);
    });

}
1
répondu truetime 2017-03-13 14:04:33