Announcement

Collapse
No announcement yet.

Automatisierung einer Webanwendung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Automatisierung einer Webanwendung

    Hallo,

    ich möchte per JavaScript die Bedienung einer bestehenden Webanwendung (HTML-Seiten) automatisieren.

    Dazu möchte ich die Werte einiger Steuerelemente (Textfelder, Tabellenzellen, etc.) auslesen, Werte in Steuerelemente (z.B. in Textfelder) eintragen und dann durch automatisches Betätigen eines Schalters neue HTML-Seiten laden und dort in Abhängigkeit den vorherigen Eingaben neue Eingaben automatisiert tätigen. Es soll so etwas ähnliches wie ein Testtool werden.

    Die Webanwendung soll unverändert bleiben. Ich habe mir hierzu schon Tools wie „selenium“ angesehen. Diese helfen aber nicht richtig weiter.

    Bisher habe ich es geschafft per JavaScript auf eine HTML-Seite und deren Steuerelemente zuzugreifen. Ich kann Werte auslesen, setzten und auch eine neue Seite aufrufen bzw. die Seite neu laden.

    Mein Script soll jedoch über mehrere Seiten bzw. über mehrere Aufrufe einer Seite (wenn in Abhängigkeit der Eingaben neue Daten nachgeladen werden müssen) laufen.

    Und hier beginnt mein Problem.

    Ich kriege es nicht hin, mein Script solange anzuhalten, bis die neue Seite geladen ist bzw. die benötigten Daten nachgeladen sind und dann die Ausführung des Scriptes fortzuführen.

    Also in etwa :

    lese Wert aus Textfeld 1
    ergänze Wert um xyz setzte Wert in Textfeld 1
    betätige Schalter „suche Daten gemäß Eingabe aus Textfeld 1“
    warte bis Seite neu geladen wurde
    [Seite wird neu geladen mit Ergebnis der Suche in Abhängigkeit der Eingabe im Textfeld 1]
    lese Werte aus Tabelle aus
    vergleiche Werte mit Vorgabe
    wiederhole mit anderen Werten

    Ich habe versucht nach dem Betätigen des Schalters, der das erneute Laden der Seite auslöst, in Abständen von 2 Sekunden zu prüfen, ob die Seite erneut geladen wurde (delay, while (document.readyState != "complete")), jedoch scheint JS nur im single-thread zu arbeiten, so dass die Seite nicht geladen wird und statt dessen das Script endlos ausgeführt wird.

    Auch habe ich schon an „setTimeout“ bzw. „setIntervall“ gedacht. Jedoch wird bei Verwendung dieser Funktionen mein Script weiter durchlaufen statt angehalten zu werden. Da ich jedoch eine Reihe von Anweisungen in einer Funktion abarbeiten möchte, die in einer genauen Reihenfolge vor und nach dem Laden einer Seite ausgeführt werden sollen, ist mir nicht klar, wie mir „setTimeout“ bzw. „setIntervall“ weiterhelfen könnten, da sie ja lediglich eine Funktion erneut aufrufen und nicht etwa die Ausführung einer Funktion unterbrechen und nach einem festgelegten Zeitpunk an eine bestimmte Stelle innerhalb (!) der Funktion zurück kehren um dann dort die weitere Ausführung des Scriptes wieder aufzunehmen.
    Ich komme hier einfach nicht weiter und wäre für eine Lösung sehr, sehr dankbar.

    Ich habe mal versucht, zur Simulation, einen Prototypen meines Problems zu erstellen.

    Dazu habe ich 3 HTML-Seiten erstell.
    1. index.html > enthält 2 Frames; - einer mit einer HMTL-Seite zur
    Steuerung des Informationsframes
    - einer mit einer HMTL-Seite zur Darstellung der Informationen
    2. ctl.htm > enthält Schalter und Funktionen zur Steuerung der Seite
    inhalt.html
    3. inhalt.html > Stellt Informationen dar


    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
    "http://www.w3.org/TR/html4/frameset.dtd">
    <html>
    <head>
    <title>Index</title>
    </head>
    <frameset rows="15%, *">
    <frame src="ctl.html" name="fraCtl" frameborder="1">
    <frame src="inhalt.html" name="fraInhalt" onload="parent.fraCtl.loaded()" onreload="parent.fraCtl.loaded()" frameborder="1">
    <noframes>
    <body>
    </body>
    </noframes>
    </frameset>
    </html>

    -------------------------------------------------------------------------------------------------------------

    <html> <head>
    <title>ctl</title>
    </head>
    <script type="text/javascript">
    var loaded=false;

    function loaded() {
    loaded=true;
    };

    function setNeuenText(_Text) {
    window.top.frames["fraInhalt"].document.getElementById("inpTxt").value=_Text + " neuer Text";
    };

    function setText() {
    var alterText = window.top.frames["fraInhalt"].document.getElementById("inpTxt").value;
    loaded=false;
    window.top.frames["fraInhalt"].location.reload(true);
    //window.setTimeout("setNeuenText('" + alterText + "');", 3000);
    while (loaded==false){};
    setNeuenText(alterText);
    };
    </script>
    <body>
    <input type="button" value="setText" onclick="setText();">
    </body> </html>

    -------------------------------------------------------------------------------------------------------------

    <html> <head>
    <title>Inhalt</title>
    <script type="text/javascript">
    window.onload=function(){
    //simuliert verzögertes Laden der Seite
    var iStart=new Date;

    while (new Date-iStart<2000) {
    };
    };
    </script>
    </head> <body>
    <input type="text" id="inpTxt" value="alter Text"/>
    </body> </html>


    -------------------------------------------------------------------------------------------------------------

    Über nachfolgenden Script-Auszug habe ich versucht zu ermitteln, ob die Seite neu geladen wurde :

    1. Versuch :
    function delay(_WartezeitInMS) {
    var iStart=new Date;
    while (new Date-iStart<_WartezeitInMS) {};
    };

    delay(2000);
    while (document.readyState != "complete")
    delay(2000);
    {

    2. Versuch :
    function loaded() {
    loaded=true;
    };

    <frame src="inhalt.html" name="fraInhalt" onload="parent.fraCtl.loaded()" …

    while (loaded==false){};

  • #2
    Hallo,

    eine "Warteschleife" wie du sie dir vorstellst ist in JS nicht möglich. Hier hilft nur Polling mittels window.setTimeout().

    Dazu folgendes:
    Dein Frameset definiert eine globale Variable frmLoaded. Diese wird beim Neuladen des Inhalts auf false gesetzt. Dein fraCtl definiert eine Callback-Funktion pollLoading(). Beim Abschicken und Neuladen des Inhalts wird pollLoading() mittels window.setTimeout() erstmals aufgerufen. pollLoading() prüft ob die globale Variable frmLoaded mittlerweile true (die Seite also neu geladen) ist. Im Erfolgsfall können entsprechende Aktionen ausgeführt werden und im Negativfall startet sich die Funktion über window.setTimeout() selbst neu.

    Kleines Bsp.:
    Frameset:
    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
    <html>
    <head>
      <title>Titel</title>
      <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" >
      <script type="text/javascript">
      <!--
        var frmloaded = false;
        function loaded()
        {
          frmloaded = true;
        }
      -->
      </script>
    </head>
    <frameset rows="15%, *" >
    <frame src="ctl.html" name="fraCtl" frameborder="1" >
    <frame src="inhalt.html" name="fraInhalt" frameborder="1" onload="loaded();" >
    <noframes>
    <body></body>
    </noframes>
    </frameset>
    </html>
    fraCtl:
    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
    <head>
      <title>Titel</title>
      <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
      <script type="text/javascript">
      <!--
        function pollLoading()
        {
          if (parent.frmloaded)
            alert('Frame ist loaded!');
          else
            window.setTimeout('pollLoading()', 1500);
        }
    
        function loadnew()
        {
          parent.frmloaded = false;
          parent.fraInhalt.location.href = 'inhalt.html';
          window.setTimeout('pollLoading()', 1500);
        }
      -->
      </script>
    </head>
    <body>
      <a href="javascript:loadnew();">Lade neue Seite...</a>
    </body>
    </html>
    Beachten solltest du aber das das Event onload im frame-Tag propritär und nicht in HTML 4.01 definiert ist. FF und IE(6) führen es zwar aus, aber mit anderen Browsern könnte es durchaus Probleme geben.

    Gruß Falk
    Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

    Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

    Comment


    • #3
      Hallo Falk,

      erst einmal Danke für deine Antwort.

      Ich schätze um Timeout komme ich wohl nicht rum. Ich habe nur noch keine Ahnung, wie ich dass bei mir einbauen kann.

      Die Szenarien die ich durchtesten möchte sind unterschiedlich und ich möchte ja nicht nur eine Seite Testen, sondern mehrer in einem gemeinsamen Kontext. Es wird also während der Ausführung nicht nur eine Seite mehrmals (im unterschiedlichem Kontext) aufgerufen, sondern auch noch andere Seiten.

      Bsp.:
      Anwendung aufrufen
      [Seite A wird geladen ]
      Wenn Seite geladen : Anmelden an Anwendung
      [Seite B wird geladen ]
      Seite C aufrufen
      [Seite C wird geladen ]
      Wenn Seite geladen : Werte in Filter eintragen
      Schalter "Filtern" betätigen
      [Seite C wird geladen ]
      Wenn Seite geladen : Wert aus Combobox auswählen
      [Seite C wird geladen ]
      Wenn Seite geladen : Werte aus Tabelle auslesen und mit Vorgaben
      vergleichen
      in Abhängigkeit von Tabellenwerten "unter-"Seite D aufrufen
      [Seite D wird geladen ]
      Wenn Seite geladen : Werte auf Seite D eintragen
      Ergebnis der Berechnungen vergleichen
      Seite D schließen
      [Seite C wird geladen ]
      Wenn Seite geladen : Seite C schließen
      [Seite B wird geladen ]
      Wenn Seite geladen : Seite F aufrufen
      [Seite F wird geladen ]
      Werte in Filter eintragen
      Schalter "Filtern" betätigen
      [Seite F wird geladen ]
      Wenn Seite geladen : Werte aus Tabelle auslesen und mit Vorgaben
      vergleichen
      ...
      Seite n schließen
      [Seite B wird geladen ]
      Wenn Seite geladen : von Anwendung abmelden
      [Seite A wird geladen ]


      Auch ist es mir nicht möglich die Web-Anwendung zu verändern (z.B. "onLoad" in Seite einfügen etc.).

      Ich kann zwar auf eine Seite zugreifen (lesen, schreiben, auslösen von Ereignissen) aber das betrifft nur das Setzen und Auslesen von Werten und das Betätigen von Schaltern.

      An der Struktur (z.B. event-handler) des Dokumentes möchte (kann/darf) ich nichts ändern, um zu vermeiden, dass die Seite serverseitig durch meine Manipulationen anders verarbeitet wird und meine Tests somit Fehler verursachen, die im Test und nicht in der Anwendung liegen.

      Abgesehen davon ist es mir auch nicht möglich so etwas wie
      window.top.frames["fraInhalt"].frames["iFraAnwendung"].frames[0].onload="alert('geladen');" ;
      zu setzen.

      Comment


      • #4
        Hallo hollex,

        du solltest dich davon verabschieden in einer Web-Anwendung das Laden von Seiten serialisieren zu wollen. Was spricht dagegen, deine Szenarien pro Seite zu definieren. Jedes Seitenszenario muß dann nur wissen, wer nach ihm dran ist und wie in meinem Beispiel die entsprechende Routine aufrufen.

        Die einzelnen Szenarien liesen sich in einer entsprechenden Klasse kapseln und das Ganze wäre sehr viel übersichtlicher als eine ellenlange Testroutine mit "Warteschleifen".

        Gruß Falk
        Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

        Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

        Comment


        • #5
          Hallo Falk,

          OK, ich werde versuchen meine Herangehensweise zu ändern, auch wenn mir noch nicht klar ist, wie ich dass realisieren kann. Ist halt doch eine andere Denkweise als gewohnt.
          Aber vielleicht kannst du mich ja etwas unterstützen?

          Also, mein erstes Problem ist, dass ich in der Webanwendung kein "onload" plazieren kann. Die Webanwendung besteht aus einer Seite mit einem Frame. Im Frame wird in Abhängigkeit der Aktionen eine Seite erneut geladen (Daten vom Server holen) oder eine neue Seite aufgerufen. Ich habe zwar mit addEvent dem frames[0] der Anwendung ein on(re)load-handler angefügt, jedoch ist dieser weg, sobald eine Seite (neu)geladen wird, da die Seite serverseitig neu generiert wird (jsp). Die Anwendung kann und will ich aber auch nicht verändern, so dass ich auf einem anderen Weg herausbekommen muß ob die Seite neu geladen wurde. Dies versuche ich gerade über innHTML der Seite. Ich stelle mir vor, dass ich über setTimout eine Routine aufrufe, die prüft ob eine Seite vollständig geladen wurde. Dazu prüfe ich, ob der String "</body>" in innerHTML enthalten ist. Das Problem ist, dass "</body>" gefunden wird, obwohl die Seite noch nicht vollständig geladen ist. Dadurch fehlen dann JS-Scripte der Seite, die zum Test der Seite benötigt werden.
          Hast du einen Vorschlag, wie ich sicher prüfen kann, ob eine Seite geladen wurde, ohne ein event -handler an die Seite anhängen zu müssen?

          Gruß
          Klaus

          Gruß Klaus

          Comment


          • #6
            Hallo Klaus,

            wenn du dem entsprechenden Frame-Tag einen onload-Handler verpasst, sollte das eigentlich Funktionieren.
            Im Anhang frametest2 ein kleines Bsp. wie es (zumindest im Firefox) gehen könnte.
            In frametest habe ich mal demonstriert was ich mit dem "Aufsplitten" der Szenarien pro Seite meinte.

            Gruß Falk
            Attached Files
            Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

            Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

            Comment


            • #7
              Hallo Falk,

              vielen Dank für deine Beispiele.

              Leider komme ich wahrscheinlich erst am Wochenende oder am Montag dazu, mir diese genauer anzusehen. Ich melde mich dann noch mal.

              Also erst einmal vielen Dank und ein schönes Wochenende.

              Klaus

              Comment


              • #8
                kleiner Tipp: [ code ] oder [ highlight=JavaScript ] !! (die leerzeichen vor und hinter den klammern natürlich weglassen!)

                Comment


                • #9
                  Auch ein kleiner Tipp: Mal ein Hallo, oder so etwas macht die Sach ein wenig persönlicher.

                  Außerdem glaubst du dass jemand einen fast 2 Wochen alten Beitrag neu formatiert?!
                  "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                  Comment


                  • #10
                    Hi,
                    neu formatieren nicht, aber für die zukunft

                    jaja, das mit dem hallo, ich vergesse immer mal wieder, dass es mein erster post in dem thread ist, danach unterhält man sich ja auch ganz normal, man schreibt sich auch im chat ja nich immer hallo oder so davor (is n klein bissel anders aber kaum)

                    Comment


                    • #11
                      Originally posted by levu View Post
                      kleiner Tipp: [ code ] oder [ highlight=JavaScript ] !! (die leerzeichen vor und hinter den klammern natürlich weglassen!)
                      Oh, endlich mal einer der die FAQ zum Thema BB-Code gelesen hat. Aber offensichtlich nicht vollständig sonst wüßte er das man mit [noparse]hier BB-Code[/noparse] das Parsen von BB-Code unterdrücken kann und sich somit die Leerzeichen für [code] und [highlight=JavaScript] (und den Hinweis darauf) hätte sparen können .

                      Gruß Falk
                      Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

                      Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

                      Comment


                      • #12
                        Oh, endlich mal einer der die FAQ zum Thema BB-Code gelesen hat
                        auch nur das was ich ihm zitiert habe
                        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                        Comment

                        Working...
                        X