"окно" не определено ScriptEngine в Java для Selenium - PullRequest
0 голосов
/ 17 сентября 2018

Что я делаю

Я пытаюсь вызвать что-то базовое в javascript, которое выполняется после загрузки страницы.Я делаю это для Selenium.Зачем?Я слышал, вы спрашиваете, это потому, что я делаю простой инструмент ожидания, который ждет до тех пор, пока страница не будет загружена, ЕСЛИ щелчок или иное «использование» веб-элемента приводит к перезагрузке указанной страницы.Этот «инструмент» просто использует поток вне main, чтобы попробовать webelement, подождать, пока его ссылка не устареет, а также дождаться «события загрузки» в javascript.Если обе эти вещи происходят до некоторого времени ожидания, я знаю, что A: webelement вызывает перезагрузку страницы, а B: я соответственно дождался перезагрузки страницы.Это полезно, потому что я могу программно определить, заставляет ли данный веб-элемент перезагрузить страницу, просто попробовав ее и автоматически дождавшись ее.

Проблема

Для этого мне нужно запустить событие загрузки javascript в java.Я новичок в javascript, но я исследовал ScriptEngine API, который поставляется с Java.Я решил использовать это и попытаться запустить простую функцию javascript, когда происходит событие onload.Проблема в том, что я получаю «окно» не определенное исключение.Так как объект ScriptEngine, который я использую для запуска javascript, принимает только строку из того, что я использую, я не могу хорошо проверить ошибки.

То, что я пробовал

Я пытался изучить документацию по этой ошибке и поискать в ней переполнение стека, но я не могу найти ни Java-ориентированный ответ, ни тот, который хорошо его объясняетдостаточно для меня.Все, что я почерпнул из исследования, это то, что мне, возможно, потребуется указать URL-адрес в качестве объекта окна или что-то еще, но другие источники заставили меня поверить, что, если я использую окно браузера, объект окна уже должен быть определен.Я не знаю что верить.Код, о котором идет речь:

WebDriverWait wait = new WebDriverWait(driver,timeoutSeconds);
//initialize a wait for a page to reload
        try{
            //wait untill our element we clicked is stale
            wait.until(ExpectedConditions.stalenessOf(webElement));
            //try running javascript to do something (here i tried a popup)
            //later I want this code to wait until the page is loaded and
            //then send something BACK to the javacode that I can wait for
            //so that Basically I wait until the page onload event has fired
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine javascript = manager.getEngineByName("javascript");
            try {
                javascript.eval("window.addEventListener('load', function() 
                        {" +
                        " alert(ok); " +
                        "})");
            } catch (ScriptException e) {
                e.printStackTrace();
                System.out.println("javascript thing failed");
            }

        }
        catch (TimeoutException e){
            //page remained static and webelement doesn't cause a page 
            //reload
        }

Обратите внимание, что этот код находится внутри потока, который проходит рядом с main.Простая цель состоит в том, чтобы подождать, пока элемент, на который мы нажимаем, не устареет и не произойдет событие загрузки страницы.Если обе эти вещи не произойдут, веб-элемент, на который мы нажали, не приведет к перезагрузке страницы.Если элемент становится устаревшим, мы знаем, что элемент изменяется, но страница не перезагружается.Если обе вещи случаются, то мы знаем, что webelement перезагрузит страницу.Все ждет соответственно, и следующий webelement готов быть найденным.Это полезно для Selenium, потому что мне не нужно беспокоиться о перезагрузках страницы или элементах, которые удаляются сами, но не перезагружают страницу или любой другой странный крайний случай, который может вызвать исключение StaleReference, когда этого не должно быть.Прямо сейчас выполнение этого блока кода возвращает следующую трассировку стека:

Запуск ChromeDriver 2.41.578737 (49da6702b16031c40d63e5618de03a32ff6c197e) через порт 30355 Разрешены только локальные подключения.17 сентября 2018 15:59:11 org.openqa.selenium.remote.ProtocolHandshake createSession INFO: Обнаруженный диалект: OSS sendKeys [[ChromeDriver: chrome на XP (1c2e7600f13bc56ff3b60f9a2de6ee93)] -> name: q].; @ 6dd2f3a9 страница была статической отправки [[ChromeDriver: chrome в XP (1c2e7600f13bc56ff3b60f9a2de6ee93)] -> name: q] null

сбой javascript

javax.script.ScriptException: ReferenceError: «окно» не определено в> в строке номер 1

страница перезагрузилась

в jdk.scripting.nashorn / jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException (NashornScriptEngine.java:469) в jdk.scripting.nashorn / jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl (NashornScriptEngine.java:453) в jdk.sornp.jp.NashornScriptEngine.evalImpl (NashornScriptEngine.java:405) в jdk.scripting.nashorn / jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl (NashornScriptEngine.java:401) вjdk.scripting.nashorn / jdk.nashorn.api.scripting.NashornScriptEngine.eval (NashornScriptEngine.java:154) в java.scripting / javax.script.AbstractScriptEngine.eval (AbstractScriptEngine.java:264) в SeleniumTest.tr.isPageReloaded.java:48) в java.base / java.lang.Thread.run (Thread.java:844) Причина:: 1 ReferenceError: «окно» не определено в jdk.scripting.nashorn / jdk.nashorn.internal.runtime.ECMAErrors.error (ECMAErrors.java:57) в jdk.scripting.nashorn / jdk.nashorn.internal.runtime.ECMAErrors.referenceError (ECMAErrors.java:319) в jdk.scripting.nashorn / jdk.nashorn.runtime.ECMAErrors.referenceError (ECMAErrors.java:291) в jdk.scripting.nashorn / jdk.nashorn.internal.objects.Global. noSuchProperty (Global.java:1615) в jdk.scripting.nashorn.scripts / jdk.nashorn.internal.scripts.Script $ Перекомпиляция $ 1 $ \ ^ eval_ / 1394969414.: программа (: 1) в jdk.scripting.nashorn / jdk.nashorn.internal.runtime.ScriptFunctionData.invoke (ScriptFunctionData.java: 655) на jdk.scripting.nashorn / jdk.nashorn.internal.runtime.ScriptFunction.invoke (ScriptFunction.java:513) в jdk.scripting.nashorn / jdk.nashorn.internal.runtime.ScriptRuntime.apply (ScriptRuntime.java:527) в jdk.scripting.nashorn / jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl (NashornScriptEngine.java:448) ... еще 6

Процесс завершен с кодом выхода 0

Дополнительные примечания

Обратите внимание на жирные линии в трассировке стека, это то, что я добавил для печати при некоторых состояниях ошибок.«Сообщение о перезагрузке страницы» также печатается в обычном регистре как сообщение о состоянии.Он отражает состояние кода if else.Ошибка javascript состоит в том, чтобы перехватить исключения javascript и увидеть более наглядно, что это действительно не удалось.Я просто хочу знать, что я должен сделать, чтобы определить окно, чтобы этот код javascript (и будущий код js) выполнялся для меня.Примите во внимание, что я имею опыт работы с Java, но неопытен с Javascript.

1 Ответ

0 голосов
/ 18 сентября 2018

ScriptEngineManager выполняет JavaScript только в JVM, а не в браузере.

Но «окно» является глобальной переменной в браузере, а не в JVM. Вот почему вы получаете window is undefined.

Вы должны использовать executeScript() Selenium api для запуска JavaScript в браузере.

String script = "window.addEventListener('load', function() {" +
                "  alert('ok'); " +
                "})";

JavascriptExecutor js =(JavascriptExecutor)driver;
js.executeScript(script);
...