2016-05-05 10 views
0

Ich habe dieses Szenario:Selen async Skript im eigenen Thread blockiert andere Skripte

Verschiedene Skripte müssen innerhalb des Browsers ausgeführt werden. Eine davon ist das Senden einer Nachricht von einem Browser zu einem anderen (WebRTC). Ich möchte die Verzögerung jeder Operation messen, insbesondere Nachrichten senden.

Um dies zu erreichen, habe ich einen eigenen Thread für jeden Selen-Treiber erstellt, der die Skripte ausführt. Desweiteren habe ich einen weiteren Thread erstellt, der darauf wartet, dass Nachrichten von anderen Browsern zum betrachteten Browser gelangen. Der Faden, der für die Nachrichten wartet führt eine asynchrone Skript wie folgt:

String message = (String) ((JavascriptExecutor) driver).executeAsyncScript(
"window.receivedMessage = function(message_id){" + 
            "arguments[arguments.length - 1](message_id);" + 
          "}"); 

Wie Sie sehen, ich für einen Rückruf warte, die aufgerufen wird, wenn ein Browser eine Nachricht empfängt.

Leider blockiert dies jedes andere Skript, das ausgeführt werden soll, nachdem dieses asynchrone Skript im Browser registriert wurde (spielt keine Rolle, wenn .executeScript() oder .executeAsyncScript()).

Hat Someoe eine Idee, wie man ständig darauf wartet, dass Nachrichten ankommen UND andere Skripte mit einem Webdriver ausführen?

EDIT

By the way: busy waiting sollte die Lösung nicht sein. Ich würde einen Weg bevorzugen, Selen irgendwie zu benachrichtigen, dass eine Operation durchgeführt wird, ohne ständig das Ergebnis vom Fahrer abzufragen.

+0

Haben Sie eine Option, um zu überprüfen, ob die Nachricht auf der Benutzeroberfläche des Browsers empfangen wurde? – QVSJ

+0

@QVSJ Meinst du, wenn ich Zugriff auf den Browser habe, der die Nachricht empfängt? Ja. Ich kann den Code des Browsers auch ändern. – firsti

Antwort

0

Eine Möglichkeit wäre, die Nachrichten in einer globalen Variablen zu speichern und sie zu bearbeiten, sobald die anderen Skripte ausgeführt wurden. Hier ein Beispiel:

JavascriptExecutor js = (JavascriptExecutor)driver; 
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS); 

// set a listener for the messages 
js.executeScript(
    "window._asyncResult = [];      " + 
    "window.receivedMessage = function(message_id) { " + 
    " window._asyncResult.push(message_id);   " + 
    "};            "); 

// send a message asynchroniously every second 
js.executeScript(
    "window._asyncTimer = setInterval(function(){  " + 
    " window.receivedMessage(Math.random());   " + 
    "}, 1000);          "); 

// wait for 5 messages and return the list 
List messages = (ArrayList)js.executeAsyncScript(
    "var callback = arguments[arguments.length - 1]; " + 
    "(function fn(){         " + 
    " if(window._asyncResult.length > 5) {   " + 
    " clearInterval(window._asyncTimer);   " + 
    " return callback(window._asyncResult);  " + 
    " }            " + 
    " setTimeout(fn, 30);       " + 
    "})();           "); 
+0

Danke für die Antwort, aber ich denke, das funktioniert nicht für mich. Ich habe es versucht und das Skript wird immer noch vom AsyncScript blockiert. Das Problem ist hauptsächlich, dass es scheint, dass zwei Skripte nicht parallel zu einem Treiber ausgeführt werden können. Selbst wenn einer von ihnen ein AsyncScript wäre und nur eine Funktion, die darauf wartet, angerufen zu werden. Der Treiber scheint immer noch auf den Rückruf zu warten, bevor er die folgenden Skripte ausführt. – firsti

Verwandte Themen