web-dev-qa-db-fra.com

Lecture de variables JavaScript avec Selenium WebDriver

J'utilise Selenium WebDriver (Java) et TestNG pour effectuer des tests sur un site Web que j'ai créé. Sur ce site Web, j’ai aussi du JavaScript et dans certaines fonctions, il renvoie des valeurs et les transmet également à la console du navigateur via console.log().

Je me demandais s’il existe un moyen simple pour Selenium WebDriver d’accéder à certaines de ces informations JavaScript afin que je puisse effectuer des assertions à l’aide de TestNG.

Je suis assez nouveau sur Selenium mais je comprends que vous pouvez faire quelque chose comme:

WebDriver driver = new ChromeDriver();
driver.findElement(By.id("btn")).click();

Donc, est-ce que je peux faire quelque chose de similaire en utilisant WebDriver pour lire le code JavaScript sur le site?


Clarification

Il semble que les gens partent du principe que j'essaie d'exécuter du code JavaScript via Selenium.

Ce n'est pas le cas. Au lieu de cela, j'essaie de stocker la variable JavaScript déjà définie à l'aide de Selenium.

Fondamentalement, je souhaite que Selenium puisse récupérer la valeur de la variable JavaScript, la stocker localement, puis effectuer un test d'assertion dessus.


Tentative 1

Disons que j'ai le code JS suivant pour mon site web:

$(document).ready(function() {
    var foo = $(#"input-field-val").val();

    function returnFoo() {
        return foo;
    }
});

D'après ce que j'ai lu et compris, dans mon fichier de test séparé de Selenium (Selenium.Java), je devrais être capable de faire quelque chose comme ceci ?:

public class Selenium {
    WebDriver driver = new FirefoxDriver();
    JavascriptExecutor js = (JavascriptExecutor) driver;

    @Test
    public void testSample() {
        driver.get("www.mywebsite.com");
        js.executeScript("alert(returnFoo());");
    }
}

Je fais quelque chose de similaire à ce qui précède, mais aucune boîte d’alerte ne s’ouvre. Au lieu de cela, je reçois un message d'erreur:

Exception in thread "main" org.openqa.Selenium.WebDriverException: ReferenceError: returnFoo is not defined

Je suis sûr que je ne comprends pas ce que cela signifie quand on dit que la variable JS

ne devrait pas faire partie d'une fermeture ou d'une variable locale

J'ai également essayé de définir une variable globale au-dessus de $(document).ready(function()... et le réglage est dans function returnFoo() mais ne fonctionne toujours pas.


Tentative 2

J'ai déplacé foo et returnFoo() en dehors de $(document).ready(function().... Cela a corrigé le message ReferenceError que je recevais Essayez 1 ci-dessus.

J'ai également donné à foo une valeur afin que mon code JS ressemble à ceci:

var foo = "Selenium test run";

$(document).ready(function() {
...
});

function returnFoo() {
    return foo;
}

Maintenant, j'ai du mal à assigner le retour de returnFoo() à une variable locale dans mon test Selenium. Voici ce que j'ai essayé:

public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        JavascriptExecutor js = (JavascriptExecutor) driver;

        driver.get("http://localhost:8080/HTML5TestApp/prod.html");
        Object val = js.executeScript("window.returnFoo();");
        System.out.println(val);
    } 

Mais la console affiche null au lieu de la valeur réelle de "Test de sélénium".

Tentative 2 - SOLUTION

Il me semble que si je fais Object val = js.executeScript("alert(returnFoo());");, je reçois la valeur de foo.


SOLUTION

Alors voici la solution que j'ai trouvée avec mon problème grâce à la solution de Martin Foot ci-dessous.

Dans mon fichier JavaScript, j'ai créé un var et une fonction setter/getter comme ceci:

index.js

var seleniumGlobal;

$(document).ready(function() {
...
)};

function setSG(toSet) {
    seleniumGlobal = toSet;
}

function getSG() {
    return seleniumGlobal;
}

SampleTest.Java

// Do all the necessary imports

public class SampleTest {
    WebDriver driver = new FirefoxDriver();
    JavascriptExecutor js = (JavascriptExecutor) driver;

    @Test
    public void testPrintVal() {
        String sgVal = (String) js.executeScript("alert(getSG());");
        Assert.assertEquals("new value for seleniumGlobal", sgVal);
    }
}

Ainsi, chaque fois que du code dans mon JavaScript définit ma variable seleniumGlobal par la méthode setter, je peux l'appeler via mon test Selenium et y faire des assertions.

Ce n'est probablement pas le moyen le plus efficace de le faire, mais si quelqu'un d'autre a une meilleure solution, veuillez me le faire savoir.

53
FilmiHero

Dans Ruby vous pouvez utiliser page.execute_script pour évaluer une variable JavaScript (si elle est accessible depuis le navigateur Web). Il semble qu’il existe une méthode similaire dans Java ici .

Modifier: il peut s’agir d’un cas d’utilisation plus adapté à un framework de test unitaire JavaScript tel que Jasmine .

13
Martin Foot

Tout ce que tu dois faire est:

Object val = js.executeScript("return returnFoo();");

Cela vous donnera ce que vous cherchez.

45
Jose Sutilo

Aucune fonction JavaScript requise. Ni alert() n'est nécessaire.

Object result = js.executeScript("return globalVar");

Pour Python:

result = driver.execute_script("return globalVar")
26
wTyeRogers